You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC

svn commit: r1890120 [8/43] - in /poi/trunk/poi/src: main/java/org/apache/poi/ main/java/org/apache/poi/ddf/ main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/ main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/ main/java/...

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordInputStream.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordInputStream.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RecordInputStream.java Sat May 22 20:56:44 2021
@@ -40,28 +40,28 @@ import org.apache.poi.util.RecordFormatE
 public final class RecordInputStream implements LittleEndianInput {
 
 
-	/** Maximum size of a single record (minus the 4 byte header) without a continue*/
-	public static final short MAX_RECORD_DATA_SIZE = 8224;
-	private static final int INVALID_SID_VALUE = -1;
-	//arbitrarily selected; may need to increase
-	private static final int MAX_RECORD_LENGTH = 100_000;
-	/**
-	 * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is
-	 * finished, the next sid has been properly read, but the data size field has not been read yet.
-	 */
-	private static final int DATA_LEN_NEEDS_TO_BE_READ = -1;
-	private static final byte[] EMPTY_BYTE_ARRAY = { };
-
-	/**
-	 * For use in {@link BiffViewer} which may construct {@link Record}s that don't completely
-	 * read all available data.  This exception should never be thrown otherwise.
-	 */
-	public static final class LeftoverDataException extends RuntimeException {
-		public LeftoverDataException(int sid, int remainingByteCount) {
-			super("Initialisation of record 0x" + Integer.toHexString(sid).toUpperCase(Locale.ROOT)
-					+ "(" + getRecordName(sid) + ") left " + remainingByteCount
-					+ " bytes remaining still to be read.");
-		}
+    /** Maximum size of a single record (minus the 4 byte header) without a continue*/
+    public static final short MAX_RECORD_DATA_SIZE = 8224;
+    private static final int INVALID_SID_VALUE = -1;
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000;
+    /**
+     * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is
+     * finished, the next sid has been properly read, but the data size field has not been read yet.
+     */
+    private static final int DATA_LEN_NEEDS_TO_BE_READ = -1;
+    private static final byte[] EMPTY_BYTE_ARRAY = { };
+
+    /**
+     * For use in {@link BiffViewer} which may construct {@link Record}s that don't completely
+     * read all available data.  This exception should never be thrown otherwise.
+     */
+    public static final class LeftoverDataException extends RuntimeException {
+        public LeftoverDataException(int sid, int remainingByteCount) {
+            super("Initialisation of record 0x" + Integer.toHexString(sid).toUpperCase(Locale.ROOT)
+                    + "(" + getRecordName(sid) + ") left " + remainingByteCount
+                    + " bytes remaining still to be read.");
+        }
 
         private static String getRecordName(int sid) {
             Class<? extends Record> recordClass = RecordFactory.getRecordClass(sid);
@@ -70,255 +70,255 @@ public final class RecordInputStream imp
             }
             return recordClass.getSimpleName();
         }
-	}
+    }
+
+    /** Header {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
+    private final BiffHeaderInput _bhi;
+    /** Data {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
+    private final LittleEndianInput _dataInput;
+    /** the record identifier of the BIFF record currently being read */
+    private int _currentSid;
+    /**
+     * Length of the data section of the current BIFF record (always 4 less than the total record size).
+     * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}.
+     */
+    private int _currentDataLength;
+    /**
+     * The BIFF record identifier for the next record is read when just as the current record
+     * is finished.
+     * This field is only really valid during the time that ({@link #_currentDataLength} ==
+     * {@link #DATA_LEN_NEEDS_TO_BE_READ}).  At most other times its value is not really the
+     * 'sid of the next record'.  Wwhile mid-record, this field coincidentally holds the sid
+     * of the current record.
+     */
+    private int _nextSid;
+    /**
+     * index within the data section of the current BIFF record
+     */
+    private int _currentDataOffset;
+    /**
+     * index within the data section when mark() was called
+     */
+    private int _markedDataOffset;
+
+    private static final class SimpleHeaderInput implements BiffHeaderInput {
+
+        private final LittleEndianInput _lei;
 
-	/** Header {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
-	private final BiffHeaderInput _bhi;
-	/** Data {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
-	private final LittleEndianInput _dataInput;
-	/** the record identifier of the BIFF record currently being read */
-	private int _currentSid;
-	/**
-	 * Length of the data section of the current BIFF record (always 4 less than the total record size).
-	 * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}.
-	 */
-	private int _currentDataLength;
-	/**
-	 * The BIFF record identifier for the next record is read when just as the current record
-	 * is finished.
-	 * This field is only really valid during the time that ({@link #_currentDataLength} ==
-	 * {@link #DATA_LEN_NEEDS_TO_BE_READ}).  At most other times its value is not really the
-	 * 'sid of the next record'.  Wwhile mid-record, this field coincidentally holds the sid
-	 * of the current record.
-	 */
-	private int _nextSid;
-	/**
-	 * index within the data section of the current BIFF record
-	 */
-	private int _currentDataOffset;
-	/**
-	 * index within the data section when mark() was called
-	 */
-	private int _markedDataOffset;
-
-	private static final class SimpleHeaderInput implements BiffHeaderInput {
-
-		private final LittleEndianInput _lei;
-
-		private SimpleHeaderInput(LittleEndianInput lei) {
-			_lei = lei;
-		}
-		@Override
+        private SimpleHeaderInput(LittleEndianInput lei) {
+            _lei = lei;
+        }
+        @Override
         public int available() {
-			return _lei.available();
-		}
-		@Override
+            return _lei.available();
+        }
+        @Override
         public int readDataSize() {
-			return _lei.readUShort();
-		}
-		@Override
+            return _lei.readUShort();
+        }
+        @Override
         public int readRecordSID() {
-			return _lei.readUShort();
-		}
-	}
-
-	public RecordInputStream(InputStream in) throws RecordFormatException {
-		this (in, null, 0);
-	}
-
-	public RecordInputStream(InputStream in, EncryptionInfo key, int initialOffset) throws RecordFormatException {
-		if (key == null) {
-			_dataInput = (in instanceof LittleEndianInput)
-				// accessing directly is an optimisation
-				? (LittleEndianInput)in
-				// less optimal, but should work OK just the same. Often occurs in junit tests.
-				: new LittleEndianInputStream(in);
-			_bhi = new SimpleHeaderInput(_dataInput);
-		} else {
-			Biff8DecryptingStream bds = new Biff8DecryptingStream(in, initialOffset, key);
+            return _lei.readUShort();
+        }
+    }
+
+    public RecordInputStream(InputStream in) throws RecordFormatException {
+        this (in, null, 0);
+    }
+
+    public RecordInputStream(InputStream in, EncryptionInfo key, int initialOffset) throws RecordFormatException {
+        if (key == null) {
+            _dataInput = (in instanceof LittleEndianInput)
+                // accessing directly is an optimisation
+                ? (LittleEndianInput)in
+                // less optimal, but should work OK just the same. Often occurs in junit tests.
+                : new LittleEndianInputStream(in);
+            _bhi = new SimpleHeaderInput(_dataInput);
+        } else {
+            Biff8DecryptingStream bds = new Biff8DecryptingStream(in, initialOffset, key);
             _dataInput = bds;
-			_bhi = bds;
-		}
-		_nextSid = readNextSid();
-	}
-
-	static LittleEndianInput getLEI(InputStream is) {
-		if (is instanceof LittleEndianInput) {
-			// accessing directly is an optimisation
-			return (LittleEndianInput) is;
-		}
-		// less optimal, but should work OK just the same. Often occurs in junit tests.
-		return new LittleEndianInputStream(is);
-	}
-
-	/**
-	 * @return the number of bytes available in the current BIFF record
-	 * @see #remaining()
-	 */
-	@Override
+            _bhi = bds;
+        }
+        _nextSid = readNextSid();
+    }
+
+    static LittleEndianInput getLEI(InputStream is) {
+        if (is instanceof LittleEndianInput) {
+            // accessing directly is an optimisation
+            return (LittleEndianInput) is;
+        }
+        // less optimal, but should work OK just the same. Often occurs in junit tests.
+        return new LittleEndianInputStream(is);
+    }
+
+    /**
+     * @return the number of bytes available in the current BIFF record
+     * @see #remaining()
+     */
+    @Override
     public int available() {
-		return remaining();
-	}
+        return remaining();
+    }
 
