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