Better bounds checking in RecordInputStream. Removed rarely used methods readShortArray and putShortArray
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@701747 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4bf266b1c7
commit
9897317e8e
@ -45,26 +45,26 @@ public class RecordInputStream extends InputStream {
|
||||
|
||||
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
|
||||
//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();
|
||||
/** This method will read a byte from the current record*/
|
||||
public int read() {
|
||||
checkRecordPosition(LittleEndian.BYTE_SIZE);
|
||||
|
||||
byte result = data[recordOffset];
|
||||
recordOffset += 1;
|
||||
pos += 1;
|
||||
return result;
|
||||
}
|
||||
byte result = data[recordOffset];
|
||||
recordOffset += LittleEndian.BYTE_SIZE;
|
||||
pos += LittleEndian.BYTE_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return currentSid;
|
||||
@ -90,7 +90,6 @@ public class RecordInputStream extends InputStream {
|
||||
*
|
||||
* <i>Note: The auto continue flag is reset to true</i>
|
||||
*/
|
||||
|
||||
public void nextRecord() throws RecordFormatException {
|
||||
if ((currentLength != -1) && (currentLength != recordOffset)) {
|
||||
System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(currentSid));
|
||||
@ -134,104 +133,90 @@ public class RecordInputStream extends InputStream {
|
||||
return autoContinue;
|
||||
}
|
||||
|
||||
protected void checkRecordPosition() {
|
||||
if (remaining() <= 0) {
|
||||
if (isContinueNext() && autoContinue) {
|
||||
nextRecord();
|
||||
}
|
||||
else throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
private void checkRecordPosition(int requiredByteCount) {
|
||||
|
||||
/**
|
||||
* Reads an 8 bit, signed value
|
||||
*/
|
||||
public byte readByte() {
|
||||
checkRecordPosition();
|
||||
if (remaining() < requiredByteCount) {
|
||||
if (isContinueNext() && autoContinue) {
|
||||
nextRecord();
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte result = data[recordOffset];
|
||||
recordOffset += 1;
|
||||
pos += 1;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Reads an 8 bit, signed value
|
||||
*/
|
||||
public byte readByte() {
|
||||
checkRecordPosition(LittleEndian.BYTE_SIZE);
|
||||
|
||||
/**
|
||||
* Reads a 16 bit, signed value
|
||||
*/
|
||||
public short readShort() {
|
||||
checkRecordPosition();
|
||||
byte result = data[recordOffset];
|
||||
recordOffset += LittleEndian.BYTE_SIZE;
|
||||
pos += LittleEndian.BYTE_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
short result = LittleEndian.getShort(data, recordOffset);
|
||||
recordOffset += LittleEndian.SHORT_SIZE;
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Reads a 16 bit, signed value
|
||||
*/
|
||||
public short readShort() {
|
||||
checkRecordPosition(LittleEndian.SHORT_SIZE);
|
||||
|
||||
public int readInt() {
|
||||
checkRecordPosition();
|
||||
short result = LittleEndian.getShort(data, recordOffset);
|
||||
recordOffset += LittleEndian.SHORT_SIZE;
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
int result = LittleEndian.getInt(data, recordOffset);
|
||||
recordOffset += LittleEndian.INT_SIZE;
|
||||
pos += LittleEndian.INT_SIZE;
|
||||
return result;
|
||||
}
|
||||
public int readInt() {
|
||||
checkRecordPosition(LittleEndian.INT_SIZE);
|
||||
|
||||
public long readLong() {
|
||||
checkRecordPosition();
|
||||
int result = LittleEndian.getInt(data, recordOffset);
|
||||
recordOffset += LittleEndian.INT_SIZE;
|
||||
pos += LittleEndian.INT_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
long result = LittleEndian.getLong(data, recordOffset);
|
||||
recordOffset += LittleEndian.LONG_SIZE;
|
||||
pos += LittleEndian.LONG_SIZE;
|
||||
return result;
|
||||
}
|
||||
public long readLong() {
|
||||
checkRecordPosition(LittleEndian.LONG_SIZE);
|
||||
|
||||
/**
|
||||
* Reads an 8 bit, unsigned value
|
||||
*/
|
||||
public short readUByte() {
|
||||
short s = readByte();
|
||||
if(s < 0) {
|
||||
s += 256;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
long result = LittleEndian.getLong(data, recordOffset);
|
||||
recordOffset += LittleEndian.LONG_SIZE;
|
||||
pos += LittleEndian.LONG_SIZE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 16 bit,un- signed value.
|
||||
* @return
|
||||
*/
|
||||
public int readUShort() {
|
||||
checkRecordPosition();
|
||||
/**
|
||||
* Reads an 8 bit, unsigned value
|
||||
*/
|
||||
public short readUByte() {
|
||||
return (short) (readByte() & 0x00FF);
|
||||
}
|
||||
|
||||
int result = LittleEndian.getUShort(data, recordOffset);
|
||||
recordOffset += LittleEndian.SHORT_SIZE;
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Reads a 16 bit, unsigned value.
|
||||
* @return
|
||||
*/
|
||||
public int readUShort() {
|
||||
checkRecordPosition(LittleEndian.SHORT_SIZE);
|
||||
|
||||
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;
|
||||
}
|
||||
int result = LittleEndian.getUShort(data, recordOffset);
|
||||
recordOffset += LittleEndian.SHORT_SIZE;
|
||||
pos += LittleEndian.SHORT_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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* given a byte array of 16-bit unicode characters, compress to 8-bit and
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -16,65 +15,65 @@
|
||||
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.<br/>
|
||||
* 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.putShortArray(data, 4 + offset + pos, field_1_seriesNumbers);
|
||||
LittleEndian.putUShort(data, 0 + offset, sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
|
||||
return getRecordSize();
|
||||
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 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
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user