diff --git a/src/java/org/apache/poi/hssf/record/RecordInputStream.java b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
index fe6a4b2ea3..c23868c711 100755
--- a/src/java/org/apache/poi/hssf/record/RecordInputStream.java
+++ b/src/java/org/apache/poi/hssf/record/RecordInputStream.java
@@ -33,7 +33,7 @@ public class RecordInputStream extends InputStream {
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
public final static short MAX_RECORD_DATA_SIZE = 8224;
private static final int INVALID_SID_VALUE = -1;
-
+
private InputStream in;
protected short currentSid;
protected short currentLength = -1;
@@ -42,34 +42,34 @@ public class RecordInputStream extends InputStream {
protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
protected short recordOffset;
protected long pos;
-
+
private boolean autoContinue = true;
- public RecordInputStream(InputStream in) throws RecordFormatException {
+ public RecordInputStream(InputStream in) throws RecordFormatException {
this.in = in;
try {
nextSid = LittleEndian.readShort(in);
- //Dont increment the pos just yet (technically we are at the start of
- //the record stream until nextRecord is called).
+ //Don't increment the pos just yet (technically we are at the start of
+ //the record stream until nextRecord is called).
} catch (IOException ex) {
throw new RecordFormatException("Error reading bytes", ex);
}
}
-
- /** This method will read a byte from the current record*/
- public int read() {
- checkRecordPosition();
- byte result = data[recordOffset];
- recordOffset += 1;
- pos += 1;
- return result;
- }
-
+ /** This method will read a byte from the current record*/
+ public int read() {
+ checkRecordPosition(LittleEndian.BYTE_SIZE);
+
+ byte result = data[recordOffset];
+ recordOffset += LittleEndian.BYTE_SIZE;
+ pos += LittleEndian.BYTE_SIZE;
+ return result;
+ }
+
public short getSid() {
return currentSid;
}
-
+
public short getLength() {
return currentLength;
}
@@ -85,12 +85,11 @@ public class RecordInputStream extends InputStream {
public boolean hasNextRecord() {
return nextSid != INVALID_SID_VALUE;
}
-
+
/** Moves to the next record in the stream.
- *
+ *
* Note: The auto continue flag is reset to true
*/
-
public void nextRecord() throws RecordFormatException {
if ((currentLength != -1) && (currentLength != recordOffset)) {
System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(currentSid));
@@ -100,7 +99,7 @@ public class RecordInputStream extends InputStream {
autoContinue = true;
try {
recordOffset = 0;
- currentLength = LittleEndian.readShort(in);
+ currentLength = LittleEndian.readShort(in);
if (currentLength > MAX_RECORD_DATA_SIZE)
throw new RecordFormatException("The content of an excel record cannot exceed "+MAX_RECORD_DATA_SIZE+" bytes");
pos += LittleEndian.SHORT_SIZE;
@@ -113,138 +112,124 @@ public class RecordInputStream extends InputStream {
// ex45582-22397.xls has one extra byte after the last record
// Excel reads that file OK
}
- nextSid = INVALID_SID_VALUE;
+ nextSid = INVALID_SID_VALUE;
} else {
nextSid = LittleEndian.readShort(in);
if (nextSid == INVALID_SID_VALUE) {
throw new RecordFormatException("Found sid " + nextSid + " after record with sid 0x"
+ Integer.toHexString(currentSid).toUpperCase());
}
- }
+ }
} catch (IOException ex) {
throw new RecordFormatException("Error reading bytes", ex);
}
}
-
+
public void setAutoContinue(boolean enable) {
- this.autoContinue = enable;
+ this.autoContinue = enable;
}
-
+
public boolean getAutoContinue() {
return autoContinue;
}
-
- protected void checkRecordPosition() {
- if (remaining() <= 0) {
- if (isContinueNext() && autoContinue) {
- nextRecord();
- }
- else throw new ArrayIndexOutOfBoundsException();
- }
- }
-
- /**
- * Reads an 8 bit, signed value
- */
- public byte readByte() {
- checkRecordPosition();
-
- byte result = data[recordOffset];
- recordOffset += 1;
- pos += 1;
- return result;
- }
-
- /**
- * Reads a 16 bit, signed value
- */
- public short readShort() {
- checkRecordPosition();
-
- short result = LittleEndian.getShort(data, recordOffset);
- recordOffset += LittleEndian.SHORT_SIZE;
- pos += LittleEndian.SHORT_SIZE;
- return result;
- }
- public int readInt() {
- checkRecordPosition();
-
- int result = LittleEndian.getInt(data, recordOffset);
- recordOffset += LittleEndian.INT_SIZE;
- pos += LittleEndian.INT_SIZE;
- return result;
- }
+ private void checkRecordPosition(int requiredByteCount) {
- public long readLong() {
- checkRecordPosition();
-
- long result = LittleEndian.getLong(data, recordOffset);
- recordOffset += LittleEndian.LONG_SIZE;
- pos += LittleEndian.LONG_SIZE;
- return result;
- }
+ if (remaining() < requiredByteCount) {
+ if (isContinueNext() && autoContinue) {
+ nextRecord();
+ } else {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ }
+ }
+
+ /**
+ * Reads an 8 bit, signed value
+ */
+ public byte readByte() {
+ checkRecordPosition(LittleEndian.BYTE_SIZE);
+
+ byte result = data[recordOffset];
+ recordOffset += LittleEndian.BYTE_SIZE;
+ pos += LittleEndian.BYTE_SIZE;
+ return result;
+ }
+
+ /**
+ * Reads a 16 bit, signed value
+ */
+ public short readShort() {
+ checkRecordPosition(LittleEndian.SHORT_SIZE);
+
+ short result = LittleEndian.getShort(data, recordOffset);
+ recordOffset += LittleEndian.SHORT_SIZE;
+ pos += LittleEndian.SHORT_SIZE;
+ return result;
+ }
+
+ public int readInt() {
+ checkRecordPosition(LittleEndian.INT_SIZE);
+
+ int result = LittleEndian.getInt(data, recordOffset);
+ recordOffset += LittleEndian.INT_SIZE;
+ pos += LittleEndian.INT_SIZE;
+ return result;
+ }
+
+ public long readLong() {
+ checkRecordPosition(LittleEndian.LONG_SIZE);
+
+ long result = LittleEndian.getLong(data, recordOffset);
+ recordOffset += LittleEndian.LONG_SIZE;
+ pos += LittleEndian.LONG_SIZE;
+ return result;
+ }
+
+ /**
+ * Reads an 8 bit, unsigned value
+ */
+ public short readUByte() {
+ return (short) (readByte() & 0x00FF);
+ }
+
+ /**
+ * Reads a 16 bit, unsigned value.
+ * @return
+ */
+ public int readUShort() {
+ checkRecordPosition(LittleEndian.SHORT_SIZE);
+
+ int result = LittleEndian.getUShort(data, recordOffset);
+ recordOffset += LittleEndian.SHORT_SIZE;
+ pos += LittleEndian.SHORT_SIZE;
+ return result;
+ }
+
+ public double readDouble() {
+ checkRecordPosition(LittleEndian.DOUBLE_SIZE);
+ long valueLongBits = LittleEndian.getLong(data, recordOffset);
+ double result = Double.longBitsToDouble(valueLongBits);
+ if (Double.isNaN(result)) {
+ throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN
+ }
+ recordOffset += LittleEndian.DOUBLE_SIZE;
+ pos += LittleEndian.DOUBLE_SIZE;
+ return result;
+ }
/**
- * Reads an 8 bit, unsigned value
- */
- public short readUByte() {
- short s = readByte();
- if(s < 0) {
- s += 256;
- }
- return s;
- }
-
- /**
- * Reads a 16 bit,un- signed value.
- * @return
- */
- public int readUShort() {
- checkRecordPosition();
-
- int result = LittleEndian.getUShort(data, recordOffset);
- recordOffset += LittleEndian.SHORT_SIZE;
- pos += LittleEndian.SHORT_SIZE;
- return result;
- }
-
- public double readDouble() {
- checkRecordPosition();
- long valueLongBits = LittleEndian.getLong(data, recordOffset);
- double result = Double.longBitsToDouble(valueLongBits);
- if (Double.isNaN(result)) {
- throw new RuntimeException("Did not expect to read NaN");
- }
- recordOffset += LittleEndian.DOUBLE_SIZE;
- pos += LittleEndian.DOUBLE_SIZE;
- return result;
- }
-
-
- public short[] readShortArray() {
- checkRecordPosition();
-
- short[] arr = LittleEndian.getShortArray(data, recordOffset);
- final int size = (2 * (arr.length +1));
- recordOffset += size;
- pos += size;
-
- return arr;
- }
-
- /**
- * given a byte array of 16-bit unicode characters, compress to 8-bit and
- * return a string
- *
- * { 0x16, 0x00 } -0x16
- *
+ * given a byte array of 16-bit unicode characters, compress to 8-bit and
+ * return a string
+ *
+ * { 0x16, 0x00 } -0x16
+ *
* @param length 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)
- */
+ * there is not enough data in string to create a String of that
+ * length)
+ */
public String readUnicodeLEString(int length) {
if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
@@ -258,11 +243,11 @@ public class RecordInputStream extends InputStream {
if(compressByte != 1) throw new IllegalArgumentException("compressByte in continue records must be 1 while reading unicode LE string");
}
char ch = (char)readShort();
- buf.append(ch);
+ buf.append(ch);
}
return buf.toString();
}
-
+
public String readCompressedUnicode(int length) {
if ((length < 0) || ((remaining() < length) && !isContinueNext())) {
throw new IllegalArgumentException("Illegal length " + length);
@@ -277,23 +262,23 @@ public class RecordInputStream extends InputStream {
}
byte b = readByte();
char ch = (char)(0x00FF & b); // avoid sex
- buf.append(ch);
+ buf.append(ch);
}
- return buf.toString();
+ return buf.toString();
}
-
+
/** Returns an excel style unicode string from the bytes reminaing in the record.
* Note: Unicode strings differ from normal strings due to the addition of
* formatting information.
- *
+ *
* @return The unicode string representation of the remaining bytes.
*/
public UnicodeString readUnicodeString() {
return new UnicodeString(this);
}
-
+
/** Returns the remaining bytes for the current record.
- *
+ *
* @return The remaining bytes of the current record.
*/
public byte[] readRemainder() {
@@ -304,39 +289,39 @@ public class RecordInputStream extends InputStream {
pos += size;
return result;
}
-
+
/** Reads all byte data for the current record, including any
* that overlaps into any following continue records.
- *
+ *
* @deprecated Best to write a input stream that wraps this one where there is
* special sub record that may overlap continue records.
- */
+ */
public byte[] readAllContinuedRemainder() {
//Using a ByteArrayOutputStream is just an easy way to get a
//growable array of the data.
ByteArrayOutputStream out = new ByteArrayOutputStream(2*MAX_RECORD_DATA_SIZE);
while (isContinueNext()) {
- byte[] b = readRemainder();
+ byte[] b = readRemainder();
out.write(b, 0, b.length);
nextRecord();
}
- byte[] b = readRemainder();
- out.write(b, 0, b.length);
-
+ byte[] b = readRemainder();
+ out.write(b, 0, b.length);
+
return out.toByteArray();
}
/** The remaining number of bytes in the current record.
- *
+ *
* @return The number of bytes remaining in the current record
*/
public int remaining() {
return (currentLength - recordOffset);
}
- /** Returns true iif a Continue record is next in the excel stream
- *
+ /** Returns true iif a Continue record is next in the excel stream
+ *
* @return True when a ContinueRecord is next.
*/
public boolean isContinueNext() {
diff --git a/src/java/org/apache/poi/hssf/record/SeriesListRecord.java b/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
index 2894f15877..4753eae05f 100644
--- a/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
+++ b/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -15,66 +14,66 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-
package org.apache.poi.hssf.record;
-
-
-import org.apache.poi.util.*;
+import org.apache.poi.util.LittleEndian;
/**
- * The series list record defines the series displayed as an overlay to the main chart record.
- * NOTE: This source is automatically generated please do not modify this file. Either subclass or
- * remove the record in src/records/definitions.
-
+ *
+ * The series list record defines the series displayed as an overlay to the main chart record.
+ * TODO - does this record (0x1016) really exist. It doesn't seem to be referenced in either the OOO or MS doc
+ *
* @author Glen Stampoultzis (glens at apache.org)
*/
-public class SeriesListRecord
- extends Record
-{
- public final static short sid = 0x1016;
+public final class SeriesListRecord extends Record {
+ public final static short sid = 0x1016;
private short[] field_1_seriesNumbers;
-
- public SeriesListRecord()
- {
-
+ public SeriesListRecord(short[] seriesNumbers) {
+ field_1_seriesNumbers = seriesNumbers;
}
- public SeriesListRecord(RecordInputStream in)
- {
- field_1_seriesNumbers = in.readShortArray();
+ public SeriesListRecord(RecordInputStream in) {
+ int nItems = in.readUShort();
+ short[] ss = new short[nItems];
+ for (int i = 0; i < nItems; i++) {
+ ss[i] = in.readShort();
+
+ }
+ field_1_seriesNumbers = ss;
}
- public String toString()
- {
+ public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[SERIESLIST]\n");
- buffer.append(" .seriesNumbers = ")
- .append(" (").append( getSeriesNumbers() ).append(" )");
- buffer.append(System.getProperty("line.separator"));
+ buffer.append(" .seriesNumbers= ").append(" (").append( getSeriesNumbers() ).append(" )");
+ buffer.append("\n");
buffer.append("[/SERIESLIST]\n");
return buffer.toString();
}
- public int serialize(int offset, byte[] data)
- {
- int pos = 0;
+ public int serialize(int offset, byte[] data) {
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
+ int nItems = field_1_seriesNumbers.length;
+ int dataSize = 2 + 2 * nItems;
+
+ LittleEndian.putUShort(data, 0 + offset, sid);
+ LittleEndian.putUShort(data, 2 + offset, dataSize);
- LittleEndian.putShortArray(data, 4 + offset + pos, field_1_seriesNumbers);
+ LittleEndian.putUShort(data, 4 + offset, nItems);
+
+ int pos = offset + 6;
+ for (int i = 0; i < nItems; i++) {
+ LittleEndian.putUShort(data, pos, field_1_seriesNumbers[i]);
+ pos += 2;
+ }
- return getRecordSize();
+ return 4 + dataSize;
}
- /**
- * Size of record (exluding 4 byte header)
- */
public int getRecordSize()
{
return 4 + field_1_seriesNumbers.length * 2 + 2;
@@ -86,34 +85,23 @@ public class SeriesListRecord
}
public Object clone() {
- SeriesListRecord rec = new SeriesListRecord();
-
- rec.field_1_seriesNumbers = field_1_seriesNumbers;
- return rec;
+ return new SeriesListRecord((short[]) field_1_seriesNumbers.clone());
}
-
-
-
/**
* Get the series numbers field for the SeriesList record.
*/
- public short[] getSeriesNumbers()
- {
+ public short[] getSeriesNumbers() {
return field_1_seriesNumbers;
}
/**
* Set the series numbers field for the SeriesList record.
*/
- public void setSeriesNumbers(short[] field_1_seriesNumbers)
- {
+ public void setSeriesNumbers(short[] field_1_seriesNumbers) {
this.field_1_seriesNumbers = field_1_seriesNumbers;
}
-
-
-} // END OF CLASS
-
+}
diff --git a/src/java/org/apache/poi/util/LittleEndian.java b/src/java/org/apache/poi/util/LittleEndian.java
index 6838eb2aa4..373710b47a 100644
--- a/src/java/org/apache/poi/util/LittleEndian.java
+++ b/src/java/org/apache/poi/util/LittleEndian.java
@@ -250,20 +250,6 @@ public final class LittleEndian implements LittleEndianConsts {
putNumber(data, offset, value, LittleEndianConsts.BYTE_SIZE);
}
- /**
- * put a array of shorts into a byte array
- *
- *@param data the byte array
- *@param offset a starting offset into the byte array
- *@param value the short array
- */
- public static void putShortArray(final byte[] data, final int offset, final short[] value) {
- putNumber(data, offset, value.length, SHORT_SIZE);
- for (int i = 0; i < value.length; i++) {
- putNumber(data, offset + 2 + (i * 2), value[i], SHORT_SIZE);
- }
- }
-
/**
* put an unsigned short value into a byte array
*
diff --git a/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java
index 7e81f29280..027b6c3867 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestSeriesListRecord.java
@@ -29,7 +29,7 @@ import junit.framework.TestCase;
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestSeriesListRecord extends TestCase {
- byte[] data = new byte[] {
+ private static final byte[] data = {
(byte)0x02,(byte)0x00,(byte)0x01,(byte)0x20,(byte)0xff,(byte)0xf0
};
@@ -43,10 +43,8 @@ public final class TestSeriesListRecord extends TestCase {
assertEquals( 4 + 6, record.getRecordSize() );
}
- public void testStore()
- {
- SeriesListRecord record = new SeriesListRecord();
- record.setSeriesNumbers( new short[] { (short)0x2001, (short)0xf0ff } );
+ public void testStore() {
+ SeriesListRecord record = new SeriesListRecord(new short[] { (short)0x2001, (short)0xf0ff } );
byte [] recordBytes = record.serialize();
assertEquals(recordBytes.length - 4, data.length);