-	public int read(byte[] b, int off, int len) {
-		int limit = Math.min(len, remaining());
-		if (limit == 0) {
-			return 0;
-		}
-		readFully(b, off,limit);
-		return limit;
-	}
-
-	public short getSid() {
-		return (short) _currentSid;
-	}
-
-	/**
-	 * Note - this method is expected to be called only when completed reading the current BIFF
-	 * record.
-	 *
-	 * @return true, if there's another record in the stream
-	 *
-	 * @throws LeftoverDataException if this method is called before reaching the end of the
-	 * current record.
-	 */
-	public boolean hasNextRecord() throws LeftoverDataException {
-		if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) {
-			throw new LeftoverDataException(_currentSid, remaining());
-		}
-		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
-			_nextSid = readNextSid();
-		}
-		return _nextSid != INVALID_SID_VALUE;
-	}
-
-	/**
-	 * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream
-	 */
-	private int readNextSid() {
-		int nAvailable  = _bhi.available();
-		if (nAvailable < EOFRecord.ENCODED_SIZE) {
-			// some scrap left over, if nAvailable > 0?
-			// ex45582-22397.xls has one extra byte after the last record
-			// Excel reads that file OK
-			return INVALID_SID_VALUE;
-		}
-		int result = _bhi.readRecordSID();
-		if (result == INVALID_SID_VALUE) {
-			throw new RecordFormatException("Found invalid sid (" + result + ")");
-		}
-		_currentDataLength = DATA_LEN_NEEDS_TO_BE_READ;
-		return result;
-	}
-
-	/** Moves to the next record in the stream.
-	 *
-	 * <i>Note: The auto continue flag is reset to true</i>
-	 */
-	public void nextRecord() throws RecordFormatException {
-		if (_nextSid == INVALID_SID_VALUE) {
-			throw new IllegalStateException("EOF - next record not available");
-		}
-		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
-			throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first");
-		}
-		_currentSid = _nextSid;
-		_currentDataOffset = 0;
-		_currentDataLength = _bhi.readDataSize();
-		if (_currentDataLength > MAX_RECORD_DATA_SIZE) {
-			throw new RecordFormatException("The content of an excel record cannot exceed "
-					+ MAX_RECORD_DATA_SIZE + " bytes");
-		}
-	}
-
-	private void checkRecordPosition(int requiredByteCount) {
-
-		int nAvailable = remaining();
-		if (nAvailable >= requiredByteCount) {
-			// all OK
-			return;
-		}
-		if (nAvailable == 0 && isContinueNext()) {
-			nextRecord();
-			return;
-		}
-		throw new RecordFormatException("Not enough data (" + nAvailable
-				+ ") to read requested (" + requiredByteCount +") bytes");
-	}
-
-	/**
-	 * Reads an 8 bit, signed value
-	 */
-	@Override
+    public int read(byte[] b, int off, int len) {
+        int limit = Math.min(len, remaining());
+        if (limit == 0) {
+            return 0;
+        }
+        readFully(b, off,limit);
+        return limit;
+    }
+
+    public short getSid() {
+        return (short) _currentSid;
+    }
+
+    /**
+     * Note - this method is expected to be called only when completed reading the current BIFF
+     * record.
+     *
+     * @return true, if there's another record in the stream
+     *
+     * @throws LeftoverDataException if this method is called before reaching the end of the
+     * current record.
+     */
+    public boolean hasNextRecord() throws LeftoverDataException {
+        if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) {
+            throw new LeftoverDataException(_currentSid, remaining());
+        }
+        if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+            _nextSid = readNextSid();
+        }
+        return _nextSid != INVALID_SID_VALUE;
+    }
+
+    /**
+     * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream
+     */
+    private int readNextSid() {
+        int nAvailable  = _bhi.available();
+        if (nAvailable < EOFRecord.ENCODED_SIZE) {
+            // some scrap left over, if nAvailable > 0?
+            // ex45582-22397.xls has one extra byte after the last record
+            // Excel reads that file OK
+            return INVALID_SID_VALUE;
+        }
+        int result = _bhi.readRecordSID();
+        if (result == INVALID_SID_VALUE) {
+            throw new RecordFormatException("Found invalid sid (" + result + ")");
+        }
+        _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ;
+        return result;
+    }
+
+    /** Moves to the next record in the stream.
+     *
+     * <i>Note: The auto continue flag is reset to true</i>
+     */
+    public void nextRecord() throws RecordFormatException {
+        if (_nextSid == INVALID_SID_VALUE) {
+            throw new IllegalStateException("EOF - next record not available");
+        }
+        if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+            throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first");
+        }
+        _currentSid = _nextSid;
+        _currentDataOffset = 0;
+        _currentDataLength = _bhi.readDataSize();
+        if (_currentDataLength > MAX_RECORD_DATA_SIZE) {
+            throw new RecordFormatException("The content of an excel record cannot exceed "
+                    + MAX_RECORD_DATA_SIZE + " bytes");
+        }
+    }
+
+    private void checkRecordPosition(int requiredByteCount) {
+
+        int nAvailable = remaining();
+        if (nAvailable >= requiredByteCount) {
+            // all OK
+            return;
+        }
+        if (nAvailable == 0 && isContinueNext()) {
+            nextRecord();
+            return;
+        }
+        throw new RecordFormatException("Not enough data (" + nAvailable
+                + ") to read requested (" + requiredByteCount +") bytes");
+    }
+
+    /**
+     * Reads an 8 bit, signed value
+     */
+    @Override
     public byte readByte() {
-		checkRecordPosition(LittleEndianConsts.BYTE_SIZE);
-		_currentDataOffset += LittleEndianConsts.BYTE_SIZE;
-		return _dataInput.readByte();
-	}
-
-	/**
-	 * Reads a 16 bit, signed value
-	 */
-	@Override
+        checkRecordPosition(LittleEndianConsts.BYTE_SIZE);
+        _currentDataOffset += LittleEndianConsts.BYTE_SIZE;
+        return _dataInput.readByte();
+    }
+
+    /**
+     * Reads a 16 bit, signed value
+     */
+    @Override
     public short readShort() {
-		checkRecordPosition(LittleEndianConsts.SHORT_SIZE);
-		_currentDataOffset += LittleEndianConsts.SHORT_SIZE;
-		return _dataInput.readShort();
-	}
-
-	/**
-	 * Reads a 32 bit, signed value
-	 */
-	@Override
+        checkRecordPosition(LittleEndianConsts.SHORT_SIZE);
+        _currentDataOffset += LittleEndianConsts.SHORT_SIZE;
+        return _dataInput.readShort();
+    }
+
+    /**
+     * Reads a 32 bit, signed value
+     */
+    @Override
     public int readInt() {
-		checkRecordPosition(LittleEndianConsts.INT_SIZE);
-		_currentDataOffset += LittleEndianConsts.INT_SIZE;
-		return _dataInput.readInt();
-	}
-
-	/**
-	 * Reads a 64 bit, signed value
-	 */
-	@Override
+        checkRecordPosition(LittleEndianConsts.INT_SIZE);
+        _currentDataOffset += LittleEndianConsts.INT_SIZE;
+        return _dataInput.readInt();
+    }
+
+    /**
+     * Reads a 64 bit, signed value
+     */
+    @Override
     public long readLong() {
-		checkRecordPosition(LittleEndianConsts.LONG_SIZE);
-		_currentDataOffset += LittleEndianConsts.LONG_SIZE;
-		return _dataInput.readLong();
-	}
-
-	/**
-	 * Reads an 8 bit, unsigned value
-	 */
-	@Override
+        checkRecordPosition(LittleEndianConsts.LONG_SIZE);
+        _currentDataOffset += LittleEndianConsts.LONG_SIZE;
+        return _dataInput.readLong();
+    }
+
+    /**
+     * Reads an 8 bit, unsigned value
+     */
+    @Override
     public int readUByte() {
-		return readByte() & 0x00FF;
-	}
+        return readByte() & 0x00FF;
+    }
 
-	/**
-	 * Reads a 16 bit, unsigned value.
-	 */
-	@Override
+    /**
+     * Reads a 16 bit, unsigned value.
+     */
+    @Override
     public int readUShort() {
-		checkRecordPosition(LittleEndianConsts.SHORT_SIZE);
-		_currentDataOffset += LittleEndianConsts.SHORT_SIZE;
-		return _dataInput.readUShort();
-	}
+        checkRecordPosition(LittleEndianConsts.SHORT_SIZE);
+        _currentDataOffset += LittleEndianConsts.SHORT_SIZE;
+        return _dataInput.readUShort();
+    }
 
-	@Override
+    @Override
     public double readDouble() {
         // YK: Excel doesn't write NaN but instead converts the cell type into {@link CellType#ERROR}.
-		return Double.longBitsToDouble(readLong());
-	}
+        return Double.longBitsToDouble(readLong());
+    }
 
-	@Override
-	public void readPlain(byte[] buf, int off, int len) {
-	    readFully(buf, 0, buf.length, true);
-	}
+    @Override
+    public void readPlain(byte[] buf, int off, int len) {
+        readFully(buf, 0, buf.length, true);
+    }
 
