diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index 222f0a6ab..84ebf9962 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -95,7 +95,7 @@ public final class Workbook implements Model { protected int numxfs = 0; // hold the number of extended format records protected int numfonts = 0; // hold the number of font records - private short maxformatid = -1; // holds the max format id + private int maxformatid = -1; // holds the max format id private boolean uses1904datewindowing = false; // whether 1904 date windowing is being used private DrawingManager2 drawingManager; private List escherBSERecords = new ArrayList(); // EscherBSERecord @@ -1106,15 +1106,8 @@ public final class Workbook implements Model { * @see org.apache.poi.hssf.record.Record * @return record containing a TabIdRecord */ - - protected Record createTabId() { - TabIdRecord retval = new TabIdRecord(); - short[] tabidarray = { - 0 - }; - - retval.setTabIdArray(tabidarray); - return retval; + private static TabIdRecord createTabId() { + return new TabIdRecord(); } /** @@ -1334,7 +1327,6 @@ public final class Workbook implements Model { * @see org.apache.poi.hssf.record.Record * @return record containing a FontRecord */ - protected Record createFont() { FontRecord retval = new FontRecord(); @@ -1342,7 +1334,6 @@ public final class Workbook implements Model { retval.setAttributes(( short ) 0x0); retval.setColorPaletteIndex(( short ) 0x7fff); retval.setBoldWeight(( short ) 0x190); - retval.setFontNameLength(( byte ) 5); retval.setFontName("Arial"); return retval; } @@ -1355,66 +1346,21 @@ public final class Workbook implements Model { * @see org.apache.poi.hssf.record.FormatRecord * @see org.apache.poi.hssf.record.Record */ - - protected Record createFormat(int id) { // we'll need multiple editions for - FormatRecord retval = new FormatRecord(); // the differnt formats + private static FormatRecord createFormat(int id) { + // we'll need multiple editions for + // the different formats switch (id) { - - case 0 : - retval.setIndexCode(( short ) 5); - retval.setFormatStringLength(( byte ) 0x17); - retval.setFormatString("\"$\"#,##0_);\\(\"$\"#,##0\\)"); - break; - - case 1 : - retval.setIndexCode(( short ) 6); - retval.setFormatStringLength(( byte ) 0x1c); - retval.setFormatString("\"$\"#,##0_);[Red]\\(\"$\"#,##0\\)"); - break; - - case 2 : - retval.setIndexCode(( short ) 7); - retval.setFormatStringLength(( byte ) 0x1d); - retval.setFormatString("\"$\"#,##0.00_);\\(\"$\"#,##0.00\\)"); - break; - - case 3 : - retval.setIndexCode(( short ) 8); - retval.setFormatStringLength(( byte ) 0x22); - retval.setFormatString( - "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)"); - break; - - case 4 : - retval.setIndexCode(( short ) 0x2a); - retval.setFormatStringLength(( byte ) 0x32); - retval.setFormatString( - "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)"); - break; - - case 5 : - retval.setIndexCode(( short ) 0x29); - retval.setFormatStringLength(( byte ) 0x29); - retval.setFormatString( - "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)"); - break; - - case 6 : - retval.setIndexCode(( short ) 0x2c); - retval.setFormatStringLength(( byte ) 0x3a); - retval.setFormatString( - "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)"); - break; - - case 7 : - retval.setIndexCode(( short ) 0x2b); - retval.setFormatStringLength(( byte ) 0x31); - retval.setFormatString( - "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)"); - break; + case 0: return new FormatRecord(5, "\"$\"#,##0_);\\(\"$\"#,##0\\)"); + case 1: return new FormatRecord(6, "\"$\"#,##0_);[Red]\\(\"$\"#,##0\\)"); + case 2: return new FormatRecord(7, "\"$\"#,##0.00_);\\(\"$\"#,##0.00\\)"); + case 3: return new FormatRecord(8, "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)"); + case 4: return new FormatRecord(0x2a, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)"); + case 5: return new FormatRecord(0x29, "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)"); + case 6: return new FormatRecord(0x2c, "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)"); + case 7: return new FormatRecord(0x2b, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)"); } - return retval; + throw new IllegalArgumentException("Unexpected id " + id); } /** @@ -2061,12 +2007,12 @@ public final class Workbook implements Model { for (iterator = formats.iterator(); iterator.hasNext();) { FormatRecord r = (FormatRecord)iterator.next(); if (r.getFormatString().equals(format)) { - return r.getIndexCode(); + return (short)r.getIndexCode(); } } if (createIfNotFound) { - return createFormat(format); + return (short)createFormat(format); } return -1; @@ -2082,21 +2028,15 @@ public final class Workbook implements Model { /** * Creates a FormatRecord, inserts it, and returns the index code. - * @param format the format string + * @param formatString the format string * @return the index code of the format record. * @see org.apache.poi.hssf.record.FormatRecord * @see org.apache.poi.hssf.record.Record */ - public short createFormat( String format ) - { -// ++xfpos; //These are to ensure that positions are updated properly -// ++palettepos; -// ++bspos; - FormatRecord rec = new FormatRecord(); - maxformatid = maxformatid >= (short) 0xa4 ? (short) ( maxformatid + 1 ) : (short) 0xa4; //Starting value from M$ empiracle study. - rec.setIndexCode( maxformatid ); - rec.setFormatStringLength( (byte) format.length() ); - rec.setFormatString( format ); + public int createFormat(String formatString) { + + maxformatid = maxformatid >= 0xa4 ? maxformatid + 1 : 0xa4; //Starting value from M$ empircal study. + FormatRecord rec = new FormatRecord(maxformatid, formatString); int pos = 0; while ( pos < records.size() && records.get( pos ).getSid() != FormatRecord.sid ) diff --git a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java index 17d337f82..391a3a08b 100644 --- a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java +++ b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java @@ -24,20 +24,19 @@ import java.util.List; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.HexDump; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianOutput; import org.apache.poi.util.StringUtil; /** - * Title: Bound Sheet Record (aka BundleSheet)
- * Description: Defines a sheet within a workbook. Basically stores the sheetname + * Title: Bound Sheet Record (aka BundleSheet) (0x0085)
+ * Description: Defines a sheet within a workbook. Basically stores the sheet name * and tells where the Beginning of file record is within the HSSF * file.
* REFERENCE: PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Sergei Kozello (sergeikozello at mail.ru)
- * @version 2.0-pre
*/
-public final class BoundSheetRecord extends Record {
+public final class BoundSheetRecord extends StandardRecord {
public final static short sid = 0x0085;
private static final BitField hiddenFlag = BitFieldFactory.getInstance(0x01);
@@ -160,23 +159,19 @@ public final class BoundSheetRecord extends Record {
return 8 + field_5_sheetname.length() * (isMultibyte() ? 2 : 1);
}
- public int serialize(int offset, byte[] data) {
- int dataSize = getDataSize();
- LittleEndian.putUShort(data, 0 + offset, sid);
- LittleEndian.putUShort(data, 2 + offset, dataSize);
- LittleEndian.putInt(data, 4 + offset, getPositionOfBof());
- LittleEndian.putUShort(data, 8 + offset, field_2_option_flags);
+ public void serialize(LittleEndianOutput out) {
+ out.writeInt(getPositionOfBof());
+ out.writeShort(field_2_option_flags);
String name = field_5_sheetname;
- LittleEndian.putByte(data, 10 + offset, name.length());
- LittleEndian.putByte(data, 11 + offset, field_4_isMultibyteUnicode);
+ out.writeByte(name.length());
+ out.writeByte(field_4_isMultibyteUnicode);
if (isMultibyte()) {
- StringUtil.putUnicodeLE(name, data, 12 + offset);
+ StringUtil.putUnicodeLE(name, out);
} else {
- StringUtil.putCompressedUnicode(name, data, 12 + offset);
+ StringUtil.putCompressedUnicode(name, out);
}
- return 4 + dataSize;
}
public short getSid() {
@@ -215,16 +210,14 @@ public final class BoundSheetRecord extends Record {
* Converts a List of {@link BoundSheetRecord}s to an array and sorts by the position of their
* BOFs.
*/
- public static BoundSheetRecord[] orderByBofPosition(List boundSheetRecords) {
+ public static BoundSheetRecord[] orderByBofPosition(List
* REFERENCE: PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height
- * @version 2.0-pre
*/
-public final class DBCellRecord extends Record {
+public final class DBCellRecord extends StandardRecord {
+ public final static short sid = 0x00D7;
public final static int BLOCK_SIZE = 32;
- public final static short sid = 0xd7;
- private int field_1_row_offset;
- private short[] field_2_cell_offsets;
+
+ public static final class Builder {
+ private short[] _cellOffsets;
+ private int _nCellOffsets;
+ public Builder() {
+ _cellOffsets = new short[4];
+ }
- public DBCellRecord()
- {
- field_2_cell_offsets = new short[0];
+ public void addCellOffset(int cellRefOffset) {
+ if (_cellOffsets.length <= _nCellOffsets) {
+ short[] temp = new short[_nCellOffsets * 2];
+ System.arraycopy(_cellOffsets, 0, temp, 0, _nCellOffsets);
+ _cellOffsets = temp;
+ }
+ _cellOffsets[_nCellOffsets] = (short) cellRefOffset;
+ _nCellOffsets++;
+ }
+
+ public DBCellRecord build(int rowOffset) {
+ short[] cellOffsets = new short[_nCellOffsets];
+ System.arraycopy(_cellOffsets, 0, cellOffsets, 0, _nCellOffsets);
+ return new DBCellRecord(rowOffset, cellOffsets);
+ }
+ }
+ /**
+ * offset from the start of this DBCellRecord to the start of the first cell in
+ * the next DBCell block.
+ */
+ private final int field_1_row_offset;
+ private final short[] field_2_cell_offsets;
+
+ DBCellRecord(int rowOffset, short[]cellOffsets) {
+ field_1_row_offset = rowOffset;
+ field_2_cell_offsets = cellOffsets;
}
- public DBCellRecord(RecordInputStream in)
- {
+ public DBCellRecord(RecordInputStream in) {
field_1_row_offset = in.readUShort();
int size = in.remaining();
field_2_cell_offsets = new short[ size / 2 ];
@@ -50,101 +77,28 @@ public final class DBCellRecord extends Record {
}
}
- /**
- * sets offset from the start of this DBCellRecord to the start of the first cell in
- * the next DBCell block.
- *
- * @param offset offset to the start of the first cell in the next DBCell block
- */
- public void setRowOffset(int offset)
- {
- field_1_row_offset = offset;
- }
- // need short list impl.
- public void addCellOffset(short offset)
- {
- if (field_2_cell_offsets == null)
- {
- field_2_cell_offsets = new short[ 1 ];
- }
- else
- {
- short[] temp = new short[ field_2_cell_offsets.length + 1 ];
-
- System.arraycopy(field_2_cell_offsets, 0, temp, 0,
- field_2_cell_offsets.length);
- field_2_cell_offsets = temp;
- }
- field_2_cell_offsets[ field_2_cell_offsets.length - 1 ] = offset;
- }
-
- /**
- * gets offset from the start of this DBCellRecord to the start of the first cell in
- * the next DBCell block.
- *
- * @return rowoffset to the start of the first cell in the next DBCell block
- */
- public int getRowOffset()
- {
- return field_1_row_offset;
- }
-
- /**
- * return the cell offset in the array
- *
- * @param index of the cell offset to retrieve
- * @return celloffset from the celloffset array
- */
- public short getCellOffsetAt(int index)
- {
- return field_2_cell_offsets[ index ];
- }
-
- /**
- * get the number of cell offsets in the celloffset array
- *
- * @return number of cell offsets
- */
- public int getNumCellOffsets()
- {
- return field_2_cell_offsets.length;
- }
-
- public String toString()
- {
+ public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[DBCELL]\n");
- buffer.append(" .rowoffset = ")
- .append(Integer.toHexString(getRowOffset())).append("\n");
- for (int k = 0; k < getNumCellOffsets(); k++)
- {
- buffer.append(" .cell_" + k + " = ")
- .append(Integer.toHexString(getCellOffsetAt(k))).append("\n");
+ buffer.append(" .rowoffset = ").append(HexDump.intToHex(field_1_row_offset)).append("\n");
+ for (int k = 0; k < field_2_cell_offsets.length; k++) {
+ buffer.append(" .cell_").append(k).append(" = ")
+ .append(HexDump.shortToHex(field_2_cell_offsets[ k ])).append("\n");
}
buffer.append("[/DBCELL]\n");
return buffer.toString();
}
- public int serialize(int offset, byte [] data)
- {
- if (field_2_cell_offsets == null)
- {
- field_2_cell_offsets = new short[ 0 ];
+ public void serialize(LittleEndianOutput out) {
+ out.writeInt(field_1_row_offset);
+ for (int k = 0; k < field_2_cell_offsets.length; k++) {
+ out.writeShort(field_2_cell_offsets[ k ]);
}
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset,
- (( short ) (4 + (getNumCellOffsets() * 2))));
- LittleEndian.putInt(data, 4 + offset, getRowOffset());
- for (int k = 0; k < getNumCellOffsets(); k++)
- {
- LittleEndian.putShort(data, 8 + 2*k + offset, getCellOffsetAt(k));
- }
- return getRecordSize();
}
protected int getDataSize() {
- return 4 + (getNumCellOffsets() * 2);
+ return 4 + field_2_cell_offsets.length * 2;
}
/**
@@ -158,14 +112,12 @@ public final class DBCellRecord extends Record {
return nBlocks * 8 + nRows * 2;
}
- public short getSid()
- {
+ public short getSid() {
return sid;
}
public Object clone() {
- // TODO - make immutable.
- // this should be safe because only the instantiating code mutates these objects
+ // safe because immutable
return this;
}
}
diff --git a/src/java/org/apache/poi/hssf/record/DVALRecord.java b/src/java/org/apache/poi/hssf/record/DVALRecord.java
index 69e94deac..0bd4600b6 100644
--- a/src/java/org/apache/poi/hssf/record/DVALRecord.java
+++ b/src/java/org/apache/poi/hssf/record/DVALRecord.java
@@ -16,16 +16,15 @@
package org.apache.poi.hssf.record;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: DATAVALIDATIONS Record
+ * Title: DATAVALIDATIONS Record (0x01B2)
- * contains the elements of "info" in the SST's array field
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
- * @see org.apache.poi.hssf.record.ExtSSTRecord
- */
-
-public class ExtSSTInfoSubRecord
- extends Record
-{
- public static final int INFO_SIZE = 8;
- public final static short sid =
- 0xFFF; // only here for conformance, doesn't really have an sid
- private int field_1_stream_pos; // stream pointer to the SST record
- private short field_2_bucket_sst_offset; // don't really understand this yet.
- private short field_3_zero; // must be 0;
-
- /** Creates new ExtSSTInfoSubRecord */
-
- public ExtSSTInfoSubRecord()
- {
- }
-
- public ExtSSTInfoSubRecord(RecordInputStream in)
- {
- field_1_stream_pos = in.readInt();
- field_2_bucket_sst_offset = in.readShort();
- field_3_zero = in.readShort();
- }
-
- public void setStreamPos(int pos)
- {
- field_1_stream_pos = pos;
- }
-
- public void setBucketRecordOffset(short offset)
- {
- field_2_bucket_sst_offset = offset;
- }
-
- public int getStreamPos()
- {
- return field_1_stream_pos;
- }
-
- public short getBucketSSTOffset()
- {
- return field_2_bucket_sst_offset;
- }
-
- public String toString()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("[EXTSST]\n");
- buffer.append(" .streampos = ")
- .append(Integer.toHexString(getStreamPos())).append("\n");
- buffer.append(" .bucketsstoffset= ")
- .append(Integer.toHexString(getBucketSSTOffset())).append("\n");
- buffer.append(" .zero = ")
- .append(Integer.toHexString(field_3_zero)).append("\n");
- buffer.append("[/EXTSST]\n");
- return buffer.toString();
- }
-
- public int serialize(int offset, byte [] data)
- {
- LittleEndian.putInt(data, 0 + offset, getStreamPos());
- LittleEndian.putShort(data, 4 + offset, getBucketSSTOffset());
- LittleEndian.putShort(data, 6 + offset, ( short ) 0);
- return getRecordSize();
- }
-
- protected int getDataSize() {
- return 4;
- }
-
- public short getSid()
- {
- return sid;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java b/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java
index 8225f6b76..f5fe5df32 100644
--- a/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java
@@ -17,13 +17,10 @@
package org.apache.poi.hssf.record;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: Extended Static String Table
+ * Title: Extended Static String Table (0x00FF)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height (jheight at apache dot org)
- * @version 2.0-pre
+ *
* @see org.apache.poi.hssf.record.ExtSSTInfoSubRecord
*/
-public final class ExtSSTRecord extends Record {
+public final class ExtSSTRecord extends StandardRecord {
public final static short sid = 0x00FF;
public static final int DEFAULT_BUCKET_SIZE = 8;
//Can't seem to find this documented but from the biffviewer it is clear that
//Excel only records the indexes for the first 128 buckets.
public static final int MAX_BUCKETS = 128;
- private short field_1_strings_per_bucket = DEFAULT_BUCKET_SIZE;
- private List field_2_sst_info;
+
+
+ private static final class InfoSubRecord {
+ public static final int ENCODED_SIZE = 8;
+ private int field_1_stream_pos; // stream pointer to the SST record
+ private int field_2_bucket_sst_offset; // don't really understand this yet.
+ /** unused - supposed to be zero */
+ private short field_3_zero;
+
+ /** Creates new ExtSSTInfoSubRecord */
+
+ public InfoSubRecord(int streamPos, int bucketSstOffset) {
+ field_1_stream_pos = streamPos;
+ field_2_bucket_sst_offset = bucketSstOffset;
+ }
+
+ public InfoSubRecord(RecordInputStream in)
+ {
+ field_1_stream_pos = in.readInt();
+ field_2_bucket_sst_offset = in.readShort();
+ field_3_zero = in.readShort();
+ }
+
+ public int getStreamPos() {
+ return field_1_stream_pos;
+ }
+
+ public int getBucketSSTOffset() {
+ return field_2_bucket_sst_offset;
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeInt(field_1_stream_pos);
+ out.writeShort(field_2_bucket_sst_offset);
+ out.writeShort(field_3_zero);
+ }
+ }
+
+
+ private short _stringsPerBucket;
+ private InfoSubRecord[] _sstInfos;
- public ExtSSTRecord()
- {
- field_2_sst_info = new ArrayList();
+ public ExtSSTRecord() {
+ _stringsPerBucket = DEFAULT_BUCKET_SIZE;
+ _sstInfos = new InfoSubRecord[0];
}
- public ExtSSTRecord(RecordInputStream in)
- {
- field_2_sst_info = new ArrayList();
- field_1_strings_per_bucket = in.readShort();
- while (in.remaining() > 0) {
- ExtSSTInfoSubRecord rec = new ExtSSTInfoSubRecord(in);
-
- field_2_sst_info.add(rec);
+ public ExtSSTRecord(RecordInputStream in) {
+ _stringsPerBucket = in.readShort();
+ int nInfos = in.remaining() / InfoSubRecord.ENCODED_SIZE;
+ _sstInfos = new InfoSubRecord[nInfos];
+ for (int i = 0; i < _sstInfos.length; i++) {
+ _sstInfos[i] = new InfoSubRecord(in);
}
}
- public void setNumStringsPerBucket(short numStrings)
- {
- field_1_strings_per_bucket = numStrings;
+ public void setNumStringsPerBucket(short numStrings) {
+ _stringsPerBucket = numStrings;
}
- public void addInfoRecord(ExtSSTInfoSubRecord rec)
- {
- field_2_sst_info.add(rec);
- }
-
- public short getNumStringsPerBucket()
- {
- return field_1_strings_per_bucket;
- }
-
- public int getNumInfoRecords()
- {
- return field_2_sst_info.size();
- }
-
- public ExtSSTInfoSubRecord getInfoRecordAt(int elem)
- {
- return ( ExtSSTInfoSubRecord ) field_2_sst_info.get(elem);
- }
-
- public String toString()
- {
+ public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[EXTSST]\n");
buffer.append(" .dsst = ")
- .append(Integer.toHexString(getNumStringsPerBucket()))
+ .append(Integer.toHexString(_stringsPerBucket))
.append("\n");
- buffer.append(" .numInfoRecords = ").append(getNumInfoRecords())
+ buffer.append(" .numInfoRecords = ").append(_sstInfos.length)
.append("\n");
- for (int k = 0; k < getNumInfoRecords(); k++)
+ for (int k = 0; k < _sstInfos.length; k++)
{
buffer.append(" .inforecord = ").append(k).append("\n");
buffer.append(" .streampos = ")
.append(Integer
- .toHexString(getInfoRecordAt(k).getStreamPos())).append("\n");
+ .toHexString(_sstInfos[k].getStreamPos())).append("\n");
buffer.append(" .sstoffset = ")
.append(Integer
- .toHexString(getInfoRecordAt(k).getBucketSSTOffset()))
+ .toHexString(_sstInfos[k].getBucketSSTOffset()))
.append("\n");
}
buffer.append("[/EXTSST]\n");
return buffer.toString();
}
- public int serialize(int offset, byte [] data)
- {
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
- LittleEndian.putShort(data, 4 + offset, field_1_strings_per_bucket);
- int pos = 6;
-
- for (int k = 0; k < getNumInfoRecords(); k++)
- {
- ExtSSTInfoSubRecord rec = getInfoRecordAt(k);
- pos += rec.serialize(pos + offset, data);
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(_stringsPerBucket);
+ for (int k = 0; k < _sstInfos.length; k++) {
+ _sstInfos[k].serialize(out);
}
- return pos;
}
protected int getDataSize() {
- return 2 + 8*getNumInfoRecords();
+ return 2 + InfoSubRecord.ENCODED_SIZE*_sstInfos.length;
}
public static final int getNumberOfInfoRecsForStrings(int numStrings) {
@@ -133,7 +137,7 @@ public final class ExtSSTRecord extends Record {
if ((numStrings % DEFAULT_BUCKET_SIZE) != 0)
infoRecs ++;
//Excel seems to max out after 128 info records.
- //This isnt really documented anywhere...
+ //This isn't really documented anywhere...
if (infoRecs > MAX_BUCKETS)
infoRecs = MAX_BUCKETS;
return infoRecs;
@@ -141,24 +145,18 @@ public final class ExtSSTRecord extends Record {
/** Given a number of strings (in the sst), returns the size of the extsst record*/
public static final int getRecordSizeForStrings(int numStrings) {
- return 4 + 2 + (getNumberOfInfoRecsForStrings(numStrings) * 8);
+ return 4 + 2 + getNumberOfInfoRecsForStrings(numStrings) * 8;
}
- public short getSid()
- {
+ public short getSid() {
return sid;
}
- public void setBucketOffsets( int[] bucketAbsoluteOffsets, int[] bucketRelativeOffsets )
- {
- this.field_2_sst_info = new ArrayList(bucketAbsoluteOffsets.length);
- for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )
- {
- ExtSSTInfoSubRecord r = new ExtSSTInfoSubRecord();
- r.setBucketRecordOffset((short)bucketRelativeOffsets[i]);
- r.setStreamPos(bucketAbsoluteOffsets[i]);
- field_2_sst_info.add(r);
+ public void setBucketOffsets(int[] bucketAbsoluteOffsets, int[] bucketRelativeOffsets) {
+ // TODO - replace no-arg constructor with this logic
+ _sstInfos = new InfoSubRecord[bucketAbsoluteOffsets.length];
+ for (int i = 0; i < bucketAbsoluteOffsets.length; i++) {
+ _sstInfos[i] = new InfoSubRecord(bucketAbsoluteOffsets[i], bucketRelativeOffsets[i]);
}
}
-
}
diff --git a/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java b/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
index cbb287ed1..af6b9731a 100644
--- a/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
@@ -20,7 +20,7 @@ package org.apache.poi.hssf.record;
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
* EXTERNSHEET (0x0017)
+ * Title: FILESHARING (0x005B)
+ * Title: Font Record (0x0031)
* Description: An element in the Font Table
* REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
* @author Andrew C. Oliver (acoliver at apache dot org)
*/
-public final class FontRecord extends Record {
+public final class FontRecord extends StandardRecord {
public final static short sid = 0x0031; // docs are wrong (0x231 Microsoft Support site article Q184647)
public final static short SS_NONE = 0;
public final static short SS_SUPER = 1;
@@ -42,16 +43,12 @@ public final class FontRecord extends Record {
private short field_2_attributes;
// 0 0x01 - Reserved bit must be 0
- static final private BitField italic =
- BitFieldFactory.getInstance(0x02); // is this font in italics
+ private static final BitField italic = BitFieldFactory.getInstance(0x02); // is this font in italics
// 2 0x04 - reserved bit must be 0
- static final private BitField strikeout =
- BitFieldFactory.getInstance(0x08); // is this font has a line through the center
- static final private BitField macoutline = BitFieldFactory.getInstance(
- 0x10); // some weird macintosh thing....but who understands those mac people anyhow
- static final private BitField macshadow = BitFieldFactory.getInstance(
- 0x20); // some weird macintosh thing....but who understands those mac people anyhow
+ private static final BitField strikeout =BitFieldFactory.getInstance(0x08); // is this font has a line through the center
+ private static final BitField macoutline = BitFieldFactory.getInstance(0x10); // some weird macintosh thing....but who understands those mac people anyhow
+ private static final BitField macshadow = BitFieldFactory.getInstance(0x20); // some weird macintosh thing....but who understands those mac people anyhow
// 7-6 - reserved bits must be 0
// the rest is unused
@@ -62,15 +59,13 @@ public final class FontRecord extends Record {
private byte field_7_family; // ?? defined by windows api logfont structure?
private byte field_8_charset; // ?? defined by windows api logfont structure?
private byte field_9_zero = 0; // must be 0
- private byte field_10_font_name_len; // length of the font name
+ /** possibly empty string never
+ * Title: Footer Record (0x0015)
- * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
- * Description: describes a number format -- those goofy strings like $(#,###)
+ * Title: Format Record (0x041E)
+ * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
@@ -28,172 +26,50 @@ import org.apache.poi.util.StringUtil;
* @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02
* @author Jason Height (jheight at chariot dot net dot au)
*/
-public final class HeaderRecord extends Record {
+public final class HeaderRecord extends HeaderFooterBase {
public final static short sid = 0x0014;
- private byte field_1_header_len;
- private byte field_2_reserved;
- private byte field_3_unicode_flag;
- private String field_4_header;
- public HeaderRecord()
- {
+ public HeaderRecord(String text) {
+ super(text);
}
- public HeaderRecord(RecordInputStream in)
- {
- if (in.remaining() > 0)
- {
- field_1_header_len = in.readByte();
- /** These two fields are a bit odd. They are not documented*/
- field_2_reserved = in.readByte();
- field_3_unicode_flag = in.readByte(); // unicode
-
- if(isMultibyte())
- {
- field_4_header = in.readUnicodeLEString(LittleEndian.ubyteToInt( field_1_header_len));
- }
- else
- {
- field_4_header = in.readCompressedUnicode(LittleEndian.ubyteToInt( field_1_header_len));
- }
- }
- }
-
- /**
- * see the unicode flag
- *
- * @return boolean flag
- * true:footer string has at least one multibyte character
- */
- public boolean isMultibyte() {
- return ((field_3_unicode_flag & 0xFF) == 1);
- }
-
- /**
- * set the length of the header string
- *
- * @param len length of the header string
- * @see #setHeader(String)
- */
-
- public void setHeaderLength(byte len)
- {
- field_1_header_len = len;
+ public HeaderRecord(RecordInputStream in) {
+ super(in);
}
/**
* set the header string
*
* @param header string to display
- * @see #setHeaderLength(byte)
*/
-
- public void setHeader(String header)
- {
- field_4_header = header;
- field_3_unicode_flag =
- (byte) (StringUtil.hasMultibyte(field_4_header) ? 1 : 0);
-
- // Check it'll fit into the space in the record
- if(field_4_header == null) return;
- if(field_3_unicode_flag == 1) {
- if(field_4_header.length() > 127) {
- throw new IllegalArgumentException("Header string too long (limit is 127 for unicode strings)");
- }
- } else {
- if(field_4_header.length() > 255) {
- throw new IllegalArgumentException("Header string too long (limit is 255 for non-unicode strings)");
- }
- }
- }
-
- /**
- * get the length of the header string
- *
- * @return length of the header string
- * @see #getHeader()
- */
-
- public short getHeaderLength()
- {
- return (short)(0xFF & field_1_header_len); // [Shawn] Fixed needing unsigned byte
+ public void setHeader(String header) {
+ setText(header);
}
/**
* get the header string
*
* @return header string to display
- * @see #getHeaderLength()
*/
-
- public String getHeader()
- {
- return field_4_header;
+ public String getHeader() {
+ return getText();
}
- public String toString()
- {
+ public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[HEADER]\n");
- buffer.append(" .length = ").append(getHeaderLength())
- .append("\n");
- buffer.append(" .header = ").append(getHeader())
- .append("\n");
+ buffer.append(" .header = ").append(getText()).append("\n");
buffer.append("[/HEADER]\n");
return buffer.toString();
}
- public int serialize(int offset, byte [] data)
- {
- int len = 4;
- if (getHeaderLength() != 0)
- {
- len+=3; // [Shawn] Fixed for two null bytes in the length
- }
- short bytelen = (short)(isMultibyte() ?
- getHeaderLength()*2 : getHeaderLength() );
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset,
- ( short ) ((len - 4) + bytelen));
-
- if (getHeaderLength() > 0)
- {
- data[ 4 + offset ] = (byte)getHeaderLength();
- data[ 6 + offset ] = field_3_unicode_flag;
- if(isMultibyte())
- {
- StringUtil.putUnicodeLE(getHeader(), data, 7 + offset);
- }
- else
- {
- StringUtil.putCompressedUnicode(getHeader(), data, 7 + offset); // [Shawn] Place the string in the correct offset
- }
- }
- return getRecordSize();
- }
-
- protected int getDataSize() {
- int retval = 0;
-
- if (getHeaderLength() != 0) {
- retval+=3; // [Shawn] Fixed for two null bytes in the length
- }
- return retval + getHeaderLength() * (isMultibyte() ? 2 : 1);
- }
-
- public short getSid()
- {
+ public short getSid() {
return sid;
}
public Object clone() {
- HeaderRecord rec = new HeaderRecord();
- rec.field_1_header_len = field_1_header_len;
- rec.field_2_reserved = field_2_reserved;
- rec.field_3_unicode_flag = field_3_unicode_flag;
- rec.field_4_header = field_4_header;
- return rec;
+ return new HeaderRecord(getText());
}
}
diff --git a/src/java/org/apache/poi/hssf/record/IndexRecord.java b/src/java/org/apache/poi/hssf/record/IndexRecord.java
index 650d1258c..63727bb94 100644
--- a/src/java/org/apache/poi/hssf/record/IndexRecord.java
+++ b/src/java/org/apache/poi/hssf/record/IndexRecord.java
@@ -18,25 +18,23 @@
package org.apache.poi.hssf.record;
import org.apache.poi.util.IntList;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: Index Record
+ * Title: Index Record (0x020B)
+ * Important for locating cells
+ * REFERENCE: PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2) Record that contains the functionality page breaks (horizontal and vertical)
- * We support this in READ-ONLY mode. HSSF converts these to NUMBER records
+ * cycles on this then leave on of those "valuable" records out).
+ * Title: Recalc Id Record (0x01C1)
- * REFERENCE: http://chicago.sourceforge.net/devel/docs/excel/biff8.html
+ * serialization process
@@ -30,7 +32,7 @@ import org.apache.poi.util.LittleEndian;
* @author Jason Height (jheight at chariot dot net dot au)
* @author Glen Stampoultzis (glens at apache.org)
*/
-public final class SelectionRecord extends Record {
+public final class SelectionRecord extends StandardRecord {
public final static short sid = 0x001D;
private byte field_1_pane;
private int field_2_row_active_cell;
@@ -123,45 +125,35 @@ public final class SelectionRecord extends Record {
* @return ref number of active cell
*/
public int getActiveCellRef() {
- return (short)field_4_active_cell_ref_index;
+ return field_4_active_cell_ref_index;
}
public String toString() {
- StringBuffer buffer = new StringBuffer();
+ StringBuffer sb = new StringBuffer();
- buffer.append("[SELECTION]\n");
- buffer.append(" .pane = ")
- .append(Integer.toHexString(getPane())).append("\n");
- buffer.append(" .activecellrow = ")
- .append(Integer.toHexString(getActiveCellRow())).append("\n");
- buffer.append(" .activecellcol = ")
- .append(Integer.toHexString(getActiveCellCol())).append("\n");
- buffer.append(" .activecellref = ")
- .append(Integer.toHexString(getActiveCellRef())).append("\n");
- buffer.append(" .numrefs = ")
- .append(Integer.toHexString(field_6_refs.length)).append("\n");
- buffer.append("[/SELECTION]\n");
- return buffer.toString();
+ sb.append("[SELECTION]\n");
+ sb.append(" .pane = ").append(HexDump.byteToHex(getPane())).append("\n");
+ sb.append(" .activecellrow = ").append(HexDump.shortToHex(getActiveCellRow())).append("\n");
+ sb.append(" .activecellcol = ").append(HexDump.shortToHex(getActiveCellCol())).append("\n");
+ sb.append(" .activecellref = ").append(HexDump.shortToHex(getActiveCellRef())).append("\n");
+ sb.append(" .numrefs = ").append(HexDump.shortToHex(field_6_refs.length)).append("\n");
+ sb.append("[/SELECTION]\n");
+ return sb.toString();
}
protected int getDataSize() {
return 9 // 1 byte + 4 shorts
+ CellRangeAddress8Bit.getEncodedSize(field_6_refs.length);
}
- public int serialize(int offset, byte [] data) {
- int dataSize = getDataSize();
- LittleEndian.putUShort(data, 0 + offset, sid);
- LittleEndian.putUShort(data, 2 + offset, dataSize);
- LittleEndian.putByte(data, 4 + offset, getPane());
- LittleEndian.putUShort(data, 5 + offset, getActiveCellRow());
- LittleEndian.putUShort(data, 7 + offset, getActiveCellCol());
- LittleEndian.putUShort(data, 9 + offset, getActiveCellRef());
+ public void serialize(LittleEndianOutput out) {
+ out.writeByte(getPane());
+ out.writeShort(getActiveCellRow());
+ out.writeShort(getActiveCellCol());
+ out.writeShort(getActiveCellRef());
int nRefs = field_6_refs.length;
- LittleEndian.putUShort(data, 11 + offset, nRefs);
+ out.writeShort(nRefs);
for (int i = 0; i < field_6_refs.length; i++) {
- CellRangeAddress8Bit r = field_6_refs[i];
- r.serialize(offset + 13 + i * CellRangeAddress8Bit.ENCODED_SIZE, data);
+ field_6_refs[i].serialize(out);
}
- return 4 + dataSize;
}
public short getSid() {
diff --git a/src/java/org/apache/poi/hssf/record/SeriesListRecord.java b/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
index a6ebefd25..c8edda2aa 100644
--- a/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
+++ b/src/java/org/apache/poi/hssf/record/SeriesListRecord.java
@@ -17,16 +17,19 @@
package org.apache.poi.hssf.record;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
+ * SERIESLIST (0x1016)
*
* The series list record defines the series displayed as an overlay to the main chart record.
+ * Title: Sheet Tab Index Array Record (0x013D)
- * REFERENCE: PG 412 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * regardless of what their name is.
+ * Title: Unknown Record (for debugging)
+ * don't know all the records to. (HSSF leaves these alone!)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Jason Height (jheight at chariot dot net dot au)
* @author Glen Stampoultzis (glens at apache.org)
*/
-public final class UnknownRecord extends Record {
+public final class UnknownRecord extends StandardRecord {
/*
* Some Record IDs used by POI as 'milestones' in the record stream
@@ -79,12 +79,8 @@ public final class UnknownRecord extends Record {
/**
* spit the record out AS IS. no interpretation or identification
*/
- public final int serialize(int offset, byte[] data) {
- LittleEndian.putUShort(data, 0 + offset, _sid);
- int dataSize = _rawData.length;
- LittleEndian.putUShort(data, 2 + offset, dataSize);
- System.arraycopy(_rawData, 0, data, 4 + offset, dataSize);
- return 4 + dataSize;
+ public void serialize(LittleEndianOutput out) {
+ out.write(_rawData);
}
protected int getDataSize() {
@@ -94,7 +90,7 @@ public final class UnknownRecord extends Record {
/**
* print a sort of string representation ([UNKNOWN RECORD] id = x [/UNKNOWN RECORD])
*/
- public final String toString() {
+ public String toString() {
String biffName = getBiffName(_sid);
if (biffName == null) {
biffName = "UNKNOWNRECORD";
@@ -110,7 +106,7 @@ public final class UnknownRecord extends Record {
return sb.toString();
}
- public final short getSid() {
+ public short getSid() {
return (short) _sid;
}
@@ -267,8 +263,8 @@ public final class UnknownRecord extends Record {
return false;
}
- public final Object clone() {
- // immutable - ok to return this
+ public Object clone() {
+ // immutable - OK to return this
return this;
}
}
diff --git a/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java b/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
index 5870a9ace..3ff094e7f 100644
--- a/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
+++ b/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
@@ -19,7 +19,7 @@ package org.apache.poi.hssf.record;
import java.util.Arrays;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
@@ -33,9 +33,10 @@ import org.apache.poi.util.StringUtil;
*
* @author Andrew C. Oliver (acoliver at apache dot org)
*/
-public final class WriteAccessRecord extends Record {
- private static final byte PAD_CHAR = (byte) ' ';
+public final class WriteAccessRecord extends StandardRecord {
public final static short sid = 0x005C;
+
+ private static final byte PAD_CHAR = (byte) ' ';
private static final int DATA_SIZE = 112;
private String field_1_username;
/** this record is always padded to a constant length */
@@ -113,24 +114,18 @@ public final class WriteAccessRecord extends Record {
return buffer.toString();
}
- public int serialize(int offset, byte[] data) {
+ public void serialize(LittleEndianOutput out) {
String username = getUsername();
boolean is16bit = StringUtil.hasMultibyte(username);
- LittleEndian.putUShort(data, 0 + offset, sid);
- LittleEndian.putUShort(data, 2 + offset, DATA_SIZE);
- LittleEndian.putUShort(data, 4 + offset, username.length());
- LittleEndian.putByte(data, 6 + offset, is16bit ? 0x01 : 0x00);
- int pos = offset + 7;
+ out.writeShort(username.length());
+ out.writeByte(is16bit ? 0x01 : 0x00);
if (is16bit) {
- StringUtil.putUnicodeLE(username, data, pos);
- pos += username.length() * 2;
+ StringUtil.putUnicodeLE(username, out);
} else {
- StringUtil.putCompressedUnicode(username, data, pos);
- pos += username.length();
+ StringUtil.putCompressedUnicode(username, out);
}
- System.arraycopy(padding, 0, data, pos, padding.length);
- return 4 + DATA_SIZE;
+ out.write(padding);
}
protected int getDataSize() {
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
index c4d156597..68d4559a3 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
@@ -51,8 +51,8 @@ public final class PageSettingsBlock extends RecordAggregate {
// (The whole PageSettingsBlock may not be present)
private PageBreakRecord _rowBreaksRecord;
private PageBreakRecord _columnBreaksRecord;
- private HeaderRecord header;
- private FooterRecord footer;
+ private HeaderRecord _header;
+ private FooterRecord _footer;
private HCenterRecord _hCenter;
private VCenterRecord _vCenter;
private LeftMarginRecord _leftMargin;
@@ -77,8 +77,8 @@ public final class PageSettingsBlock extends RecordAggregate {
public PageSettingsBlock() {
_rowBreaksRecord = new HorizontalPageBreakRecord();
_columnBreaksRecord = new VerticalPageBreakRecord();
- header = createHeader();
- footer = createFooter();
+ _header = new HeaderRecord("");
+ _footer = new FooterRecord("");
_hCenter = createHCenter();
_vCenter = createVCenter();
printSetup = createPrintSetup();
@@ -117,10 +117,10 @@ public final class PageSettingsBlock extends RecordAggregate {
_columnBreaksRecord = (PageBreakRecord) rs.getNext();
break;
case HeaderRecord.sid:
- header = (HeaderRecord) rs.getNext();
+ _header = (HeaderRecord) rs.getNext();
break;
case FooterRecord.sid:
- footer = (FooterRecord) rs.getNext();
+ _footer = (FooterRecord) rs.getNext();
break;
case HCenterRecord.sid:
_hCenter = (HCenterRecord) rs.getNext();
@@ -193,8 +193,8 @@ public final class PageSettingsBlock extends RecordAggregate {
public void visitContainedRecords(RecordVisitor rv) {
visitIfPresent(_rowBreaksRecord, rv);
visitIfPresent(_columnBreaksRecord, rv);
- visitIfPresent(header, rv);
- visitIfPresent(footer, rv);
+ visitIfPresent(_header, rv);
+ visitIfPresent(_footer, rv);
visitIfPresent(_hCenter, rv);
visitIfPresent(_vCenter, rv);
visitIfPresent(_leftMargin, rv);
@@ -220,28 +220,6 @@ public final class PageSettingsBlock extends RecordAggregate {
}
}
- /**
- * creates the Header Record and sets it to nothing/0 length
- */
- private static HeaderRecord createHeader() {
- HeaderRecord retval = new HeaderRecord();
-
- retval.setHeaderLength(( byte ) 0);
- retval.setHeader(null);
- return retval;
- }
-
- /**
- * creates the Footer Record and sets it to nothing/0 length
- */
- private static FooterRecord createFooter() {
- FooterRecord retval = new FooterRecord();
-
- retval.setFooterLength(( byte ) 0);
- retval.setFooter(null);
- return retval;
- }
-
/**
* creates the HCenter Record and sets it to false (don't horizontally center)
*/
@@ -292,7 +270,7 @@ public final class PageSettingsBlock extends RecordAggregate {
*/
public HeaderRecord getHeader ()
{
- return header;
+ return _header;
}
/**
@@ -301,7 +279,7 @@ public final class PageSettingsBlock extends RecordAggregate {
*/
public void setHeader (HeaderRecord newHeader)
{
- header = newHeader;
+ _header = newHeader;
}
/**
@@ -310,7 +288,7 @@ public final class PageSettingsBlock extends RecordAggregate {
*/
public FooterRecord getFooter ()
{
- return footer;
+ return _footer;
}
/**
@@ -319,7 +297,7 @@ public final class PageSettingsBlock extends RecordAggregate {
*/
public void setFooter (FooterRecord newFooter)
{
- footer = newFooter;
+ _footer = newFooter;
}
/**
@@ -419,11 +397,11 @@ public final class PageSettingsBlock extends RecordAggregate {
*/
private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {
- Iterator iterator = breaks.getBreaksIterator();
- List shiftedBreak = new ArrayList();
+ Iterator
@@ -28,9 +28,9 @@ import org.apache.poi.util.LittleEndian;
*
* @author Libin Roman (Vista Portal LDT. Developer)
*/
-public class ExternSheetRecord extends Record {
+public class ExternSheetRecord extends StandardRecord {
public final static short sid = 0x0017;
- private List _list;
+ private Listnull
*/
private String field_11_font_name; // whoa...the font name
- public FontRecord()
- {
+ public FontRecord() {
}
- public FontRecord(RecordInputStream in)
- {
+ public FontRecord(RecordInputStream in) {
field_1_font_height = in.readShort();
field_2_attributes = in.readShort();
field_3_color_palette_index = in.readShort();
@@ -80,17 +75,15 @@ public final class FontRecord extends Record {
field_7_family = in.readByte();
field_8_charset = in.readByte();
field_9_zero = in.readByte();
- field_10_font_name_len = in.readByte();
- if (field_10_font_name_len > 0)
- {
- if (in.readByte() == 0)
- { // is compressed unicode
- field_11_font_name = in.readCompressedUnicode(LittleEndian.ubyteToInt(field_10_font_name_len));
- }
- else
- { // is not compressed unicode
+ int field_10_font_name_len = in.readUByte();
+ if (field_10_font_name_len > 0) {
+ if (in.readByte() == 0) { // is compressed unicode
+ field_11_font_name = in.readCompressedUnicode(field_10_font_name_len);
+ } else { // is not compressed unicode
field_11_font_name = in.readUnicodeLEString(field_10_font_name_len);
}
+ } else {
+ field_11_font_name = "";
}
}
@@ -244,17 +237,6 @@ public final class FontRecord extends Record {
field_8_charset = charset;
}
- /**
- * set the length of the fontname string
- *
- * @param len length of the font name
- * @see #setFontName(String)
- */
-
- public void setFontNameLength(byte len)
- {
- field_10_font_name_len = len;
- }
/**
* set the name of the font
@@ -415,18 +397,6 @@ public final class FontRecord extends Record {
return field_8_charset;
}
- /**
- * get the length of the fontname string
- *
- * @return length of the font name
- * @see #getFontName()
- */
-
- public byte getFontNameLength()
- {
- return field_10_font_name_len;
- }
-
/**
* get the name of the font
*
@@ -467,45 +437,46 @@ public final class FontRecord extends Record {
.append(Integer.toHexString(getFamily())).append("\n");
buffer.append(" .charset = ")
.append(Integer.toHexString(getCharset())).append("\n");
- buffer.append(" .namelength = ")
- .append(Integer.toHexString(getFontNameLength())).append("\n");
buffer.append(" .fontname = ").append(getFontName())
.append("\n");
buffer.append("[/FONT]\n");
return buffer.toString();
}
- public int serialize(int offset, byte [] data)
- {
- int realflen = getFontNameLength() * 2;
-
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(
- data, 2 + offset,
- ( short ) (15 + realflen
- + 1)); // 19 - 4 (sid/len) + font name length = datasize
-
- // undocumented single byte (1)
- LittleEndian.putShort(data, 4 + offset, getFontHeight());
- LittleEndian.putShort(data, 6 + offset, getAttributes());
- LittleEndian.putShort(data, 8 + offset, getColorPaletteIndex());
- LittleEndian.putShort(data, 10 + offset, getBoldWeight());
- LittleEndian.putShort(data, 12 + offset, getSuperSubScript());
- data[ 14 + offset ] = getUnderline();
- data[ 15 + offset ] = getFamily();
- data[ 16 + offset ] = getCharset();
- data[ 17 + offset ] = field_9_zero;
- data[ 18 + offset ] = getFontNameLength();
- data[ 19 + offset ] = ( byte ) 1;
- if (getFontName() != null) {
- StringUtil.putUnicodeLE(getFontName(), data, 20 + offset);
- }
- return getRecordSize();
+ public void serialize(LittleEndianOutput out) {
+
+ out.writeShort(getFontHeight());
+ out.writeShort(getAttributes());
+ out.writeShort(getColorPaletteIndex());
+ out.writeShort(getBoldWeight());
+ out.writeShort(getSuperSubScript());
+ out.writeByte(getUnderline());
+ out.writeByte(getFamily());
+ out.writeByte(getCharset());
+ out.writeByte(field_9_zero);
+ int fontNameLen = field_11_font_name.length();
+ out.writeByte(fontNameLen);
+ if (fontNameLen > 0) {
+ boolean hasMultibyte = StringUtil.hasMultibyte(field_11_font_name);
+ out.writeByte(hasMultibyte ? 0x01 : 0x00);
+ if (hasMultibyte) {
+ StringUtil.putUnicodeLE(field_11_font_name, out);
+ } else {
+ StringUtil.putCompressedUnicode(field_11_font_name, out);
+ }
+ }
}
protected int getDataSize() {
- // Note - no matter the original, we always
- // re-serialise the font name as unicode
- return 16 + getFontNameLength() * 2;
+ int size = 15; // 5 shorts + 5 bytes
+ int fontNameLen = field_11_font_name.length();
+ if (fontNameLen < 1) {
+ // options byte is not encoded if no character data
+ return size;
+ }
+ size ++; // options byte
+
+ boolean hasMultibyte = StringUtil.hasMultibyte(field_11_font_name);
+ return size + fontNameLen * (hasMultibyte ? 2 : 1);
}
public short getSid()
@@ -528,7 +499,6 @@ public final class FontRecord extends Record {
field_7_family = source.field_7_family;
field_8_charset = source.field_8_charset;
field_9_zero = source.field_9_zero;
- field_10_font_name_len = source.field_10_font_name_len;
field_11_font_name = source.field_11_font_name;
}
@@ -548,7 +518,6 @@ public final class FontRecord extends Record {
result = prime * result + field_7_family;
result = prime * result + field_8_charset;
result = prime * result + field_9_zero;
- result = prime * result + field_10_font_name_len;
return result;
}
@@ -572,7 +541,6 @@ public final class FontRecord extends Record {
field_7_family == other.field_7_family &&
field_8_charset == other.field_8_charset &&
field_9_zero == other.field_9_zero &&
- field_10_font_name_len == other.field_10_font_name_len &&
field_11_font_name.equals(other.field_11_font_name)
;
}
diff --git a/src/java/org/apache/poi/hssf/record/FooterRecord.java b/src/java/org/apache/poi/hssf/record/FooterRecord.java
index 0350d3a8c..b08d3dca1 100644
--- a/src/java/org/apache/poi/hssf/record/FooterRecord.java
+++ b/src/java/org/apache/poi/hssf/record/FooterRecord.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,191 +14,61 @@
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.LittleEndian;
-import org.apache.poi.util.StringUtil;
-
/**
- * Title: Footer Record
- * Description: Optional record defining a square area of cells to "merged" into
- * one cell.
- * REFERENCE: NONE (UNDOCUMENTED PRESENTLY)
+ * Description: Optional record defining a square area of cells to "merged" into one cell.
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
*/
-public final class MergeCellsRecord extends Record {
+public final class MergeCellsRecord extends StandardRecord {
public final static short sid = 0x00E5;
/** sometimes the regions array is shared with other MergedCellsRecords */
private CellRangeAddress[] _regions;
@@ -80,37 +77,26 @@ public final class MergeCellsRecord extends Record {
return sid;
}
- public int serialize(int offset, byte [] data) {
- int dataSize = CellRangeAddressList.getEncodedSize(_numberOfRegions);
-
- LittleEndian.putUShort(data, offset + 0, sid);
- LittleEndian.putUShort(data, offset + 2, dataSize);
+ public void serialize(LittleEndianOutput out) {
int nItems = _numberOfRegions;
- LittleEndian.putUShort(data, offset + 4, nItems);
- int pos = 6;
+ out.writeShort(nItems);
for (int i = 0; i < _numberOfRegions; i++) {
- pos += _regions[_startIndex + i].serialize(offset+pos, data);
+ _regions[_startIndex + i].serialize(out);
}
- return 4 + dataSize;
}
public String toString() {
StringBuffer retval = new StringBuffer();
retval.append("[MERGEDCELLS]").append("\n");
- retval.append(" .numregions =").append(getNumAreas())
- .append("\n");
+ retval.append(" .numregions =").append(getNumAreas()).append("\n");
for (int k = 0; k < _numberOfRegions; k++) {
- CellRangeAddress region = _regions[_startIndex + k];
+ CellRangeAddress r = _regions[_startIndex + k];
- retval.append(" .rowfrom =").append(region.getFirstRow())
- .append("\n");
- retval.append(" .rowto =").append(region.getLastRow())
- .append("\n");
- retval.append(" .colfrom =").append(region.getFirstColumn())
- .append("\n");
- retval.append(" .colto =").append(region.getLastColumn())
- .append("\n");
+ retval.append(" .rowfrom =").append(r.getFirstRow()).append("\n");
+ retval.append(" .rowto =").append(r.getLastRow()).append("\n");
+ retval.append(" .colfrom =").append(r.getFirstColumn()).append("\n");
+ retval.append(" .colto =").append(r.getLastColumn()).append("\n");
}
retval.append("[MERGEDCELLS]").append("\n");
return retval.toString();
diff --git a/src/java/org/apache/poi/hssf/record/MulBlankRecord.java b/src/java/org/apache/poi/hssf/record/MulBlankRecord.java
index 6ecaa20f9..009148ea3 100644
--- a/src/java/org/apache/poi/hssf/record/MulBlankRecord.java
+++ b/src/java/org/apache/poi/hssf/record/MulBlankRecord.java
@@ -17,6 +17,8 @@
package org.apache.poi.hssf.record;
+import org.apache.poi.util.LittleEndianOutput;
+
/**
* Title: Multiple Blank cell record(0x00BE)
* Description: Represents a set of columns in a row with no value but with styling.
@@ -27,7 +29,7 @@ package org.apache.poi.hssf.record;
* @author Glen Stampoultzis (glens at apache.org)
* @see BlankRecord
*/
-public final class MulBlankRecord extends Record {
+public final class MulBlankRecord extends StandardRecord {
public final static short sid = 0x00BE;
private int field_1_row;
@@ -124,7 +126,7 @@ public final class MulBlankRecord extends Record {
return sid;
}
- public int serialize(int offset, byte [] data) {
+ public void serialize(LittleEndianOutput out) {
throw new RecordFormatException( "Sorry, you can't serialize MulBlank in this release");
}
protected int getDataSize() {
diff --git a/src/java/org/apache/poi/hssf/record/MulRKRecord.java b/src/java/org/apache/poi/hssf/record/MulRKRecord.java
index dbb41c10f..3c1390d07 100644
--- a/src/java/org/apache/poi/hssf/record/MulRKRecord.java
+++ b/src/java/org/apache/poi/hssf/record/MulRKRecord.java
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
import org.apache.poi.hssf.util.RKUtil;
import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
/**
* MULRK (0x00BD)
@@ -29,7 +30,7 @@ import org.apache.poi.util.HexDump;
* @author Andrew C. Oliver (acoliver at apache dot org)
* @version 2.0-pre
*/
-public final class MulRKRecord extends Record {
+public final class MulRKRecord extends StandardRecord {
public final static short sid = 0x00BD;
private int field_1_row;
@@ -113,7 +114,7 @@ public final class MulRKRecord extends Record {
return sid;
}
- public int serialize(int offset, byte [] data) {
+ public void serialize(LittleEndianOutput out) {
throw new RecordFormatException( "Sorry, you can't serialize MulRK in this release");
}
protected int getDataSize() {
diff --git a/src/java/org/apache/poi/hssf/record/PageBreakRecord.java b/src/java/org/apache/poi/hssf/record/PageBreakRecord.java
index a3717f40e..d0f6e2af0 100644
--- a/src/java/org/apache/poi/hssf/record/PageBreakRecord.java
+++ b/src/java/org/apache/poi/hssf/record/PageBreakRecord.java
@@ -23,7 +23,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
* null
if the specified index
* does not exist
*/
- public byte[] getColor(short byteIndex)
- {
+ public byte[] getColor(short byteIndex) {
int i = byteIndex - FIRST_COLOR_INDEX;
if (i < 0 || i >= field_2_colors.size())
{
return null;
}
- PColor color = (PColor) field_2_colors.get(i);
+ PColor color = field_2_colors.get(i);
return new byte[] { color.red, color.green, color.blue };
}
@@ -138,9 +120,9 @@ public class PaletteRecord
{
return;
}
- while (field_2_colors.size() <= i)
- {
- field_2_colors.add(new PColor((byte) 0, (byte) 0, (byte) 0));
+ // may need to grow - fill intervening pallette entries with black
+ while (field_2_colors.size() <= i) {
+ field_2_colors.add(new PColor(0, 0, 0));
}
PColor custColor = new PColor(red, green, blue);
field_2_colors.set(i, custColor);
@@ -151,100 +133,99 @@ public class PaletteRecord
*
* @see org.apache.poi.hssf.model.Workbook#createPalette
*/
- private void createDefaultPalette()
+ private static PColor[] createDefaultPalette()
{
- field_1_numcolors = STANDARD_PALETTE_SIZE;
- field_2_colors = new ArrayList(field_1_numcolors);
- byte[] palette = new byte[]
- {
- (byte) 0, (byte) 0, (byte) 0, (byte) 0, //color 0...
- (byte) 255, (byte) 255, (byte) 255, (byte) 0,
- (byte) 255, (byte) 0, (byte) 0, (byte) 0,
- (byte) 0, (byte) 255, (byte) 0, (byte) 0,
- (byte) 0, (byte) 0, (byte) 255, (byte) 0,
- (byte) 255, (byte) 255, (byte) 0, (byte) 0,
- (byte) 255, (byte) 0, (byte) 255, (byte) 0,
- (byte) 0, (byte) 255, (byte) 255, (byte) 0,
- (byte) 128, (byte) 0, (byte) 0, (byte) 0,
- (byte) 0, (byte) 128, (byte) 0, (byte) 0,
- (byte) 0, (byte) 0, (byte) 128, (byte) 0,
- (byte) 128, (byte) 128, (byte) 0, (byte) 0,
- (byte) 128, (byte) 0, (byte) 128, (byte) 0,
- (byte) 0, (byte) 128, (byte) 128, (byte) 0,
- (byte) 192, (byte) 192, (byte) 192, (byte) 0,
- (byte) 128, (byte) 128, (byte) 128, (byte) 0,
- (byte) 153, (byte) 153, (byte) 255, (byte) 0,
- (byte) 153, (byte) 51, (byte) 102, (byte) 0,
- (byte) 255, (byte) 255, (byte) 204, (byte) 0,
- (byte) 204, (byte) 255, (byte) 255, (byte) 0,
- (byte) 102, (byte) 0, (byte) 102, (byte) 0,
- (byte) 255, (byte) 128, (byte) 128, (byte) 0,
- (byte) 0, (byte) 102, (byte) 204, (byte) 0,
- (byte) 204, (byte) 204, (byte) 255, (byte) 0,
- (byte) 0, (byte) 0, (byte) 128, (byte) 0,
- (byte) 255, (byte) 0, (byte) 255, (byte) 0,
- (byte) 255, (byte) 255, (byte) 0, (byte) 0,
- (byte) 0, (byte) 255, (byte) 255, (byte) 0,
- (byte) 128, (byte) 0, (byte) 128, (byte) 0,
- (byte) 128, (byte) 0, (byte) 0, (byte) 0,
- (byte) 0, (byte) 128, (byte) 128, (byte) 0,
- (byte) 0, (byte) 0, (byte) 255, (byte) 0,
- (byte) 0, (byte) 204, (byte) 255, (byte) 0,
- (byte) 204, (byte) 255, (byte) 255, (byte) 0,
- (byte) 204, (byte) 255, (byte) 204, (byte) 0,
- (byte) 255, (byte) 255, (byte) 153, (byte) 0,
- (byte) 153, (byte) 204, (byte) 255, (byte) 0,
- (byte) 255, (byte) 153, (byte) 204, (byte) 0,
- (byte) 204, (byte) 153, (byte) 255, (byte) 0,
- (byte) 255, (byte) 204, (byte) 153, (byte) 0,
- (byte) 51, (byte) 102, (byte) 255, (byte) 0,
- (byte) 51, (byte) 204, (byte) 204, (byte) 0,
- (byte) 153, (byte) 204, (byte) 0, (byte) 0,
- (byte) 255, (byte) 204, (byte) 0, (byte) 0,
- (byte) 255, (byte) 153, (byte) 0, (byte) 0,
- (byte) 255, (byte) 102, (byte) 0, (byte) 0,
- (byte) 102, (byte) 102, (byte) 153, (byte) 0,
- (byte) 150, (byte) 150, (byte) 150, (byte) 0,
- (byte) 0, (byte) 51, (byte) 102, (byte) 0,
- (byte) 51, (byte) 153, (byte) 102, (byte) 0,
- (byte) 0, (byte) 51, (byte) 0, (byte) 0,
- (byte) 51, (byte) 51, (byte) 0, (byte) 0,
- (byte) 153, (byte) 51, (byte) 0, (byte) 0,
- (byte) 153, (byte) 51, (byte) 102, (byte) 0,
- (byte) 51, (byte) 51, (byte) 153, (byte) 0,
- (byte) 51, (byte) 51, (byte) 51, (byte) 0
+ return new PColor[] {
+ pc(0, 0, 0),
+ pc(255, 255, 255),
+ pc(255, 0, 0),
+ pc(0, 255, 0),
+ pc(0, 0, 255),
+ pc(255, 255, 0),
+ pc(255, 0, 255),
+ pc(0, 255, 255),
+ pc(128, 0, 0),
+ pc(0, 128, 0),
+ pc(0, 0, 128),
+ pc(128, 128, 0),
+ pc(128, 0, 128),
+ pc(0, 128, 128),
+ pc(192, 192, 192),
+ pc(128, 128, 128),
+ pc(153, 153, 255),
+ pc(153, 51, 102),
+ pc(255, 255, 204),
+ pc(204, 255, 255),
+ pc(102, 0, 102),
+ pc(255, 128, 128),
+ pc(0, 102, 204),
+ pc(204, 204, 255),
+ pc(0, 0, 128),
+ pc(255, 0, 255),
+ pc(255, 255, 0),
+ pc(0, 255, 255),
+ pc(128, 0, 128),
+ pc(128, 0, 0),
+ pc(0, 128, 128),
+ pc(0, 0, 255),
+ pc(0, 204, 255),
+ pc(204, 255, 255),
+ pc(204, 255, 204),
+ pc(255, 255, 153),
+ pc(153, 204, 255),
+ pc(255, 153, 204),
+ pc(204, 153, 255),
+ pc(255, 204, 153),
+ pc(51, 102, 255),
+ pc(51, 204, 204),
+ pc(153, 204, 0),
+ pc(255, 204, 0),
+ pc(255, 153, 0),
+ pc(255, 102, 0),
+ pc(102, 102, 153),
+ pc(150, 150, 150),
+ pc(0, 51, 102),
+ pc(51, 153, 102),
+ pc(0, 51, 0),
+ pc(51, 51, 0),
+ pc(153, 51, 0),
+ pc(153, 51, 102),
+ pc(51, 51, 153),
+ pc(51, 51, 51),
};
-
- for (int k = 0; k < field_1_numcolors; k++) {
- field_2_colors.add(new PColor(
- palette[k*4],
- palette[k*4+1],
- palette[k*4+2]
- )
- );
- }
-
}
-}
+
+ private static PColor pc(int r, int g, int b) {
+ return new PColor(r, g, b);
+ }
/**
* PColor - element in the list of colors - consider it a "struct"
*/
-class PColor {
+private static final class PColor {
+ public static final short ENCODED_SIZE = 4;
public byte red;
public byte green;
public byte blue;
- public PColor(byte red, byte green, byte blue) {
- this.red=red;
- this.green=green;
- this.blue=blue;
+
+ public PColor(int red, int green, int blue) {
+ this.red=(byte) red;
+ this.green=(byte) green;
+ this.blue=(byte) blue;
}
- public void serialize(byte[] data, int offset) {
- data[offset + 0] = red;
- data[offset + 1] = green;
- data[offset + 2] = blue;
- data[offset + 3] = 0;
+ public PColor(RecordInputStream in) {
+ red=in.readByte();
+ green=in.readByte();
+ blue=in.readByte();
+ in.readByte(); // unused
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeByte(red);
+ out.writeByte(green);
+ out.writeByte(blue);
+ out.writeByte(0);
}
public String toString() {
@@ -255,3 +236,4 @@ class PColor {
return buffer.toString();
}
}
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/RKRecord.java b/src/java/org/apache/poi/hssf/record/RKRecord.java
index 48a8c564f..966aaf219 100644
--- a/src/java/org/apache/poi/hssf/record/RKRecord.java
+++ b/src/java/org/apache/poi/hssf/record/RKRecord.java
@@ -19,15 +19,16 @@ package org.apache.poi.hssf.record;
import org.apache.poi.hssf.util.RKUtil;
import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: RK Record (0x027E)
+ * Title: RK Record (0x027E)
* Description: An internal 32 bit number with the two most significant bits
* storing the type. This is part of a bizarre scheme to save disk
* space and memory (gee look at all the other whole records that
* are in the file just "cause"..,far better to waste processor
- * cycles on this then leave on of those "valuable" records out).0xC1 0x01 0x00 0x00 0x60 0x69 0x01
* 0x00
have been seen. If the field isNeeded
is
* set to false (default), then this record is swallowed during the
- * serialization process
- * TODO - does this record (0x1016) really exist. It doesn't seem to be referenced in either the OOO or MS doc
+ * This record doesn't seem to be referenced in either the OOO or MS doc, but this page mentions it
+ * http://ooxmlisdefectivebydesign.blogspot.com/2008/03/bad-surprise-in-microsoft-office-binary.html
+ *
*
* @author Glen Stampoultzis (glens at apache.org)
*/
-public final class SeriesListRecord extends Record {
+public final class SeriesListRecord extends StandardRecord {
public final static short sid = 0x1016;
private short[] field_1_seriesNumbers;
@@ -55,23 +58,13 @@ public final class SeriesListRecord extends Record {
return buffer.toString();
}
- public int serialize(int offset, byte[] data) {
+ public void serialize(LittleEndianOutput out) {
int nItems = field_1_seriesNumbers.length;
- int dataSize = 2 + 2 * nItems;
-
- LittleEndian.putUShort(data, 0 + offset, sid);
- LittleEndian.putUShort(data, 2 + offset, dataSize);
-
- LittleEndian.putUShort(data, 4 + offset, nItems);
-
- int pos = offset + 6;
+ out.writeShort(nItems);
for (int i = 0; i < nItems; i++) {
- LittleEndian.putUShort(data, pos, field_1_seriesNumbers[i]);
- pos += 2;
+ out.writeShort(field_1_seriesNumbers[i]);
}
-
- return 4 + dataSize;
}
protected int getDataSize() {
@@ -84,7 +77,7 @@ public final class SeriesListRecord extends Record {
}
public Object clone() {
- return new SeriesListRecord((short[]) field_1_seriesNumbers.clone());
+ return new SeriesListRecord(field_1_seriesNumbers.clone());
}
/**
diff --git a/src/java/org/apache/poi/hssf/record/StyleRecord.java b/src/java/org/apache/poi/hssf/record/StyleRecord.java
index 9994dfcf7..f9541d593 100644
--- a/src/java/org/apache/poi/hssf/record/StyleRecord.java
+++ b/src/java/org/apache/poi/hssf/record/StyleRecord.java
@@ -20,7 +20,7 @@ package org.apache.poi.hssf.record;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
@@ -30,11 +30,9 @@ import org.apache.poi.util.StringUtil;
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author aviks : string fixes for UserDefined Style
*/
-public final class StyleRecord extends Record {
+public final class StyleRecord extends StandardRecord {
public final static short sid = 0x0293;
- private static final BitField is16BitUnicodeFlag = BitFieldFactory.getInstance(0x01);
-
private static final BitField styleIndexMask = BitFieldFactory.getInstance(0x0FFF);
private static final BitField isBuiltinFlag = BitFieldFactory.getInstance(0x8000);
@@ -46,7 +44,7 @@ public final class StyleRecord extends Record {
private int field_3_outline_style_level;
// only for user defined styles
- private int field_3_string_options;
+ private boolean field_3_stringHasMultibyte;
private String field_4_name;
/**
@@ -74,8 +72,8 @@ public final class StyleRecord extends Record {
field_4_name = "";
} else {
- int is16BitUnicode = in.readByte();
- if (is16BitUnicodeFlag.isSet(is16BitUnicode)) {
+ 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);
@@ -107,7 +105,7 @@ public final class StyleRecord extends Record {
*/
public void setName(String name) {
field_4_name = name;
- field_3_string_options = StringUtil.hasMultibyte(name) ? 0x01 : 0x00;
+ field_3_stringHasMultibyte = StringUtil.hasMultibyte(name);
field_1_xf_index = isBuiltinFlag.clear(field_1_xf_index);
}
@@ -162,34 +160,24 @@ public final class StyleRecord extends Record {
if (isBuiltin()) {
return 4; // short, byte, byte
}
- int size = 2 + 3; // short
- if (is16BitUnicodeFlag.isSet(field_3_string_options)) {
- size += 2 * field_4_name.length();
- } else {
- size += field_4_name.length();
- }
- return size;
+ return 2 // short xf index
+ + 3 // str len + flag
+ + field_4_name.length() * (field_3_stringHasMultibyte ? 2 : 1);
}
- public int serialize(int offset, byte [] data) {
- int dataSize = getDataSize();
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putUShort(data, 2 + offset, dataSize);
-
- LittleEndian.putUShort(data, 4 + offset, field_1_xf_index);
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(field_1_xf_index);
if (isBuiltin()) {
- LittleEndian.putByte(data, 6 + offset, field_2_builtin_style);
- LittleEndian.putByte(data, 7 + offset, field_3_outline_style_level);
+ out.writeByte(field_2_builtin_style);
+ out.writeByte(field_3_outline_style_level);
} else {
- LittleEndian.putUShort(data, 6 + offset, field_4_name.length());
- LittleEndian.putByte(data, 8 + offset, field_3_string_options);
- StringUtil.putCompressedUnicode(getName(), data, 9 + offset);
+ out.writeShort(field_4_name.length());
+ out.writeByte(field_3_stringHasMultibyte ? 0x01 : 0x00);
+ StringUtil.putCompressedUnicode(getName(), out);
}
- return 4+dataSize;
}
- public short getSid()
- {
+ public short getSid() {
return sid;
}
}
diff --git a/src/java/org/apache/poi/hssf/record/TabIdRecord.java b/src/java/org/apache/poi/hssf/record/TabIdRecord.java
index 9478d008b..7c6803d4e 100644
--- a/src/java/org/apache/poi/hssf/record/TabIdRecord.java
+++ b/src/java/org/apache/poi/hssf/record/TabIdRecord.java
@@ -17,30 +17,31 @@
package org.apache.poi.hssf.record;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: Sheet Tab Index Array Record