diff --git a/src/java/org/apache/poi/hssf/record/CRNRecord.java b/src/java/org/apache/poi/hssf/record/CRNRecord.java index 417f2a559..050076cca 100755 --- a/src/java/org/apache/poi/hssf/record/CRNRecord.java +++ b/src/java/org/apache/poi/hssf/record/CRNRecord.java @@ -18,17 +18,18 @@ package org.apache.poi.hssf.record; import org.apache.poi.hssf.record.constant.ConstantValueParser; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianOutput; /** - * Title: CRN
- * Description: This record stores the contents of an external cell or cell range
- * REFERENCE: 5.23
+ * Title: CRN(0x005A)
+ * Description: This record stores the contents of an external cell or cell range + * REFERENCE: OOO 5.23 * * @author josh micich */ public final class CRNRecord extends Record { - public final static short sid = 0x5A; + public final static short sid = 0x005A; private int field_1_last_column_index; private int field_2_first_column_index; @@ -45,8 +46,8 @@ public final class CRNRecord extends Record { public CRNRecord(RecordInputStream in) { - field_1_last_column_index = in.readByte() & 0x00FF; - field_2_first_column_index = in.readByte() & 0x00FF; + field_1_last_column_index = in.readUByte(); + field_2_first_column_index = in.readUByte(); field_3_row_index = in.readShort(); int nValues = field_1_last_column_index - field_2_first_column_index + 1; field_4_constant_values = ConstantValueParser.parse(in, nValues); @@ -68,13 +69,15 @@ public final class CRNRecord extends Record { public int serialize(int offset, byte [] data) { int dataSize = getDataSize(); - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, (short) dataSize); - LittleEndian.putByte(data, 4 + offset, field_1_last_column_index); - LittleEndian.putByte(data, 5 + offset, field_2_first_column_index); - LittleEndian.putShort(data, 6 + offset, (short) field_3_row_index); - ConstantValueParser.encode(data, 8 + offset, field_4_constant_values); - return getRecordSize(); + int recSize = 4 + dataSize; + LittleEndianOutput out = new LittleEndianByteArrayOutputStream(data, offset, recSize); + out.writeShort(sid); + out.writeShort(dataSize); + out.writeByte(field_1_last_column_index); + out.writeByte(field_2_first_column_index); + out.writeShort(field_3_row_index); + ConstantValueParser.encode(out, field_4_constant_values); + return recSize; } public int getRecordSize() { diff --git a/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java b/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java index 12f26bfde..8304eb0ee 100755 --- a/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java +++ b/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java @@ -17,10 +17,11 @@ package org.apache.poi.hssf.record.constant; -import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.UnicodeString; import org.apache.poi.hssf.record.UnicodeString.UnicodeRecordStats; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianInput; +import org.apache.poi.util.LittleEndianOutput; +import org.apache.poi.util.StringUtil; /** * To support Constant Values (2.5.7) as required by the CRN record. @@ -47,7 +48,7 @@ public final class ConstantValueParser { // no instances of this class } - public static Object[] parse(RecordInputStream in, int nValues) { + public static Object[] parse(LittleEndianInput in, int nValues) { Object[] result = new Object[nValues]; for (int i = 0; i < result.length; i++) { result[i] = readAConstantValue(in); @@ -55,7 +56,7 @@ public final class ConstantValueParser { return result; } - private static Object readAConstantValue(RecordInputStream in) { + private static Object readAConstantValue(LittleEndianInput in) { byte grbit = in.readByte(); switch(grbit) { case TYPE_EMPTY: @@ -64,7 +65,7 @@ public final class ConstantValueParser { case TYPE_NUMBER: return new Double(in.readDouble()); case TYPE_STRING: - return in.readUnicodeString(); + return new UnicodeString(StringUtil.readUnicodeString(in)); case TYPE_BOOLEAN: return readBoolean(in); case TYPE_ERROR_CODE: @@ -77,7 +78,7 @@ public final class ConstantValueParser { throw new RuntimeException("Unknown grbit value (" + grbit + ")"); } - private static Object readBoolean(RecordInputStream in) { + private static Object readBoolean(LittleEndianInput in) { byte val = (byte)in.readLong(); // 7 bytes 'not used' switch(val) { case FALSE_ENCODING: @@ -116,46 +117,43 @@ public final class ConstantValueParser { return urs.recordSize; } - public static void encode(byte[] data, int offset, Object[] values) { - int currentOffset = offset; + public static void encode(LittleEndianOutput out, Object[] values) { for (int i = 0; i < values.length; i++) { - currentOffset += encodeSingleValue(data, currentOffset, values[i]); + encodeSingleValue(out, values[i]); } } - private static int encodeSingleValue(byte[] data, int offset, Object value) { + private static void encodeSingleValue(LittleEndianOutput out, Object value) { if (value == EMPTY_REPRESENTATION) { - LittleEndian.putByte(data, offset, TYPE_EMPTY); - LittleEndian.putLong(data, offset+1, 0L); - return 9; + out.writeByte(TYPE_EMPTY); + out.writeLong(0L); + return; } if (value instanceof Boolean) { Boolean bVal = ((Boolean)value); - LittleEndian.putByte(data, offset, TYPE_BOOLEAN); + out.writeByte(TYPE_BOOLEAN); long longVal = bVal.booleanValue() ? 1L : 0L; - LittleEndian.putLong(data, offset+1, longVal); - return 9; + out.writeLong(longVal); + return; } if (value instanceof Double) { Double dVal = (Double) value; - LittleEndian.putByte(data, offset, TYPE_NUMBER); - LittleEndian.putDouble(data, offset+1, dVal.doubleValue()); - return 9; + out.writeByte(TYPE_NUMBER); + out.writeDouble(dVal.doubleValue()); + return; } if (value instanceof UnicodeString) { UnicodeString usVal = (UnicodeString) value; - LittleEndian.putByte(data, offset, TYPE_STRING); - UnicodeRecordStats urs = new UnicodeRecordStats(); - usVal.serialize(urs, offset +1, data); - return 1 + urs.recordSize; + out.writeByte(TYPE_STRING); + StringUtil.writeUnicodeString(out, usVal.getString()); + return; } if (value instanceof ErrorConstant) { ErrorConstant ecVal = (ErrorConstant) value; - LittleEndian.putByte(data, offset, TYPE_ERROR_CODE); - LittleEndian.putUShort(data, offset+1, ecVal.getErrorCode()); - LittleEndian.putUShort(data, offset+3, 0); - LittleEndian.putInt(data, offset+5, 0); - return 9; + out.writeByte(TYPE_ERROR_CODE); + long longVal = ecVal.getErrorCode(); + out.writeLong(longVal); + return; } throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'"); diff --git a/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java index 5bee0afe0..7802fcd13 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java +++ b/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java @@ -17,7 +17,7 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; /** @@ -30,7 +30,7 @@ public abstract class Area2DPtgBase extends AreaPtgBase { super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative); } - protected Area2DPtgBase(RecordInputStream in) { + protected Area2DPtgBase(LittleEndianInput in) { readCoordinates(in); } diff --git a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java index e5c2fdc10..675ee4555 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java @@ -17,10 +17,10 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.ss.formula.ExternSheetReferenceToken; import org.apache.poi.ss.formula.FormulaRenderingWorkbook; import org.apache.poi.ss.formula.WorkbookDependentFormula; +import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; /** @@ -44,7 +44,7 @@ public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFor setExternSheetIndex( externIdx ); } - public Area3DPtg(RecordInputStream in) { + public Area3DPtg(LittleEndianInput in) { field_1_index_extern_sheet = in.readShort(); readCoordinates(in); } diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java index f50af0d0c..dfbfb7ab3 100644 --- a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java @@ -17,8 +17,8 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.usermodel.HSSFErrorConstants; +import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; /** @@ -36,7 +36,7 @@ public final class AreaErrPtg extends OperandPtg { unused2 = 0; } - public AreaErrPtg(RecordInputStream in) { + public AreaErrPtg(LittleEndianInput in) { // 8 bytes unused: unused1 = in.readInt(); unused2 = in.readInt(); diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java index fc391b801..f8b761f31 100644 --- a/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java @@ -17,7 +17,7 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.util.LittleEndianInput; /** * Specifies a rectangular area of cells A1:A4 for instance. @@ -26,7 +26,7 @@ import org.apache.poi.hssf.record.RecordInputStream; public final class AreaNPtg extends Area2DPtgBase { public final static short sid = 0x2D; - public AreaNPtg(RecordInputStream in) { + public AreaNPtg(LittleEndianInput in) { super(in); } diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java index 77e9fa0b5..1da9b784c 100755 --- a/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java @@ -17,7 +17,7 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; +import org.apache.poi.util.LittleEndianInput; /** * Specifies a rectangular area of cells A1:A4 for instance. @@ -29,7 +29,7 @@ public final class AreaPtg extends Area2DPtgBase { public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) { super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative); } - public AreaPtg(RecordInputStream in) { + public AreaPtg(LittleEndianInput in) { super(in); } public AreaPtg(String arearef) { diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java b/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java index 2fa1290c0..8e338c587 100644 --- a/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java +++ b/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java @@ -17,11 +17,11 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.util.AreaReference; import org.apache.poi.hssf.util.CellReference; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; +import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; /** @@ -113,7 +113,7 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI { } } - protected final void readCoordinates(RecordInputStream in) { + protected final void readCoordinates(LittleEndianInput in) { field_1_first_row = in.readUShort(); field_2_last_row = in.readUShort(); field_3_first_column = in.readUShort(); diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java index 21df3982a..3fcc23eda 100644 --- a/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java @@ -17,11 +17,10 @@ package org.apache.poi.hssf.record.formula; -import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.UnicodeString; import org.apache.poi.hssf.record.constant.ConstantValueParser; import org.apache.poi.hssf.record.constant.ErrorConstant; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; /** @@ -55,7 +54,7 @@ public final class ArrayPtg extends Ptg { private short token_2_rows; private Object[] token_3_arrayValues; - public ArrayPtg(RecordInputStream in) { + public ArrayPtg(LittleEndianInput in) { field_1_reserved = new byte[RESERVED_FIELD_LEN]; // TODO - add readFully method to RecordInputStream for(int i=0; i< RESERVED_FIELD_LEN; i++) { @@ -109,7 +108,7 @@ public final class ArrayPtg extends Ptg { * AFTER the last Ptg in the expression. * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf */ - public void readTokenValues(RecordInputStream in) { + public void readTokenValues(LittleEndianInput in) { int nColumns = in.readUByte(); short nRows = in.readShort(); //The token_1_columns and token_2_rows do not follow the documentation. @@ -133,7 +132,7 @@ public final class ArrayPtg extends Ptg { if (token_3_arrayValues == null) { sb.append(" #values#uninitialised#\n"); } else { - sb.append(" ").append(formatAsString()); + sb.append(" ").append(toFormulaString()); } return sb.toString(); } @@ -159,11 +158,11 @@ public final class ArrayPtg extends Ptg { out.write(field_1_reserved); } - public int writeTokenValueBytes(byte[] data, int offset) { + public int writeTokenValueBytes(LittleEndianOutput out) { - LittleEndian.putByte(data, offset + 0, token_1_columns-1); - LittleEndian.putUShort(data, offset + 1, token_2_rows-1); - ConstantValueParser.encode(data, offset + 3, token_3_arrayValues); + out.writeByte(token_1_columns-1); + out.writeShort(token_2_rows-1); + ConstantValueParser.encode(out, token_3_arrayValues); return 3 + ConstantValueParser.getEncodedSize(token_3_arrayValues); } @@ -183,7 +182,7 @@ public final class ArrayPtg extends Ptg { + ConstantValueParser.getEncodedSize(token_3_arrayValues); } - public String formatAsString() { // TODO - fold into toFormulaString + public String toFormulaString() { StringBuffer b = new StringBuffer(); b.append("{"); for (int y=0;y