-	@Override
+    @Override
     public void readFully(byte[] buf) {
-		readFully(buf, 0, buf.length, false);
-	}
+        readFully(buf, 0, buf.length, false);
+    }
 
     @Override
     public void readFully(byte[] buf, int off, int len) {
@@ -326,126 +326,126 @@ public final class RecordInputStream imp
     }
 
     private void readFully(byte[] buf, int off, int len, boolean isPlain) {
-	    int origLen = len;
-	    if (buf == null) {
-	        throw new NullPointerException();
-	    } else if (off < 0 || len < 0 || len > buf.length - off) {
-	        throw new IndexOutOfBoundsException();
-	    }
-
-	    while (len > 0) {
-	        int nextChunk = Math.min(available(),len);
-	        if (nextChunk == 0) {
-	            if (!hasNextRecord()) {
-	                throw new RecordFormatException("Can't read the remaining "+len+" bytes of the requested "+origLen+" bytes. No further record exists.");
-	            } else {
-	                nextRecord();
-	                nextChunk = Math.min(available(),len);
-	                assert(nextChunk > 0);
-	            }
-	        }
-	        checkRecordPosition(nextChunk);
-	        if (isPlain) {
+        int origLen = len;
+        if (buf == null) {
+            throw new NullPointerException();
+        } else if (off < 0 || len < 0 || len > buf.length - off) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        while (len > 0) {
+            int nextChunk = Math.min(available(),len);
+            if (nextChunk == 0) {
+                if (!hasNextRecord()) {
+                    throw new RecordFormatException("Can't read the remaining "+len+" bytes of the requested "+origLen+" bytes. No further record exists.");
+                } else {
+                    nextRecord();
+                    nextChunk = Math.min(available(),len);
+                    assert(nextChunk > 0);
+                }
+            }
+            checkRecordPosition(nextChunk);
+            if (isPlain) {
                 _dataInput.readPlain(buf, off, nextChunk);
-	        } else {
+            } else {
                 _dataInput.readFully(buf, off, nextChunk);
-	        }
-	        _currentDataOffset+=nextChunk;
-	        off += nextChunk;
-	        len -= nextChunk;
-	    }
-	}
-
-	public String readString() {
-		int requestedLength = readUShort();
-		byte compressFlag = readByte();
-		return readStringCommon(requestedLength, compressFlag == 0);
-	}
-	/**
-	 *  given a byte array of 16-bit unicode characters, compress to 8-bit and
-	 *  return a string
-	 *
-	 * { 0x16, 0x00 } -0x16
-	 *
-	 * @param requestedLength the length of the final string
-	 * @return                                     the converted string
-	 * @exception  IllegalArgumentException        if len is too large (i.e.,
-	 *      there is not enough data in string to create a String of that
-	 *      length)
-	 */
-	public String readUnicodeLEString(int requestedLength) {
-		return readStringCommon(requestedLength, false);
-	}
-
-	public String readCompressedUnicode(int requestedLength) {
-		return readStringCommon(requestedLength, true);
-	}
-
-	private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
-		// Sanity check to detect garbage string lengths
-		if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
-			throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
-		}
-		char[] buf = new char[requestedLength];
-		boolean isCompressedEncoding = pIsCompressedEncoding;
-		int curLen = 0;
-		while(true) {
-			int availableChars =isCompressedEncoding ?  remaining() : remaining() / LittleEndianConsts.SHORT_SIZE;
-			if (requestedLength - curLen <= availableChars) {
-				// enough space in current record, so just read it out
-				while(curLen < requestedLength) {
-					char ch;
-					if (isCompressedEncoding) {
-						ch = (char)readUByte();
-					} else {
-						ch = (char)readShort();
-					}
-					buf[curLen] = ch;
-					curLen++;
-				}
-				return new String(buf);
-			}
-			// else string has been spilled into next continue record
-			// so read what's left of the current record
-			while(availableChars > 0) {
-				char ch;
-				if (isCompressedEncoding) {
-					ch = (char)readUByte();
-				} else {
-					ch = (char)readShort();
-				}
-				buf[curLen] = ch;
-				curLen++;
-				availableChars--;
-			}
-			if (!isContinueNext()) {
-				throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining "
-						+ (requestedLength-curLen) + " of " + requestedLength + " chars");
-			}
-			if(remaining() != 0) {
-				throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind");
-			}
-			nextRecord();
-			// note - the compressed flag may change on the fly
-			byte compressFlag = readByte();
+            }
+            _currentDataOffset+=nextChunk;
+            off += nextChunk;
+            len -= nextChunk;
+        }
+    }
+
+    public String readString() {
+        int requestedLength = readUShort();
+        byte compressFlag = readByte();
+        return readStringCommon(requestedLength, compressFlag == 0);
+    }
+    /**
+     *  given a byte array of 16-bit unicode characters, compress to 8-bit and
+     *  return a string
+     *
+     * { 0x16, 0x00 } -0x16
+     *
+     * @param requestedLength the length of the final string
+     * @return                                     the converted string
+     * @exception  IllegalArgumentException        if len is too large (i.e.,
+     *      there is not enough data in string to create a String of that
+     *      length)
+     */
+    public String readUnicodeLEString(int requestedLength) {
+        return readStringCommon(requestedLength, false);
+    }
+
+    public String readCompressedUnicode(int requestedLength) {
+        return readStringCommon(requestedLength, true);
+    }
+
+    private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
+        // Sanity check to detect garbage string lengths
+        if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
+            throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
+        }
+        char[] buf = new char[requestedLength];
+        boolean isCompressedEncoding = pIsCompressedEncoding;
+        int curLen = 0;
+        while(true) {
+            int availableChars =isCompressedEncoding ?  remaining() : remaining() / LittleEndianConsts.SHORT_SIZE;
+            if (requestedLength - curLen <= availableChars) {
+                // enough space in current record, so just read it out
+                while(curLen < requestedLength) {
+                    char ch;
+                    if (isCompressedEncoding) {
+                        ch = (char)readUByte();
+                    } else {
+                        ch = (char)readShort();
+                    }
+                    buf[curLen] = ch;
+                    curLen++;
+                }
+                return new String(buf);
+            }
+            // else string has been spilled into next continue record
+            // so read what's left of the current record
+            while(availableChars > 0) {
+                char ch;
+                if (isCompressedEncoding) {
+                    ch = (char)readUByte();
+                } else {
+                    ch = (char)readShort();
+                }
+                buf[curLen] = ch;
+                curLen++;
+                availableChars--;
+            }
+            if (!isContinueNext()) {
+                throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining "
+                        + (requestedLength-curLen) + " of " + requestedLength + " chars");
+            }
+            if(remaining() != 0) {
+                throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind");
+            }
+            nextRecord();
+            // note - the compressed flag may change on the fly
+            byte compressFlag = readByte();
             assert(compressFlag == 0 || compressFlag == 1);
-			isCompressedEncoding = (compressFlag == 0);
-		}
-	}
-
-	/** Returns the remaining bytes for the current record.
-	 *
-	  * @return The remaining bytes of the current record.
-	  */
-	public byte[] readRemainder() {
-		int size = remaining();
-		if (size ==0) {
-			return EMPTY_BYTE_ARRAY;
-		}
-		byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
-		readFully(result);
-		return result;
-	}
+            isCompressedEncoding = (compressFlag == 0);
+        }
+    }
+
+    /** Returns the remaining bytes for the current record.
+     *
+      * @return The remaining bytes of the current record.
+      */
+    public byte[] readRemainder() {
+        int size = remaining();
+        if (size ==0) {
+            return EMPTY_BYTE_ARRAY;
+        }
+        byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
+        readFully(result);
+        return result;
+    }
 
     /**
      * Reads all byte data for the current record, including any that overlaps
@@ -472,36 +472,36 @@ public final class RecordInputStream imp
         return out.toByteArray();
     }
 
-	/** The remaining number of bytes in the <i>current</i> record.
-	 *
-	 * @return The number of bytes remaining in the current record
-	 */
-	public int remaining() {
-		if (_currentDataLength == DATA_LEN_NEEDS_TO_BE_READ) {
-			// already read sid of next record. so current one is finished
-			return 0;
-		}
-		return _currentDataLength - _currentDataOffset;
-	}
-
-	/**
-	 *
-	 * @return {@code true} when a {@link ContinueRecord} is next.
-	 */
-	private boolean isContinueNext() {
-		if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) {
-			throw new IllegalStateException("Should never be called before end of current record");
-		}
-		if (!hasNextRecord()) {
-			return false;
-		}
-		// At what point are records continued?
-		//  - Often from within the char data of long strings (caller is within readStringCommon()).
-		//  - From UnicodeString construction (many different points - call via checkRecordPosition)
-		//  - During TextObjectRecord construction (just before the text, perhaps within the text,
-		//    and before the formatting run data)
-		return _nextSid == ContinueRecord.sid;
-	}
+    /** The remaining number of bytes in the <i>current</i> record.
+     *
+     * @return The number of bytes remaining in the current record
+     */
+    public int remaining() {
+        if (_currentDataLength == DATA_LEN_NEEDS_TO_BE_READ) {
+            // already read sid of next record. so current one is finished
+            return 0;
+        }
+        return _currentDataLength - _currentDataOffset;
+    }
+
+    /**
+     *
+     * @return {@code true} when a {@link ContinueRecord} is next.
+     */
+    private boolean isContinueNext() {
+        if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) {
+            throw new IllegalStateException("Should never be called before end of current record");
+        }
+        if (!hasNextRecord()) {
+            return false;
+        }
+        // At what point are records continued?
+        //  - Often from within the char data of long strings (caller is within readStringCommon()).
+        //  - From UnicodeString construction (many different points - call via checkRecordPosition)
+        //  - During TextObjectRecord construction (just before the text, perhaps within the text,
+        //    and before the formatting run data)
+        return _nextSid == ContinueRecord.sid;
+    }
 
     /**
      @return sid of next record. Can be called after hasNextRecord()

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RowRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RowRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RowRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/RowRecord.java Sat May 22 20:56:44 2021
@@ -81,9 +81,9 @@ public final class RowRecord extends Sta
 
 
     public RowRecord(int rowNumber) {
-    	if(rowNumber < 0) {
-    		throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")");
-    	}
+        if(rowNumber < 0) {
+            throw new IllegalArgumentException("Invalid row number (" + rowNumber + ")");
+        }
         field_1_row_number = rowNumber;
         field_4_height = (short)0xFF;
         field_5_optimize = ( short ) 0;
@@ -96,9 +96,9 @@ public final class RowRecord extends Sta
 
     public RowRecord(RecordInputStream in) {
         field_1_row_number   = in.readUShort();
-    	if(field_1_row_number < 0) {
-    		throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream");
-    	}
+        if(field_1_row_number < 0) {
+            throw new IllegalArgumentException("Invalid row number " + field_1_row_number + " found in InputStream");
+        }
         field_2_first_col    = in.readShort();
         field_3_last_col     = in.readShort();
         field_4_height       = in.readShort();
@@ -209,7 +209,7 @@ public final class RowRecord extends Sta
      * @param index to the XF record
      */
     public void setXFIndex(short index) {
-    	field_8_option_flags = xfIndex.setValue(field_8_option_flags, index);
+        field_8_option_flags = xfIndex.setValue(field_8_option_flags, index);
     }
 
     /**
@@ -218,7 +218,7 @@ public final class RowRecord extends Sta
      * @param f has thick top border
      */
     public void setTopBorder(boolean f) {
-    	field_8_option_flags = topBorder.setBoolean(field_8_option_flags, f);
+        field_8_option_flags = topBorder.setBoolean(field_8_option_flags, f);
     }
 
     /**
@@ -228,7 +228,7 @@ public final class RowRecord extends Sta
      * @param f has thick bottom border
      */
     public void setBottomBorder(boolean f) {
-    	field_8_option_flags = bottomBorder.setBoolean(field_8_option_flags, f);
+        field_8_option_flags = bottomBorder.setBoolean(field_8_option_flags, f);
     }
 
     /**
@@ -237,7 +237,7 @@ public final class RowRecord extends Sta
      * @param f use phoenetic guide
      */
     public void setPhoeneticGuide(boolean f) {
-    	field_8_option_flags = phoneticGuide.setBoolean(field_8_option_flags, f);
+        field_8_option_flags = phoneticGuide.setBoolean(field_8_option_flags, f);
     }
 
     /**
@@ -353,7 +353,7 @@ public final class RowRecord extends Sta
      * @return index to the XF record or bogus value (undefined) if isn't formatted
      */
     public short getXFIndex() {
-    	return xfIndex.getShortValue((short)field_8_option_flags);
+        return xfIndex.getShortValue((short)field_8_option_flags);
     }
 
     /**
@@ -362,7 +362,7 @@ public final class RowRecord extends Sta
      * @return has cells with a thick top border
      */
     public boolean getTopBorder() {
-    	return topBorder.isSet(field_8_option_flags);
+        return topBorder.isSet(field_8_option_flags);
     }
 
     /**
@@ -371,7 +371,7 @@ public final class RowRecord extends Sta
      * @return has cells with a thick bottom border
      */
     public boolean getBottomBorder() {
-    	return bottomBorder.isSet(field_8_option_flags);
+        return bottomBorder.isSet(field_8_option_flags);
     }
 
     /**
@@ -380,7 +380,7 @@ public final class RowRecord extends Sta
      * @return has phoentic guide
      */
     public boolean getPhoeneticGuide() {
-    	return phoneticGuide.isSet(field_8_option_flags);
+        return phoneticGuide.isSet(field_8_option_flags);
     }
 
     public void serialize(LittleEndianOutput out) {

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTDeserializer.java Sat May 22 20:56:44 2021
@@ -31,7 +31,7 @@ import static org.apache.logging.log4j.u
  */
 class SSTDeserializer
 {
-	private static final Logger LOG = LogManager.getLogger(SSTDeserializer.class);
+    private static final Logger LOG = LogManager.getLogger(SSTDeserializer.class);
     private IntMapper<UnicodeString> strings;
 
     public SSTDeserializer( IntMapper<UnicodeString> strings )

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTSerializer.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTSerializer.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTSerializer.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SSTSerializer.java Sat May 22 20:56:44 2021
@@ -27,8 +27,8 @@ import org.apache.poi.util.IntMapper;
  */
 final class SSTSerializer {
 
-	private final int _numStrings;
-	private final int _numUniqueStrings;
+    private final int _numStrings;
+    private final int _numUniqueStrings;
 
     private final IntMapper<UnicodeString> strings;
 
@@ -40,8 +40,8 @@ final class SSTSerializer {
     public SSTSerializer( IntMapper<UnicodeString> strings, int numStrings, int numUniqueStrings )
     {
         this.strings = strings;
-		_numStrings = numStrings;
-		_numUniqueStrings = numUniqueStrings;
+        _numStrings = numStrings;
+        _numUniqueStrings = numUniqueStrings;
 
         int infoRecs = ExtSSTRecord.getNumberOfInfoRecsForStrings(strings.size());
         this.bucketAbsoluteOffsets = new int[infoRecs];

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedFormulaRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedFormulaRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedFormulaRecord.java Sat May 22 20:56:44 2021
@@ -106,9 +106,9 @@ public final class SharedFormulaRecord e
     public SharedFormulaRecord copy() {
         return new SharedFormulaRecord(this);
     }
-	public boolean isFormulaSame(SharedFormulaRecord other) {
-		return field_7_parsed_expr.isSame(other.field_7_parsed_expr);
-	}
+    public boolean isFormulaSame(SharedFormulaRecord other) {
+        return field_7_parsed_expr.isSame(other.field_7_parsed_expr);
+    }
 
     @Override
     public HSSFRecordTypes getGenericRecordType() {

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedValueRecordBase.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedValueRecordBase.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedValueRecordBase.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SharedValueRecordBase.java Sat May 22 20:56:44 2021
@@ -27,95 +27,95 @@ import org.apache.poi.util.LittleEndianO
  */
 public abstract class SharedValueRecordBase extends StandardRecord {
 
-	private CellRangeAddress8Bit _range;
+    private CellRangeAddress8Bit _range;
 
-	protected SharedValueRecordBase(SharedValueRecordBase other) {
-		super(other);
-		_range = (other._range == null) ? null : other._range.copy();
-	}
-
-	protected SharedValueRecordBase(CellRangeAddress8Bit range) {
-		if (range == null) {
-			throw new IllegalArgumentException("range must be supplied.");
-		}
-		_range = range;
-	}
-
-	protected SharedValueRecordBase() {
-		this(new CellRangeAddress8Bit(0, 0, 0, 0));
-	}
-
-	/**
-	 * reads only the range (1 {@link CellRangeAddress8Bit}) from the stream
-	 *
-	 * @param in The interface for reading the record data.
-	 */
-	public SharedValueRecordBase(LittleEndianInput in) {
-		_range = new CellRangeAddress8Bit(in);
-	}
-
-	/**
-	 * @return the range of cells that this record is shared across.  Never <code>null</code>.
-	 */
-	public final CellRangeAddress8Bit getRange() {
-		return _range;
-	}
-
-	public final int getFirstRow() {
-		return _range.getFirstRow();
-	}
-
-	public final int getLastRow() {
-		return _range.getLastRow();
-	}
-
-	public final int getFirstColumn() {
-		return (short) _range.getFirstColumn();
-	}
-
-	public final int getLastColumn() {
-		return (short) _range.getLastColumn();
-	}
-
-	protected int getDataSize() {
-		return CellRangeAddress8Bit.ENCODED_SIZE + getExtraDataSize();
-	}
-
-	protected abstract int getExtraDataSize();
-
-	protected abstract void serializeExtraData(LittleEndianOutput out);
-
-	public void serialize(LittleEndianOutput out) {
-		_range.serialize(out);
-		serializeExtraData(out);
-	}
+    protected SharedValueRecordBase(SharedValueRecordBase other) {
+        super(other);
+        _range = (other._range == null) ? null : other._range.copy();
+    }
+
+    protected SharedValueRecordBase(CellRangeAddress8Bit range) {
+        if (range == null) {
+            throw new IllegalArgumentException("range must be supplied.");
+        }
+        _range = range;
+    }
+
+    protected SharedValueRecordBase() {
+        this(new CellRangeAddress8Bit(0, 0, 0, 0));
+    }
 
-	/**
+    /**
+     * reads only the range (1 {@link CellRangeAddress8Bit}) from the stream
+     *
+     * @param in The interface for reading the record data.
+     */
+    public SharedValueRecordBase(LittleEndianInput in) {
+        _range = new CellRangeAddress8Bit(in);
+    }
+
+    /**
+     * @return the range of cells that this record is shared across.  Never <code>null</code>.
+     */
+    public final CellRangeAddress8Bit getRange() {
+        return _range;
+    }
+
+    public final int getFirstRow() {
+        return _range.getFirstRow();
+    }
+
+    public final int getLastRow() {
+        return _range.getLastRow();
+    }
+
+    public final int getFirstColumn() {
+        return (short) _range.getFirstColumn();
+    }
+
+    public final int getLastColumn() {
+        return (short) _range.getLastColumn();
+    }
+
+    protected int getDataSize() {
+        return CellRangeAddress8Bit.ENCODED_SIZE + getExtraDataSize();
+    }
+
+    protected abstract int getExtraDataSize();
+
+    protected abstract void serializeExtraData(LittleEndianOutput out);
+
+    public void serialize(LittleEndianOutput out) {
+        _range.serialize(out);
+        serializeExtraData(out);
+    }
+
+    /**
+     * @param rowIx the row index
+     * @param colIx the column index
+     *
+     * @return {@code true} if (rowIx, colIx) is within the range of this shared value object.
+     *
+     * @see #getRange()
+     */
+    public final boolean isInRange(int rowIx, int colIx) {
+        CellRangeAddress8Bit r = _range;
+        return r.getFirstRow() <= rowIx
+            && r.getLastRow() >= rowIx
+            && r.getFirstColumn() <= colIx
+            && r.getLastColumn() >= colIx;
+    }
+    /**
      * @param rowIx the row index
      * @param colIx the column index
      *
-	 * @return {@code true} if (rowIx, colIx) is within the range of this shared value object.
+     * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value
+     * object's range
      *
      * @see #getRange()
-	 */
-	public final boolean isInRange(int rowIx, int colIx) {
-		CellRangeAddress8Bit r = _range;
-		return r.getFirstRow() <= rowIx
-			&& r.getLastRow() >= rowIx
-			&& r.getFirstColumn() <= colIx
-			&& r.getLastColumn() >= colIx;
-	}
-	/**
-	 * @param rowIx the row index
-	 * @param colIx the column index
-	 *
-	 * @return {@code true} if (rowIx, colIx) describes the first cell in this shared value
-	 * object's range
-	 *
-	 * @see #getRange()
-	 */
-	public final boolean isFirstCell(int rowIx, int colIx) {
-		CellRangeAddress8Bit r = getRange();
-		return r.getFirstRow() == rowIx && r.getFirstColumn() == colIx;
-	}
+     */
+    public final boolean isFirstCell(int rowIx, int colIx) {
+        CellRangeAddress8Bit r = getRange();
+        return r.getFirstRow() == rowIx && r.getFirstColumn() == colIx;
+    }
 }

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StringRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StringRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StringRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StringRecord.java Sat May 22 20:56:44 2021
@@ -31,10 +31,10 @@ import org.apache.poi.util.StringUtil;
  * Stores the cached result of a text formula
  */
 public final class StringRecord extends ContinuableRecord {
-	public static final short sid = 0x0207;
+    public static final short sid = 0x0207;
 
-	private boolean _is16bitUnicode;
-	private String _text;
+    private boolean _is16bitUnicode;
+    private String _text;
 
     public StringRecord() {}
 

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StyleRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StyleRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StyleRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/StyleRecord.java Sat May 22 20:56:44 2021
@@ -31,174 +31,174 @@ import org.apache.poi.util.StringUtil;
  * Describes a builtin to the gui or user defined style
  */
 public final class StyleRecord extends StandardRecord {
-	public static final short sid = 0x0293;
+    public static final short sid = 0x0293;
 
-	private static final BitField styleIndexMask = BitFieldFactory.getInstance(0x0FFF);
-	private static final BitField isBuiltinFlag  = BitFieldFactory.getInstance(0x8000);
+    private static final BitField styleIndexMask = BitFieldFactory.getInstance(0x0FFF);
+    private static final BitField isBuiltinFlag  = BitFieldFactory.getInstance(0x8000);
 
-	/** shared by both user defined and built-in styles */
-	private int field_1_xf_index;
+    /** shared by both user defined and built-in styles */
+    private int field_1_xf_index;
 
-	// only for built in styles
-	private int field_2_builtin_style;
-	private int field_3_outline_style_level;
-
-	// only for user defined styles
-	private boolean field_3_stringHasMultibyte;
-	private String field_4_name;
-
-	/**
-	 * creates a new style record, initially set to 'built-in'
-	 */
-	public StyleRecord() {
-		field_1_xf_index = isBuiltinFlag.set(0);
-	}
-
-	public StyleRecord(StyleRecord other) {
-		super(other);
-		field_1_xf_index = other.field_1_xf_index;
-		field_2_builtin_style = other.field_2_builtin_style;
-		field_3_outline_style_level = other.field_3_outline_style_level;
-		field_3_stringHasMultibyte = other.field_3_stringHasMultibyte;
-		field_4_name = other.field_4_name;
-	}
-
-	public StyleRecord(RecordInputStream in) {
-		field_1_xf_index = in.readShort();
-		if (isBuiltin()) {
-			field_2_builtin_style	   = in.readByte();
-			field_3_outline_style_level = in.readByte();
-		} else {
-			int field_2_name_length = in.readShort();
-
-			if(in.remaining() < 1) {
-				// Some files from Crystal Reports lack the is16BitUnicode byte
-				//  the remaining fields, which is naughty
-				if (field_2_name_length != 0) {
-					throw new RecordFormatException("Ran out of data reading style record");
-				}
-				// guess this is OK if the string length is zero
-				field_4_name = "";
-			} else {
-
-				field_3_stringHasMultibyte = in.readByte() != 0x00;
-				if (field_3_stringHasMultibyte) {
-					field_4_name = StringUtil.readUnicodeLE(in, field_2_name_length);
-				} else {
-					field_4_name = StringUtil.readCompressedUnicode(in, field_2_name_length);
-				}
-			}
-		}
-	}
-
-	/**
-	 * set the actual index of the style extended format record
-	 * @param xfIndex of the xf record
-	 */
-	public void setXFIndex(int xfIndex) {
-		field_1_xf_index = styleIndexMask.setValue(field_1_xf_index, xfIndex);
-	}
-
-	/**
-	 * get the actual index of the style extended format record
-	 * @see #getXFIndex()
-	 * @return index of the xf record
-	 */
-	public int getXFIndex() {
-		return styleIndexMask.getValue(field_1_xf_index);
-	}
-
-	/**
-	 * set the style's name
-	 * @param name of the style
-	 */
-	public void setName(String name) {
-		field_4_name = name;
-		field_3_stringHasMultibyte = StringUtil.hasMultibyte(name);
-		field_1_xf_index = isBuiltinFlag.clear(field_1_xf_index);
-	}
-
-	/**
-	 * if this is a builtin style set the number of the built in style
-	 * @param  builtinStyleId style number (0-7)
-	 *
-	 */
-	public void setBuiltinStyle(int builtinStyleId) {
-		field_1_xf_index = isBuiltinFlag.set(field_1_xf_index);
-		field_2_builtin_style = builtinStyleId;
-	}
-
-	/**
-	 * set the row or column level of the style (if builtin 1||2)
-	 *
-	 * @param level The outline-level
-	 */
-	public void setOutlineStyleLevel(int level) {
-		field_3_outline_style_level = level & 0x00FF;
-	}
-
-	public boolean isBuiltin(){
-		return isBuiltinFlag.isSet(field_1_xf_index);
-	}
-
-	/**
-	 * get the style's name
-	 * @return name of the style
-	 */
-	public String getName() {
-		return field_4_name;
-	}
-
-	@Override
-	protected int getDataSize() {
-		if (isBuiltin()) {
-			return 4; // short, byte, byte
-		}
-		return 2 // short xf index
-			+ 3 // str len + flag
-			+ field_4_name.length() * (field_3_stringHasMultibyte ? 2 : 1);
-	}
-
-	@Override
-	public void serialize(LittleEndianOutput out) {
-		out.writeShort(field_1_xf_index);
-		if (isBuiltin()) {
-			out.writeByte(field_2_builtin_style);
-			out.writeByte(field_3_outline_style_level);
-		} else {
-			out.writeShort(field_4_name.length());
-			out.writeByte(field_3_stringHasMultibyte ? 0x01 : 0x00);
-			if (field_3_stringHasMultibyte) {
-				StringUtil.putUnicodeLE(getName(), out);
-			} else {
-				StringUtil.putCompressedUnicode(getName(), out);
-			}
-		}
-	}
-
-	@Override
-	public short getSid() {
-		return sid;
-	}
-
-	@Override
-	public StyleRecord copy() {
-		return new StyleRecord(this);
-	}
-
-	@Override
-	public HSSFRecordTypes getGenericRecordType() {
-		return HSSFRecordTypes.STYLE;
-	}
-
-	@Override
-	public Map<String, Supplier<?>> getGenericProperties() {
-		return GenericRecordUtil.getGenericProperties(
-			"xfIndex", this::getXFIndex,
-			"type", () -> isBuiltin() ? "built-in" : "user-defined",
-			"builtin_style", () -> field_2_builtin_style,
-			"outline_level", () -> field_3_outline_style_level,
-			"name", this::getName
-		);
-	}
+    // only for built in styles
+    private int field_2_builtin_style;
+    private int field_3_outline_style_level;
+
+    // only for user defined styles
+    private boolean field_3_stringHasMultibyte;
+    private String field_4_name;
+
+    /**
+     * creates a new style record, initially set to 'built-in'
+     */
+    public StyleRecord() {
+        field_1_xf_index = isBuiltinFlag.set(0);
+    }
+
+    public StyleRecord(StyleRecord other) {
+        super(other);
+        field_1_xf_index = other.field_1_xf_index;
+        field_2_builtin_style = other.field_2_builtin_style;
+        field_3_outline_style_level = other.field_3_outline_style_level;
+        field_3_stringHasMultibyte = other.field_3_stringHasMultibyte;
+        field_4_name = other.field_4_name;
+    }
+
+    public StyleRecord(RecordInputStream in) {
+        field_1_xf_index = in.readShort();
+        if (isBuiltin()) {
+            field_2_builtin_style      = in.readByte();
+            field_3_outline_style_level = in.readByte();
+        } else {
+            int field_2_name_length = in.readShort();
+
+            if(in.remaining() < 1) {
+                // Some files from Crystal Reports lack the is16BitUnicode byte
+                //  the remaining fields, which is naughty
+                if (field_2_name_length != 0) {
+                    throw new RecordFormatException("Ran out of data reading style record");
+                }
+                // guess this is OK if the string length is zero
+                field_4_name = "";
+            } else {
+
+                field_3_stringHasMultibyte = in.readByte() != 0x00;
+                if (field_3_stringHasMultibyte) {
+                    field_4_name = StringUtil.readUnicodeLE(in, field_2_name_length);
+                } else {
+                    field_4_name = StringUtil.readCompressedUnicode(in, field_2_name_length);
+                }
+            }
+        }
+    }
+
+    /**
+     * set the actual index of the style extended format record
+     * @param xfIndex of the xf record
+     */
+    public void setXFIndex(int xfIndex) {
+        field_1_xf_index = styleIndexMask.setValue(field_1_xf_index, xfIndex);
+    }
+
+    /**
+     * get the actual index of the style extended format record
+     * @see #getXFIndex()
+     * @return index of the xf record
+     */
+    public int getXFIndex() {
+        return styleIndexMask.getValue(field_1_xf_index);
+    }
+
+    /**
+     * set the style's name
+     * @param name of the style
+     */
+    public void setName(String name) {
+        field_4_name = name;
+        field_3_stringHasMultibyte = StringUtil.hasMultibyte(name);
+        field_1_xf_index = isBuiltinFlag.clear(field_1_xf_index);
+    }
+
+    /**
+     * if this is a builtin style set the number of the built in style
+     * @param  builtinStyleId style number (0-7)
+     *
+     */
+    public void setBuiltinStyle(int builtinStyleId) {
+        field_1_xf_index = isBuiltinFlag.set(field_1_xf_index);
+        field_2_builtin_style = builtinStyleId;
+    }
+
+    /**
+     * set the row or column level of the style (if builtin 1||2)
+     *
+     * @param level The outline-level
+     */
+    public void setOutlineStyleLevel(int level) {
+        field_3_outline_style_level = level & 0x00FF;
+    }
+
+    public boolean isBuiltin(){
+        return isBuiltinFlag.isSet(field_1_xf_index);
+    }
+
+    /**
+     * get the style's name
+     * @return name of the style
+     */
+    public String getName() {
+        return field_4_name;
+    }
+
+    @Override
+    protected int getDataSize() {
+        if (isBuiltin()) {
+            return 4; // short, byte, byte
+        }
+        return 2 // short xf index
+            + 3 // str len + flag
+            + field_4_name.length() * (field_3_stringHasMultibyte ? 2 : 1);
+    }
+
+    @Override
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_xf_index);
+        if (isBuiltin()) {
+            out.writeByte(field_2_builtin_style);
+            out.writeByte(field_3_outline_style_level);
+        } else {
+            out.writeShort(field_4_name.length());
+            out.writeByte(field_3_stringHasMultibyte ? 0x01 : 0x00);
+            if (field_3_stringHasMultibyte) {
+                StringUtil.putUnicodeLE(getName(), out);
+            } else {
+                StringUtil.putCompressedUnicode(getName(), out);
+            }
+        }
+    }
+
+    @Override
+    public short getSid() {
+        return sid;
+    }
+
+    @Override
+    public StyleRecord copy() {
+        return new StyleRecord(this);
+    }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.STYLE;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "xfIndex", this::getXFIndex,
+            "type", () -> isBuiltin() ? "built-in" : "user-defined",
+            "builtin_style", () -> field_2_builtin_style,
+            "outline_level", () -> field_3_outline_style_level,
+            "name", this::getName
+        );
+    }
 }

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SubRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SubRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SubRecord.java Sat May 22 20:56:44 2021
@@ -38,61 +38,61 @@ import org.apache.poi.util.LittleEndianO
  */
 public abstract class SubRecord implements Duplicatable, GenericRecord {
 
-	public enum SubRecordTypes {
-		UNKNOWN(-1, UnknownSubRecord::new),
-		END(0x0000, EndSubRecord::new),
-		GROUP_MARKER(0x0006, GroupMarkerSubRecord::new),
-		FT_CF(0x0007, FtCfSubRecord::new),
-		FT_PIO_GRBIT(0x0008, FtPioGrbitSubRecord::new),
-		EMBEDDED_OBJECT_REF(0x0009, EmbeddedObjectRefSubRecord::new),
-		FT_CBLS(0x000C, FtCblsSubRecord::new),
-		NOTE_STRUCTURE(0x000D, NoteStructureSubRecord::new),
-		LBS_DATA(0x0013, LbsDataSubRecord::new),
-		COMMON_OBJECT_DATA(0x0015, CommonObjectDataSubRecord::new),
-		;
-
-		@FunctionalInterface
-		public interface RecordConstructor<T extends SubRecord> {
-			/**
-			 * read a sub-record from the supplied stream
-			 *
-			 * @param in    the stream to read from
-			 * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord,
-			 *   we need it to propagate to next sub-records as it defines what data follows
-			 * @return the created sub-record
-			 */
-			T apply(LittleEndianInput in, int size, int cmoOt);
-		}
-
-		private static final Map<Short,SubRecordTypes> LOOKUP =
-			Arrays.stream(values()).collect(Collectors.toMap(SubRecordTypes::getSid, Function.identity()));
-
-		public final short sid;
-		public final RecordConstructor<?> recordConstructor;
-
-		SubRecordTypes(int sid, RecordConstructor<?> recordConstructor) {
-			this.sid = (short)sid;
-			this.recordConstructor = recordConstructor;
-		}
-
-		public static SubRecordTypes forSID(int sid) {
-			return LOOKUP.getOrDefault((short)sid, UNKNOWN);
-		}
-
-		public short getSid() {
-			return sid;
-		}
-	}
+    public enum SubRecordTypes {
+        UNKNOWN(-1, UnknownSubRecord::new),
+        END(0x0000, EndSubRecord::new),
+        GROUP_MARKER(0x0006, GroupMarkerSubRecord::new),
+        FT_CF(0x0007, FtCfSubRecord::new),
+        FT_PIO_GRBIT(0x0008, FtPioGrbitSubRecord::new),
+        EMBEDDED_OBJECT_REF(0x0009, EmbeddedObjectRefSubRecord::new),
+        FT_CBLS(0x000C, FtCblsSubRecord::new),
+        NOTE_STRUCTURE(0x000D, NoteStructureSubRecord::new),
+        LBS_DATA(0x0013, LbsDataSubRecord::new),
+        COMMON_OBJECT_DATA(0x0015, CommonObjectDataSubRecord::new),
+        ;
+
+        @FunctionalInterface
+        public interface RecordConstructor<T extends SubRecord> {
+            /**
+             * read a sub-record from the supplied stream
+             *
+             * @param in    the stream to read from
+             * @param cmoOt the objectType field of the containing CommonObjectDataSubRecord,
+             *   we need it to propagate to next sub-records as it defines what data follows
+             * @return the created sub-record
+             */
+            T apply(LittleEndianInput in, int size, int cmoOt);
+        }
+
+        private static final Map<Short,SubRecordTypes> LOOKUP =
+            Arrays.stream(values()).collect(Collectors.toMap(SubRecordTypes::getSid, Function.identity()));
+
+        public final short sid;
+        public final RecordConstructor<?> recordConstructor;
+
+        SubRecordTypes(int sid, RecordConstructor<?> recordConstructor) {
+            this.sid = (short)sid;
+            this.recordConstructor = recordConstructor;
+        }
+
+        public static SubRecordTypes forSID(int sid) {
+            return LOOKUP.getOrDefault((short)sid, UNKNOWN);
+        }
+
+        public short getSid() {
+            return sid;
+        }
+    }
 
 
-	//arbitrarily selected; may need to increase
-	private static final int MAX_RECORD_LENGTH = 1_000_000;
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
 
-	protected SubRecord() {}
+    protected SubRecord() {}
 
-	protected SubRecord(SubRecord other) {}
+    protected SubRecord(SubRecord other) {}
 
-	/**
+    /**
      * read a sub-record from the supplied stream
      *
      * @param in    the stream to read from
@@ -101,35 +101,35 @@ public abstract class SubRecord implemen
      * @return the created sub-record
      */
     public static SubRecord createSubRecord(LittleEndianInput in, int cmoOt) {
-		int sid = in.readUShort();
-		// Often (but not always) the datasize for the sub-record
-		int size = in.readUShort();
-		SubRecordTypes srt = SubRecordTypes.forSID(sid);
-		return srt.recordConstructor.apply(in, size, srt == SubRecordTypes.UNKNOWN ? sid : cmoOt);
-	}
-
-	@Override
-	public final String toString() {
-		return GenericRecordJsonWriter.marshal(this);
-	}
-
-	/**
-	 * @return the size of the data for this record (which is always 4 bytes less than the total
-	 * record size).  Note however, that ushort encoded after the record sid is usually but not
-	 * always the data size.
-	 */
-	protected abstract int getDataSize();
-	public byte[] serialize() {
-		int size = getDataSize() + 4;
-		UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(size);
-		serialize(new LittleEndianOutputStream(baos));
-		if (baos.size() != size) {
-			throw new RuntimeException("write size mismatch");
-		}
-		return baos.toByteArray();
-	}
+        int sid = in.readUShort();
+        // Often (but not always) the datasize for the sub-record
+        int size = in.readUShort();
+        SubRecordTypes srt = SubRecordTypes.forSID(sid);
+        return srt.recordConstructor.apply(in, size, srt == SubRecordTypes.UNKNOWN ? sid : cmoOt);
+    }
+
+    @Override
+    public final String toString() {
+        return GenericRecordJsonWriter.marshal(this);
+    }
 
-	public abstract void serialize(LittleEndianOutput out);
+    /**
+     * @return the size of the data for this record (which is always 4 bytes less than the total
+     * record size).  Note however, that ushort encoded after the record sid is usually but not
+     * always the data size.
+     */
+    protected abstract int getDataSize();
+    public byte[] serialize() {
+        int size = getDataSize() + 4;
+        UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(size);
+        serialize(new LittleEndianOutputStream(baos));
+        if (baos.size() != size) {
+            throw new RuntimeException("write size mismatch");
+        }
+        return baos.toByteArray();
+    }
+
+    public abstract void serialize(LittleEndianOutput out);
 
 
     /**
@@ -146,48 +146,48 @@ public abstract class SubRecord implemen
 
     private static final class UnknownSubRecord extends SubRecord {
 
-		private final int _sid;
-		private final byte[] _data;
+        private final int _sid;
+        private final byte[] _data;
 
-		public UnknownSubRecord(LittleEndianInput in, int size, int sid) {
-			_sid = sid;
-	    	byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
-	    	in.readFully(buf);
-	        _data = buf;
-		}
-		@Override
-		protected int getDataSize() {
-			return _data.length;
-		}
-		@Override
-		public void serialize(LittleEndianOutput out) {
-			out.writeShort(_sid);
-			out.writeShort(_data.length);
-			out.write(_data);
-		}
-
-		@Override
-		public UnknownSubRecord copy() {
-			return this;
-		}
-
-		@Override
-		public SubRecordTypes getGenericRecordType() {
-			return SubRecordTypes.UNKNOWN;
-		}
-
-		@Override
-		public Map<String, Supplier<?>> getGenericProperties() {
-			return GenericRecordUtil.getGenericProperties(
-				"sid", () -> _sid,
-				"data", () -> _data
-			);
-		}
-	}
+        public UnknownSubRecord(LittleEndianInput in, int size, int sid) {
+            _sid = sid;
+            byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
+            in.readFully(buf);
+            _data = buf;
+        }
+        @Override
+        protected int getDataSize() {
+            return _data.length;
+        }
+        @Override
+        public void serialize(LittleEndianOutput out) {
+            out.writeShort(_sid);
+            out.writeShort(_data.length);
+            out.write(_data);
+        }
+
+        @Override
+        public UnknownSubRecord copy() {
+            return this;
+        }
+
+        @Override
+        public SubRecordTypes getGenericRecordType() {
+            return SubRecordTypes.UNKNOWN;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "sid", () -> _sid,
+                "data", () -> _data
+            );
+        }
+    }
 
-	@Override
-	public abstract SubRecord copy();
+    @Override
+    public abstract SubRecord copy();
 
-	@Override
-	public abstract SubRecordTypes getGenericRecordType();
+    @Override
+    public abstract SubRecordTypes getGenericRecordType();
 }

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SupBookRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SupBookRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SupBookRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/SupBookRecord.java Sat May 22 20:56:44 2021
@@ -200,39 +200,39 @@ public final class SupBookRecord extends
     }
     private static String decodeFileName(String encodedUrl) {
         /* see "MICROSOFT OFFICE EXCEL 97-2007  BINARY FILE FORMAT SPECIFICATION" */
-    	StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder();
         for(int i=1; i<encodedUrl.length(); i++) {
-        	char c = encodedUrl.charAt(i);
-        	switch (c) {
-        	case CH_VOLUME:
-        		char driveLetter = encodedUrl.charAt(++i);
-        		if (driveLetter == '@') {
-        			sb.append("\\\\");
-        		} else {
-        			//Windows notation for drive letters
-        			sb.append(driveLetter).append(":");
-        		}
-        		break;
-        	case CH_SAME_VOLUME:
+            char c = encodedUrl.charAt(i);
+            switch (c) {
+            case CH_VOLUME:
+                char driveLetter = encodedUrl.charAt(++i);
+                if (driveLetter == '@') {
+                    sb.append("\\\\");
+                } else {
+                    //Windows notation for drive letters
+                    sb.append(driveLetter).append(":");
+                }
+                break;
+            case CH_SAME_VOLUME:
             case CH_DOWN_DIR:
-        		sb.append(PATH_SEPERATOR);
-        		break;
-        	case CH_UP_DIR:
-        		sb.append("..").append(PATH_SEPERATOR);
-        		break;
-        	case CH_LONG_VOLUME:
-        		//Don't known to handle...
-        		LOG.atWarn().log("Found unexpected key: ChLongVolume - IGNORING");
-        		break;
-        	case CH_STARTUP_DIR:
-        	case CH_ALT_STARTUP_DIR:
-        	case CH_LIB_DIR:
-        		LOG.atWarn().log("EXCEL.EXE path unknown - using this directory instead: .");
-        		sb.append(".").append(PATH_SEPERATOR);
-        		break;
-        	default:
-        		sb.append(c);
-        	}
+                sb.append(PATH_SEPERATOR);
+                break;
+            case CH_UP_DIR:
+                sb.append("..").append(PATH_SEPERATOR);
+                break;
+            case CH_LONG_VOLUME:
+                //Don't known to handle...
+                LOG.atWarn().log("Found unexpected key: ChLongVolume - IGNORING");
+                break;
+            case CH_STARTUP_DIR:
+            case CH_ALT_STARTUP_DIR:
+            case CH_LIB_DIR:
+                LOG.atWarn().log("EXCEL.EXE path unknown - using this directory instead: .");
+                sb.append(".").append(PATH_SEPERATOR);
+                break;
+            default:
+                sb.append(c);
+            }
         }
         return sb.toString();
     }
@@ -241,8 +241,8 @@ public final class SupBookRecord extends
     }
 
     public void setURL(String pUrl) {
-    	//Keep the first marker character!
-    	field_2_encoded_url = field_2_encoded_url.substring(0, 1) + pUrl;
+        //Keep the first marker character!
+        field_2_encoded_url = field_2_encoded_url.substring(0, 1) + pUrl;
     }
 
     @Override

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableRecord.java Sat May 22 20:56:44 2021
@@ -35,163 +35,163 @@ import org.apache.poi.util.LittleEndianO
  * which should only contain a single {@link TblPtg Ptg}.
  */
 public final class TableRecord extends SharedValueRecordBase {
-	public static final short sid = 0x0236;
+    public static final short sid = 0x0236;
 
-	private static final BitField alwaysCalc      = BitFieldFactory.getInstance(0x0001);
-	private static final BitField calcOnOpen      = BitFieldFactory.getInstance(0x0002);
-	private static final BitField rowOrColInpCell = BitFieldFactory.getInstance(0x0004);
-	private static final BitField oneOrTwoVar     = BitFieldFactory.getInstance(0x0008);
-	private static final BitField rowDeleted      = BitFieldFactory.getInstance(0x0010);
-	private static final BitField colDeleted      = BitFieldFactory.getInstance(0x0020);
-
-	private int field_5_flags;
-	private int field_6_res;
-	private int field_7_rowInputRow;
-	private int field_8_colInputRow;
-	private int field_9_rowInputCol;
-	private int field_10_colInputCol;
-
-	public TableRecord(TableRecord other) {
-		super(other);
-		field_5_flags        = other.field_5_flags;
-		field_6_res          = other.field_6_res;
-		field_7_rowInputRow  = other.field_7_rowInputRow;
-		field_8_colInputRow  = other.field_8_colInputRow;
-		field_9_rowInputCol  = other.field_9_rowInputCol;
-		field_10_colInputCol = other.field_10_colInputCol;
-	}
-
-	public TableRecord(RecordInputStream in) {
-		super(in);
-		field_5_flags        = in.readByte();
-		field_6_res          = in.readByte();
-		field_7_rowInputRow  = in.readShort();
-		field_8_colInputRow  = in.readShort();
-		field_9_rowInputCol  = in.readShort();
-		field_10_colInputCol = in.readShort();
-	}
-
-	public TableRecord(CellRangeAddress8Bit range) {
-		super(range);
-		field_6_res = 0;
-	}
-
-	public int getFlags() {
-		return field_5_flags;
-	}
-	public void setFlags(int flags) {
-		field_5_flags = flags;
-	}
-
-	public int getRowInputRow() {
-		return field_7_rowInputRow;
-	}
-	public void setRowInputRow(int rowInputRow) {
-		field_7_rowInputRow = rowInputRow;
-	}
-
-	public int getColInputRow() {
-		return field_8_colInputRow;
-	}
-	public void setColInputRow(int colInputRow) {
-		field_8_colInputRow = colInputRow;
-	}
-
-	public int getRowInputCol() {
-		return field_9_rowInputCol;
-	}
-	public void setRowInputCol(int rowInputCol) {
-		field_9_rowInputCol = rowInputCol;
-	}
-
-	public int getColInputCol() {
-		return field_10_colInputCol;
-	}
-	public void setColInputCol(int colInputCol) {
-		field_10_colInputCol = colInputCol;
-	}
-
-
-	public boolean isAlwaysCalc() {
-		return alwaysCalc.isSet(field_5_flags);
-	}
-	public void setAlwaysCalc(boolean flag) {
-		field_5_flags = alwaysCalc.setBoolean(field_5_flags, flag);
-	}
-
-	public boolean isRowOrColInpCell() {
-		return rowOrColInpCell.isSet(field_5_flags);
-	}
-	public void setRowOrColInpCell(boolean flag) {
-		field_5_flags = rowOrColInpCell.setBoolean(field_5_flags, flag);
-	}
-
-	public boolean isOneNotTwoVar() {
-		return oneOrTwoVar.isSet(field_5_flags);
-	}
-	public void setOneNotTwoVar(boolean flag) {
-		field_5_flags = oneOrTwoVar.setBoolean(field_5_flags, flag);
-	}
-
-	public boolean isColDeleted() {
-		return colDeleted.isSet(field_5_flags);
-	}
-	public void setColDeleted(boolean flag) {
-		field_5_flags = colDeleted.setBoolean(field_5_flags, flag);
-	}
-
-	public boolean isRowDeleted() {
-		return rowDeleted.isSet(field_5_flags);
-	}
-	public void setRowDeleted(boolean flag) {
-		field_5_flags = rowDeleted.setBoolean(field_5_flags, flag);
-	}
-
-
-	public short getSid() {
-		return sid;
-	}
-	protected int getExtraDataSize() {
-		return
-		2 // 2 byte fields
-		+ 8; // 4 short fields
-	}
-	protected void serializeExtraData(LittleEndianOutput out) {
-		out.writeByte(field_5_flags);
-		out.writeByte(field_6_res);
-		out.writeShort(field_7_rowInputRow);
-		out.writeShort(field_8_colInputRow);
-		out.writeShort(field_9_rowInputCol);
-		out.writeShort(field_10_colInputCol);
-	}
-
-	@Override
-	public TableRecord copy() {
-		return new TableRecord(this);
-	}
-
-	private static CellReference cr(int rowIx, int colIxAndFlags) {
-		int colIx = colIxAndFlags & 0x00FF;
-		boolean isRowAbs = (colIxAndFlags & 0x8000) == 0;
-		boolean isColAbs = (colIxAndFlags & 0x4000) == 0;
-		return new CellReference(rowIx, colIx, isRowAbs, isColAbs);
-	}
-
-	@Override
-	public HSSFRecordTypes getGenericRecordType() {
-		return HSSFRecordTypes.TABLE;
-	}
-
-	@Override
-	public Map<String, Supplier<?>> getGenericProperties() {
-		return GenericRecordUtil.getGenericProperties(
-			"range", this::getRange,
-			"flags", getBitsAsString(this::getFlags,
-				new BitField[]{alwaysCalc, calcOnOpen, rowOrColInpCell, oneOrTwoVar, rowDeleted, colDeleted},
-				new String[]{"ALWAYS_CALC","CALC_ON_OPEN","ROW_OR_COL_INP_CELL","ONE_OR_TWO_VAR","ROW_DELETED","COL_DELETED"}),
-			"reserved", () -> field_6_res,
-			"rowInput", () -> cr(field_7_rowInputRow, field_8_colInputRow),
-			"colInput", () -> cr(field_9_rowInputCol, field_10_colInputCol)
-		);
-	}
+    private static final BitField alwaysCalc      = BitFieldFactory.getInstance(0x0001);
+    private static final BitField calcOnOpen      = BitFieldFactory.getInstance(0x0002);
+    private static final BitField rowOrColInpCell = BitFieldFactory.getInstance(0x0004);
+    private static final BitField oneOrTwoVar     = BitFieldFactory.getInstance(0x0008);
+    private static final BitField rowDeleted      = BitFieldFactory.getInstance(0x0010);
+    private static final BitField colDeleted      = BitFieldFactory.getInstance(0x0020);
+
+    private int field_5_flags;
+    private int field_6_res;
+    private int field_7_rowInputRow;
+    private int field_8_colInputRow;
+    private int field_9_rowInputCol;
+    private int field_10_colInputCol;
+
+    public TableRecord(TableRecord other) {
+        super(other);
+        field_5_flags        = other.field_5_flags;
+        field_6_res          = other.field_6_res;
+        field_7_rowInputRow  = other.field_7_rowInputRow;
+        field_8_colInputRow  = other.field_8_colInputRow;
+        field_9_rowInputCol  = other.field_9_rowInputCol;
+        field_10_colInputCol = other.field_10_colInputCol;
+    }
+
+    public TableRecord(RecordInputStream in) {
+        super(in);
+        field_5_flags        = in.readByte();
+        field_6_res          = in.readByte();
+        field_7_rowInputRow  = in.readShort();
+        field_8_colInputRow  = in.readShort();
+        field_9_rowInputCol  = in.readShort();
+        field_10_colInputCol = in.readShort();
+    }
+
+    public TableRecord(CellRangeAddress8Bit range) {
+        super(range);
+        field_6_res = 0;
+    }
+
+    public int getFlags() {
+        return field_5_flags;
+    }
+    public void setFlags(int flags) {
+        field_5_flags = flags;
+    }
+
+    public int getRowInputRow() {
+        return field_7_rowInputRow;
+    }
+    public void setRowInputRow(int rowInputRow) {
+        field_7_rowInputRow = rowInputRow;
+    }
+
+    public int getColInputRow() {
+        return field_8_colInputRow;
+    }
+    public void setColInputRow(int colInputRow) {
+        field_8_colInputRow = colInputRow;
+    }
+
+    public int getRowInputCol() {
+        return field_9_rowInputCol;
+    }
+    public void setRowInputCol(int rowInputCol) {
+        field_9_rowInputCol = rowInputCol;
+    }
+
+    public int getColInputCol() {
+        return field_10_colInputCol;
+    }
+    public void setColInputCol(int colInputCol) {
+        field_10_colInputCol = colInputCol;
+    }
+
+
+    public boolean isAlwaysCalc() {
+        return alwaysCalc.isSet(field_5_flags);
+    }
+    public void setAlwaysCalc(boolean flag) {
+        field_5_flags = alwaysCalc.setBoolean(field_5_flags, flag);
+    }
+
+    public boolean isRowOrColInpCell() {
+        return rowOrColInpCell.isSet(field_5_flags);
+    }
+    public void setRowOrColInpCell(boolean flag) {
+        field_5_flags = rowOrColInpCell.setBoolean(field_5_flags, flag);
+    }
+
+    public boolean isOneNotTwoVar() {
+        return oneOrTwoVar.isSet(field_5_flags);
+    }
+    public void setOneNotTwoVar(boolean flag) {
+        field_5_flags = oneOrTwoVar.setBoolean(field_5_flags, flag);
+    }
+
+    public boolean isColDeleted() {
+        return colDeleted.isSet(field_5_flags);
+    }
+    public void setColDeleted(boolean flag) {
+        field_5_flags = colDeleted.setBoolean(field_5_flags, flag);
+    }
+
+    public boolean isRowDeleted() {
+        return rowDeleted.isSet(field_5_flags);
+    }
+    public void setRowDeleted(boolean flag) {
+        field_5_flags = rowDeleted.setBoolean(field_5_flags, flag);
+    }
+
+
+    public short getSid() {
+        return sid;
+    }
+    protected int getExtraDataSize() {
+        return
+        2 // 2 byte fields
+        + 8; // 4 short fields
+    }
+    protected void serializeExtraData(LittleEndianOutput out) {
+        out.writeByte(field_5_flags);
+        out.writeByte(field_6_res);
+        out.writeShort(field_7_rowInputRow);
+        out.writeShort(field_8_colInputRow);
+        out.writeShort(field_9_rowInputCol);
+        out.writeShort(field_10_colInputCol);
+    }
+
+    @Override
+    public TableRecord copy() {
+        return new TableRecord(this);
+    }
+
+    private static CellReference cr(int rowIx, int colIxAndFlags) {
+        int colIx = colIxAndFlags & 0x00FF;
+        boolean isRowAbs = (colIxAndFlags & 0x8000) == 0;
+        boolean isColAbs = (colIxAndFlags & 0x4000) == 0;
+        return new CellReference(rowIx, colIx, isRowAbs, isColAbs);
+    }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.TABLE;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "range", this::getRange,
+            "flags", getBitsAsString(this::getFlags,
+                new BitField[]{alwaysCalc, calcOnOpen, rowOrColInpCell, oneOrTwoVar, rowDeleted, colDeleted},
+                new String[]{"ALWAYS_CALC","CALC_ON_OPEN","ROW_OR_COL_INP_CELL","ONE_OR_TWO_VAR","ROW_DELETED","COL_DELETED"}),
+            "reserved", () -> field_6_res,
+            "rowInput", () -> cr(field_7_rowInputRow, field_8_colInputRow),
+            "colInput", () -> cr(field_9_rowInputCol, field_10_colInputCol)
+        );
+    }
 }

Modified: poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableStylesRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableStylesRecord.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableStylesRecord.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/hssf/record/TableStylesRecord.java Sat May 22 20:56:44 2021
@@ -28,83 +28,83 @@ import org.apache.poi.util.StringUtil;
  * TABLESTYLES (0x088E)
  */
 public final class TableStylesRecord extends StandardRecord {
-	public static final short sid = 0x088E;
+    public static final short sid = 0x088E;
 
-	private int rt;
-	private int grbitFrt;
-	private final byte[] unused = new byte[8];
-	private int cts;
-
-	private String rgchDefListStyle;
-	private String rgchDefPivotStyle;
-
-
-	public TableStylesRecord(TableStylesRecord other) {
-		super(other);
-		rt = other.rt;
-		grbitFrt = other.grbitFrt;
-		System.arraycopy(other.unused, 0, unused, 0, unused.length);
-		cts = other.cts;
-		rgchDefListStyle = other.rgchDefListStyle;
-		rgchDefPivotStyle = other.rgchDefPivotStyle;
-	}
-
-	public TableStylesRecord(RecordInputStream in) {
-		rt = in.readUShort();
-		grbitFrt = in.readUShort();
-		in.readFully(unused);
-		cts = in.readInt();
-		int cchDefListStyle = in.readUShort();
-		int cchDefPivotStyle = in.readUShort();
-
-		rgchDefListStyle = in.readUnicodeLEString(cchDefListStyle);
-		rgchDefPivotStyle = in.readUnicodeLEString(cchDefPivotStyle);
-	}
-
-	@Override
-	protected void serialize(LittleEndianOutput out) {
-		out.writeShort(rt);
-		out.writeShort(grbitFrt);
-		out.write(unused);
-		out.writeInt(cts);
-
-		out.writeShort(rgchDefListStyle.length());
-		out.writeShort(rgchDefPivotStyle.length());
-
-		StringUtil.putUnicodeLE(rgchDefListStyle, out);
-		StringUtil.putUnicodeLE(rgchDefPivotStyle, out);
-	}
-
-	@Override
-	protected int getDataSize() {
-		return 2 + 2 + 8 + 4 + 2 + 2
-			+ (2*rgchDefListStyle.length()) + (2*rgchDefPivotStyle.length());
-	}
-
-	@Override
-	public short getSid() {
-		return sid;
-	}
-
-	@Override
-	public TableStylesRecord copy() {
-		return new TableStylesRecord(this);
-	}
-
-	@Override
-	public HSSFRecordTypes getGenericRecordType() {
-		return HSSFRecordTypes.TABLE_STYLES;
-	}
-
-	@Override
-	public Map<String, Supplier<?>> getGenericProperties() {
-		return GenericRecordUtil.getGenericProperties(
-			"rt", () -> rt,
-			"grbitFrt", () -> grbitFrt,
-			"unused", () -> unused,
-			"cts", () -> cts,
-			"rgchDefListStyle", () -> rgchDefListStyle,
-			"rgchDefPivotStyle", () -> rgchDefPivotStyle
-		);
-	}
+    private int rt;
+    private int grbitFrt;
+    private final byte[] unused = new byte[8];
+    private int cts;
+
+    private String rgchDefListStyle;
+    private String rgchDefPivotStyle;
+
+
+    public TableStylesRecord(TableStylesRecord other) {
+        super(other);
+        rt = other.rt;
+        grbitFrt = other.grbitFrt;
+        System.arraycopy(other.unused, 0, unused, 0, unused.length);
+        cts = other.cts;
+        rgchDefListStyle = other.rgchDefListStyle;
+        rgchDefPivotStyle = other.rgchDefPivotStyle;
+    }
+
+    public TableStylesRecord(RecordInputStream in) {
+        rt = in.readUShort();
+        grbitFrt = in.readUShort();
+        in.readFully(unused);
+        cts = in.readInt();
+        int cchDefListStyle = in.readUShort();
+        int cchDefPivotStyle = in.readUShort();
+
+        rgchDefListStyle = in.readUnicodeLEString(cchDefListStyle);
+        rgchDefPivotStyle = in.readUnicodeLEString(cchDefPivotStyle);
+    }
+
+    @Override
+    protected void serialize(LittleEndianOutput out) {
+        out.writeShort(rt);
+        out.writeShort(grbitFrt);
+        out.write(unused);
+        out.writeInt(cts);
+
+        out.writeShort(rgchDefListStyle.length());
+        out.writeShort(rgchDefPivotStyle.length());
+
+        StringUtil.putUnicodeLE(rgchDefListStyle, out);
+        StringUtil.putUnicodeLE(rgchDefPivotStyle, out);
+    }
+
+    @Override
+    protected int getDataSize() {
+        return 2 + 2 + 8 + 4 + 2 + 2
+            + (2*rgchDefListStyle.length()) + (2*rgchDefPivotStyle.length());
+    }
+
+    @Override
+    public short getSid() {
+        return sid;
+    }
+
+    @Override
+    public TableStylesRecord copy() {
+        return new TableStylesRecord(this);
+    }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.TABLE_STYLES;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "rt", () -> rt,
+            "grbitFrt", () -> grbitFrt,
+            "unused", () -> unused,
+            "cts", () -> cts,
+            "rgchDefListStyle", () -> rgchDefListStyle,
+            "rgchDefPivotStyle", () -> rgchDefPivotStyle
+        );
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org