]> source.dussan.org Git - poi.git/commitdiff
Refactoring Record.serialize methods
authorJosh Micich <josh@apache.org>
Wed, 19 Nov 2008 00:06:06 +0000 (00:06 +0000)
committerJosh Micich <josh@apache.org>
Wed, 19 Nov 2008 00:06:06 +0000 (00:06 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@718810 13f79535-47bb-0310-9956-ffa450edef68

41 files changed:
src/java/org/apache/poi/hssf/model/Workbook.java
src/java/org/apache/poi/hssf/record/BoundSheetRecord.java
src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
src/java/org/apache/poi/hssf/record/ChartTitleFormatRecord.java
src/java/org/apache/poi/hssf/record/DBCellRecord.java
src/java/org/apache/poi/hssf/record/DVALRecord.java
src/java/org/apache/poi/hssf/record/DrawingRecord.java
src/java/org/apache/poi/hssf/record/ExtSSTInfoSubRecord.java [deleted file]
src/java/org/apache/poi/hssf/record/ExtSSTRecord.java
src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
src/java/org/apache/poi/hssf/record/FileSharingRecord.java
src/java/org/apache/poi/hssf/record/FontRecord.java
src/java/org/apache/poi/hssf/record/FooterRecord.java
src/java/org/apache/poi/hssf/record/FormatRecord.java
src/java/org/apache/poi/hssf/record/HeaderFooterBase.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/HeaderRecord.java
src/java/org/apache/poi/hssf/record/IndexRecord.java
src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java [deleted file]
src/java/org/apache/poi/hssf/record/LinkedDataRecord.java
src/java/org/apache/poi/hssf/record/MergeCellsRecord.java
src/java/org/apache/poi/hssf/record/MulBlankRecord.java
src/java/org/apache/poi/hssf/record/MulRKRecord.java
src/java/org/apache/poi/hssf/record/PageBreakRecord.java
src/java/org/apache/poi/hssf/record/PaletteRecord.java
src/java/org/apache/poi/hssf/record/RKRecord.java
src/java/org/apache/poi/hssf/record/RecalcIdRecord.java
src/java/org/apache/poi/hssf/record/SelectionRecord.java
src/java/org/apache/poi/hssf/record/SeriesListRecord.java
src/java/org/apache/poi/hssf/record/StyleRecord.java
src/java/org/apache/poi/hssf/record/TabIdRecord.java
src/java/org/apache/poi/hssf/record/UnknownRecord.java
src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
src/java/org/apache/poi/hssf/usermodel/HSSFFont.java
src/java/org/apache/poi/hssf/usermodel/HSSFFooter.java
src/java/org/apache/poi/hssf/usermodel/HSSFHeader.java
src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java
src/testcases/org/apache/poi/hssf/record/TestFontRecord.java
src/testcases/org/apache/poi/hssf/record/TestLinkedDataRecord.java

index 222f0a6ab6193c54e8b71850cf4a5165a2022b6a..84ebf9962242edd3ea517d5d24aa6e9e7432f85b 100644 (file)
@@ -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 )
index 17d337f82322ff9ec79dbd5c8ae178e3fb67990b..391a3a08ba7b302f2b4835a105f76837a5eb45f7 100644 (file)
@@ -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) <P>
- * Description:  Defines a sheet within a workbook.  Basically stores the sheetname
+ * Title:        Bound Sheet Record (aka BundleSheet) (0x0085)<P>
+ * 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. <P>
  * REFERENCE:  PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @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<BoundSheetRecord> boundSheetRecords) {
                BoundSheetRecord[] bsrs = new BoundSheetRecord[boundSheetRecords.size()];
                boundSheetRecords.toArray(bsrs);
                Arrays.sort(bsrs, BOFComparator);
                return bsrs;
        }
-       private static final Comparator BOFComparator = new Comparator() {
-               public int compare(Object bsr1, Object bsr2) {
-                       return compare((BoundSheetRecord)bsr1, (BoundSheetRecord)bsr2);
-               }
+       private static final Comparator<BoundSheetRecord> BOFComparator = new Comparator<BoundSheetRecord>() {
+
                public int compare(BoundSheetRecord bsr1, BoundSheetRecord bsr2) {
                        return bsr1.getPositionOfBof() - bsr2.getPositionOfBof();
                }
index eeadd388a7bbb4ebee909a05ff4e7805c7e5f4a3..eb17ee275814c23b704a3b285c18d45e88ac7592 100644 (file)
@@ -20,15 +20,15 @@ package org.apache.poi.hssf.record;
 import org.apache.poi.hssf.record.cf.CellRangeUtil;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Conditional Formatting Header record CFHEADER (0x1B0)
+ * Conditional Formatting Header record CFHEADER (0x01B0)
  * 
  * @author Dmitriy Kumshayev
  */
-public final class CFHeaderRecord extends Record {
-       public static final short sid = 0x1B0;
+public final class CFHeaderRecord extends StandardRecord {
+       public static final short sid = 0x01B0;
 
        private int field_1_numcf;
        private int field_2_need_recalculation;
@@ -136,23 +136,15 @@ public final class CFHeaderRecord extends Record {
                        + field_4_cell_ranges.getSize();
        }
        
-       /**
-        * @return byte array containing instance data
-        */
-       public int serialize(int offset, byte[] data) {
-               int dataSize = getDataSize();
-               
-               LittleEndian.putUShort(data, 0 + offset, sid);
-               LittleEndian.putUShort(data, 2 + offset, dataSize);
-               LittleEndian.putUShort(data, 4 + offset, field_1_numcf);
-               LittleEndian.putUShort(data, 6 + offset, field_2_need_recalculation);
-               field_3_enclosing_cell_range.serialize(8 + offset, data);
-               field_4_cell_ranges.serialize(16 + offset, data);
-               return 4 + dataSize;
-       }
-
-       public short getSid()
-       {
+       public void serialize(LittleEndianOutput out) {
+
+               out.writeShort(field_1_numcf);
+               out.writeShort(field_2_need_recalculation);
+               field_3_enclosing_cell_range.serialize(out);
+               field_4_cell_ranges.serialize(out);
+       }
+
+       public short getSid() {
                return sid;
        }
 
index 37f539e4a0a7d045c69a4a5c69339b39c5ee2920..d24c58a7d758734411703f21567966d7de14d28f 100644 (file)
  */
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
-
-import java.util.ArrayList;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
+ * CHARTTITLEFORMAT (0x1050)<p/>
  * Describes the formatting runs associated with a chart title.
  */
-public class ChartTitleFormatRecord extends Record {
+public class ChartTitleFormatRecord extends StandardRecord {
        public static final short sid = 0x1050;
        
-       private int             m_recs;
+       private CTFormat[] _formats;
        
-       private class CTFormat {
-               private short m_offset;
-               private short m_fontIndex;
+       private static final class CTFormat {
+               public static final int ENCODED_SIZE=4;
+               private int _offset;
+               private int _fontIndex;
                
                protected CTFormat(short offset,short fontIdx){
-                       m_offset = offset;
-                       m_fontIndex = fontIdx;
+                       _offset = offset;
+                       _fontIndex = fontIdx;
                }
                
-               public short getOffset(){
-                       return m_offset;
+               public CTFormat(RecordInputStream in) {
+                       _offset = in.readShort();
+                       _fontIndex = in.readShort();
                }
-               public void setOffset(short newOff){
-                       m_offset = newOff;
+
+               public int getOffset(){
+                       return _offset;
                }
-               public short getFontIndex() {
-                       return m_fontIndex;
+               public void setOffset(int newOff){
+                       _offset = newOff;
+               }
+               public int getFontIndex() {
+                       return _fontIndex;
                }
-       }
-       
-       private ArrayList m_formats;
 
-       public ChartTitleFormatRecord() {
-               super();
+               public void serialize(LittleEndianOutput out) {
+                       out.writeShort(_offset);
+                       out.writeShort(_fontIndex);
+               }
        }
 
+
        public ChartTitleFormatRecord(RecordInputStream in) {
-               m_recs = in.readUShort();
-               int idx;
-               CTFormat ctf;
-               if (m_formats == null){
-                       m_formats = new ArrayList(m_recs);
-               }
-               for(idx=0;idx<m_recs;idx++) {
-                       ctf = new CTFormat(in.readShort(),in.readShort());
-                       m_formats.add(ctf);
+               int nRecs = in.readUShort();
+               _formats = new CTFormat[nRecs];
+
+               for(int i=0;i<nRecs;i++) {
+                       _formats[i] = new CTFormat(in);
                }
        }
 
-       public int serialize(int offset, byte [] data)
-    {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset,
-                              ( short ) (getRecordSize() - 4));   
-        int idx;
-        CTFormat ctf;
-        LittleEndian.putShort(data, 4 + offset,(short)m_formats.size());
-        for(idx=0;idx<m_formats.size();idx++){
-               ctf = (CTFormat)m_formats.get(idx);
-               LittleEndian.putShort(data, 6 + (idx * 4) + offset, ctf.getOffset());
-               LittleEndian.putShort(data, 8 + (idx * 4) + offset, ctf.getFontIndex());
+       public void serialize(LittleEndianOutput out) {
+        out.writeShort(_formats.length);
+        for(int i=0; i<_formats.length; i++){
+            _formats[i].serialize(out);
         }
-        
-        return getRecordSize();
     }
 
     protected int getDataSize() {
-        return 2 + (4 * m_formats.size());
+        return 2 + CTFormat.ENCODED_SIZE * _formats.length;
     }
     
        public short getSid() {
@@ -97,33 +88,29 @@ public class ChartTitleFormatRecord extends Record {
        }
        
        public int getFormatCount() {
-               return m_formats.size();
+               return _formats.length;
        }
        
-       public void modifyFormatRun(short oldPos,short newLen) {
-               short shift = (short)0;
-               for(int idx=0;idx < m_formats.size();idx++) {
-                       CTFormat ctf = (CTFormat)m_formats.get(idx);
+       public void modifyFormatRun(short oldPos, short newLen) {
+               int shift = 0;
+               for(int i=0; i < _formats.length; i++) {
+                       CTFormat ctf = _formats[i];
                        if (shift != 0) {
-                               ctf.setOffset((short)(ctf.getOffset() + shift));
-                       } else if ((oldPos == ctf.getOffset()) && (idx < (m_formats.size() - 1))){
-                               CTFormat nextCTF = (CTFormat)m_formats.get(idx + 1);
-                               shift = (short)(newLen - (nextCTF.getOffset() - ctf.getOffset()));
+                               ctf.setOffset(ctf.getOffset() + shift);
+                       } else if (oldPos == ctf.getOffset() && i < _formats.length - 1){
+                               CTFormat nextCTF = _formats[i + 1];
+                               shift = newLen - (nextCTF.getOffset() - ctf.getOffset());
                        } 
                }
        }
        
-       public String toString()
-    {
+       public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[CHARTTITLEFORMAT]\n");
-        buffer.append("    .format_runs       = ").append(m_recs)
-            .append("\n");
-        int idx;
-        CTFormat ctf;
-        for(idx=0;idx<m_formats.size();idx++){
-               ctf = (CTFormat)m_formats.get(idx);
+        buffer.append("    .format_runs       = ").append(_formats.length).append("\n");
+        for(int i=0; i<_formats.length; i++) {
+            CTFormat ctf = _formats[i];
                buffer.append("       .char_offset= ").append(ctf.getOffset());
                buffer.append(",.fontidx= ").append(ctf.getFontIndex());
             buffer.append("\n");
index cb0afcbdaefd9192ce2e8acad5f1e6ba7acab11f..b9b9d44c894f95d8a3c905ae0290cb57551af403 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title:        DBCell Record
+ * Title:        DBCell Record (0x00D7)<p/>
  * Description:  Used by Excel and other MS apps to quickly find rows in the sheets.<P>
  * REFERENCE:  PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @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 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()
-    {
-        field_2_cell_offsets = new short[0];
+        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 ];
-        }
-        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));
+    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 ]);
         }
-        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;
     }
 }
index 69e94deacb1fb7466b8cf78538e0500bfb02698b..0bd4600b60de48a5a83351a9ccea1dffdf3f3423 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title:        DATAVALIDATIONS Record<P>
+ * Title:        DATAVALIDATIONS Record (0x01B2)<p/>
  * Description:  used in data validation ;
  *               This record is the list header of all data validation records (0x01BE) in the current sheet.
  * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
  */
-public class DVALRecord extends Record
-{
+public final class DVALRecord extends StandardRecord {
        public final static short sid = 0x01B2;
 
        /** Options of the DVAL */
@@ -48,57 +47,51 @@ public class DVALRecord extends Record
         field_5_dv_no = 0x00000000;
     }
 
-       public DVALRecord(RecordInputStream in)
-       {
-               this.field_1_options = in.readShort();
-               this.field_2_horiz_pos = in.readInt();
-               this.field_3_vert_pos = in.readInt();
-        this.field_cbo_id    = in.readInt(); 
-        this.field_5_dv_no   = in.readInt();
+       public DVALRecord(RecordInputStream in) {
+               field_1_options = in.readShort();
+               field_2_horiz_pos = in.readInt();
+               field_3_vert_pos = in.readInt();
+        field_cbo_id    = in.readInt(); 
+        field_5_dv_no   = in.readInt();
        }
 
-
     /**
         * @param field_1_options the options of the dialog
         */
-       public void setOptions(short field_1_options) {
-               this.field_1_options = field_1_options;
+       public void setOptions(short options) {
+               field_1_options = options;
        }
 
        /**
         * @param field_2_horiz_pos the Horizontal position of the dialog
         */
-       public void setHorizontalPos(int field_2_horiz_pos) {
-               this.field_2_horiz_pos = field_2_horiz_pos;
+       public void setHorizontalPos(int horiz_pos) {
+               field_2_horiz_pos = horiz_pos;
        }
 
        /**
         * @param field_3_vert_pos the Vertical position of the dialog
         */
-       public void setVerticalPos(int field_3_vert_pos) {
-               this.field_3_vert_pos = field_3_vert_pos;
+       public void setVerticalPos(int vert_pos) {
+               field_3_vert_pos = vert_pos;
        }
 
        /**
      * set the object ID of the drop down arrow object for list boxes
      * @param cboID - Object ID
      */
-    public void setObjectID(int cboID)
-    {
-        this.field_cbo_id = cboID;
+    public void setObjectID(int cboID) {
+        field_cbo_id = cboID;
     }
 
     /**
      * Set the number of following DV records
      * @param dvNo - the DV records number
      */
-    public void setDVRecNo(int dvNo)
-    {
-        this.field_5_dv_no = dvNo;
+    public void setDVRecNo(int dvNo) {
+        field_5_dv_no = dvNo;
     }
 
-    
-    
     /**
         * @return the field_1_options
         */
@@ -123,64 +116,55 @@ public class DVALRecord extends Record
        /**
      * get Object ID of the drop down arrow object for list boxes
      */
-    public int getObjectID( )
-    {
-        return this.field_cbo_id;
+    public int getObjectID() {
+        return field_cbo_id;
     }
 
     /**
      * Get number of following DV records
      */
-    public int getDVRecNo( )
-    {
-        return this.field_5_dv_no;
+    public int getDVRecNo() {
+        return field_5_dv_no;
     }
 
 
-       public String toString()
-       {
+       public String toString() {
                StringBuffer buffer = new StringBuffer();
 
                buffer.append("[DVAL]\n");
-               buffer.append("    .options      = ").append(this.getOptions()).append('\n');
-               buffer.append("    .horizPos     = ").append(this.getHorizontalPos()).append('\n');
-               buffer.append("    .vertPos      = ").append(this.getVerticalPos()).append('\n');
-               buffer.append("    .comboObjectID   = ").append(Integer.toHexString(this.getObjectID())).append("\n");
-               buffer.append("    .DVRecordsNumber = ").append(Integer.toHexString(this.getDVRecNo())).append("\n");
+               buffer.append("    .options      = ").append(getOptions()).append('\n');
+               buffer.append("    .horizPos     = ").append(getHorizontalPos()).append('\n');
+               buffer.append("    .vertPos      = ").append(getVerticalPos()).append('\n');
+               buffer.append("    .comboObjectID   = ").append(Integer.toHexString(getObjectID())).append("\n");
+               buffer.append("    .DVRecordsNumber = ").append(Integer.toHexString(getDVRecNo())).append("\n");
                buffer.append("[/DVAL]\n");
                return buffer.toString();
        }
 
-    public int serialize(int offset, byte [] data)
-    {
-        LittleEndian.putShort(data, 0 + offset, this.sid);
-        LittleEndian.putShort(data, 2 + offset, ( short)(this.getRecordSize()-4));
-               
-               LittleEndian.putShort(data, 4 + offset, this.getOptions());
-               LittleEndian.putInt(data, 6 + offset, this.getHorizontalPos());
-               LittleEndian.putInt(data, 10 + offset, this.getVerticalPos());
-        LittleEndian.putInt(data, 14 + offset, this.getObjectID());
-        LittleEndian.putInt(data, 18 + offset, this.getDVRecNo());
-        return getRecordSize();
+    public void serialize(LittleEndianOutput out) {
+               
+               out.writeShort(getOptions());
+               out.writeInt(getHorizontalPos());
+               out.writeInt(getVerticalPos());
+               out.writeInt(getObjectID());
+               out.writeInt(getDVRecNo());
     }
 
     protected int getDataSize() {
         return 18;
     }
 
-    public short getSid()
-    {
-        return this.sid;
+    public short getSid() {
+        return sid;
     }
 
-    public Object clone()
-    {
+    public Object clone() {
       DVALRecord rec = new DVALRecord();
       rec.field_1_options = field_1_options;
       rec.field_2_horiz_pos = field_2_horiz_pos;
       rec.field_3_vert_pos = field_3_vert_pos;
-      rec.field_cbo_id = this.field_cbo_id;
-      rec.field_5_dv_no = this.field_5_dv_no;
+      rec.field_cbo_id = field_cbo_id;
+      rec.field_5_dv_no = field_5_dv_no;
       return rec;
     }
 }
index b0af2c7e6e6cc67172d73308a743c86f4988b65f..9ba18aee03c69294dbff785e22198fd7a9aad8d1 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
-
-public final class DrawingRecord extends Record {
+import org.apache.poi.util.LittleEndianOutput;
+/**
+ * DrawingRecord (0x00EC)<p/>
+ *
+ */
+public final class DrawingRecord extends StandardRecord {
     public static final short sid = 0x00EC;
 
        private static final byte[] EMPTY_BYTE_ARRAY = { };
@@ -31,70 +34,50 @@ public final class DrawingRecord extends Record {
        recordData = EMPTY_BYTE_ARRAY;
     }
 
-    public DrawingRecord( RecordInputStream in )
-    {
+    public DrawingRecord(RecordInputStream in) {
       recordData = in.readRemainder();
     }
 
-    public void processContinueRecord( byte[] record )
-    {
+    public void processContinueRecord(byte[] record) {
         //don't merge continue record with the drawing record, it must be serialized separately
         contd = record;
     }
 
-    public int serialize( int offset, byte[] data )
-    {
-        if (recordData == null)
-        {
-            recordData = new byte[ 0 ];
-        }
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, ( short ) (recordData.length));
-        if (recordData.length > 0)
-        {
-            System.arraycopy(recordData, 0, data, 4 + offset, recordData.length);
-        }
-        return getRecordSize();
+    public void serialize(LittleEndianOutput out) {
+        out.write(recordData);
     }
     protected int getDataSize() {
-        int retval = 0;
-
-        if (recordData != null) {
-            retval += recordData.length;
-        }
-        return retval;
+        return recordData.length;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
-    public byte[] getData()
-    {
+    public byte[] getData() {
         if(contd != null) {
             byte[] newBuffer = new byte[ recordData.length + contd.length ];
             System.arraycopy( recordData, 0, newBuffer, 0, recordData.length );
             System.arraycopy( contd, 0, newBuffer, recordData.length, contd.length);
             return newBuffer;
-        } else {
-            return recordData;
         }
+        return recordData;
     }
 
-    public void setData( byte[] thedata )
-    {
-        this.recordData = thedata;
+    public void setData(byte[] thedata) {
+       if (thedata == null) {
+               throw new IllegalArgumentException("data must not be null");
+       }
+        recordData = thedata;
     }
 
     public Object clone() {
        DrawingRecord rec = new DrawingRecord();
        
-       rec.recordData = new byte[ recordData.length ];
-       System.arraycopy(recordData, 0, rec.recordData, 0, recordData.length);
+       rec.recordData = recordData.clone();
        if (contd != null) {
-               System.arraycopy(contd, 0, rec.contd, 0, contd.length);
-               rec.contd = new byte[ contd.length ];
+               // TODO - this code probably never executes
+               rec.contd = contd.clone();
        }
        
        return rec;
diff --git a/src/java/org/apache/poi/hssf/record/ExtSSTInfoSubRecord.java b/src/java/org/apache/poi/hssf/record/ExtSSTInfoSubRecord.java
deleted file mode 100644 (file)
index 845f95a..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================== */
-        
-
-/*
- * ExtSSTInfoSubRecord.java
- *
- * Created on September 8, 2001, 8:37 PM
- */
-package org.apache.poi.hssf.record;
-
-import org.apache.poi.util.LittleEndian;
-
-/**
- * Extended SST table info subrecord<P>
- * contains the elements of "info" in the SST's array field<P>
- * @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;
-    }
-}
index 8225f6b76ddd2fa3880183d8a1b4819c0bc99b88..f5fe5df32af14662c20d4b011f94f237ab63aadf 100644 (file)
 
 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<P>
+ * Title:        Extended Static String Table (0x00FF)<p/>
  * Description: This record is used for a quick lookup into the SST record. This
  *              record breaks the SST table into a set of buckets. The offsets
  *              to these buckets within the SST record are kept as well as the
@@ -31,101 +28,108 @@ import org.apache.poi.util.LittleEndian;
  * REFERENCE:  PG 313 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @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 ExtSSTRecord()
-    {
-        field_2_sst_info = new ArrayList();
-    }
+        public InfoSubRecord(RecordInputStream in)
+        {
+            field_1_stream_pos        = in.readInt();
+            field_2_bucket_sst_offset = in.readShort();
+            field_3_zero              = in.readShort();
+        }
 
-    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);
+        public int getStreamPos() {
+            return field_1_stream_pos;
+        }
 
-            field_2_sst_info.add(rec);
+        public int getBucketSSTOffset() {
+            return field_2_bucket_sst_offset;
         }
-    }
 
-    public void setNumStringsPerBucket(short numStrings)
-    {
-        field_1_strings_per_bucket = numStrings;
+        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 void addInfoRecord(ExtSSTInfoSubRecord rec)
-    {
-        field_2_sst_info.add(rec);
-    }
 
-    public short getNumStringsPerBucket()
-    {
-        return field_1_strings_per_bucket;
+    public ExtSSTRecord() {
+       _stringsPerBucket = DEFAULT_BUCKET_SIZE;
+        _sstInfos = new InfoSubRecord[0];
     }
 
-    public int getNumInfoRecords()
-    {
-        return field_2_sst_info.size();
+    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 ExtSSTInfoSubRecord getInfoRecordAt(int elem)
-    {
-        return ( ExtSSTInfoSubRecord ) field_2_sst_info.get(elem);
+    public void setNumStringsPerBucket(short numStrings) {
+        _stringsPerBucket = numStrings;
     }
 
-    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]);
         }
     }
-
 }
index cbb287ed15618975da29840b9e1c2018da846195..af6b9731a0e2a6f74d03cb95feb46eab6f0eed9e 100644 (file)
@@ -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)<br/>
@@ -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 List<RefSubRecord> _list;
        
        private final class RefSubRecord {
                public static final int ENCODED_SIZE = 6;
@@ -73,43 +73,27 @@ public class ExternSheetRecord extends Record {
                        return buffer.toString();
                }
                
-               /**
-                * called by the class that is responsible for writing this sucker.
-                * Subclasses should implement this so that their data is passed back in a
-                * byte array.
-                *
-                * @param offset to begin writing at
-                * @param data byte array containing instance data
-                * @return number of bytes written
-                */
-               public void serialize(int offset, byte [] data) {
-                       LittleEndian.putUShort(data, 0 + offset, _extBookIndex);
-                       LittleEndian.putUShort(data, 2 + offset, _firstSheetIndex);
-                       LittleEndian.putUShort(data, 4 + offset, _lastSheetIndex);
+               public void serialize(LittleEndianOutput out) {
+                       out.writeShort(_extBookIndex);
+                       out.writeShort(_firstSheetIndex);
+                       out.writeShort(_lastSheetIndex);
                }
        }       
        
        
        
        public ExternSheetRecord() {
-               _list = new ArrayList();
+               _list = new ArrayList<RefSubRecord>();
        }
-       
-       /**
-        * called by the constructor, should set class level fields.  Should throw
-        * runtime exception for bad/icomplete data.
-        *
-        * @param in the RecordInputstream to read the record from
-        */
+
        public ExternSheetRecord(RecordInputStream in) {
-               _list              = new ArrayList();
+               _list = new ArrayList<RefSubRecord>();
                
                int nItems  = in.readShort();
                
                for (int i = 0 ; i < nItems ; ++i) {
                        RefSubRecord rec = new RefSubRecord(in);
-                       
-                       _list.add( rec);
+                       _list.add(rec);
                }
        }
        
@@ -157,35 +141,18 @@ public class ExternSheetRecord extends Record {
                return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
        }
        
-       /**
-        * called by the class that is responsible for writing this sucker.
-        * Subclasses should implement this so that their data is passed back in a
-        * byte array.
-        *
-        * @param offset to begin writing at
-        * @param data byte array containing instance data
-        * @return number of bytes written
-        */
-       public int serialize(int offset, byte [] data) {
-               int dataSize = getDataSize();
-               
+       public void serialize(LittleEndianOutput out) {
                int nItems = _list.size();
 
-               LittleEndian.putShort(data, 0 + offset, sid);
-               LittleEndian.putUShort(data, 2 + offset, dataSize);
-               LittleEndian.putUShort(data, 4 + offset, nItems);
-               
-               int pos = 6 ;
+               out.writeShort(nItems);
                
                for (int i = 0; i < nItems; i++) {
-                       getRef(i).serialize(offset + pos, data);
-                       pos +=6;
+                       getRef(i).serialize(out);
                }
-               return dataSize + 4;
        }
 
        private RefSubRecord getRef(int i) {
-               return (RefSubRecord) _list.get(i);
+               return _list.get(i);
        }
        
        /**
index f6b3e6340c479fcae4c253a11d2a422f610d30b8..d53911dde5c5784bde1ee62f7de55e39deefed46 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        FILESHARING<P>
+ * Title:        FILESHARING (0x005B) <p/>
  * Description:  stores the encrypted readonly for a workbook (write protect) 
  * This functionality is accessed from the options dialog box available when performing 'Save As'.<p/>
  * REFERENCE:  PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  */
-public final class FileSharingRecord extends Record {
+public final class FileSharingRecord extends StandardRecord {
 
-    public final static short sid = 0x5b;
+    public final static short sid = 0x005B;
     private short             field_1_readonly;
     private short             field_2_password;
     private byte              field_3_username_unicode_options;
@@ -103,12 +103,6 @@ public final class FileSharingRecord extends Record {
         return field_2_password;
     }
 
-    /**
-     * @return byte representing the length of the username field
-     */
-    public short getUsernameLength() {
-        return (short) field_3_username_value.length();
-    }
 
     /**
      * @return username of the user that created the file
@@ -139,22 +133,19 @@ public final class FileSharingRecord extends Record {
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data) {
+    public void serialize(LittleEndianOutput out) {
         // TODO - junit
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize()-4));
-        LittleEndian.putShort(data, 4 + offset, getReadOnly());
-        LittleEndian.putShort(data, 6 + offset, getPassword());
-        LittleEndian.putShort(data, 8 + offset, getUsernameLength());
-        if(getUsernameLength() > 0) {
-            LittleEndian.putByte(data, 10 + offset, field_3_username_unicode_options);
-            StringUtil.putCompressedUnicode( getUsername(), data, 11 + offset );
+        out.writeShort(getReadOnly());
+        out.writeShort(getPassword());
+        out.writeShort(field_3_username_value.length());
+        if(field_3_username_value.length() > 0) {
+               out.writeByte(field_3_username_unicode_options);
+            StringUtil.putCompressedUnicode(getUsername(), out);
         }
-        return getRecordSize();
     }
 
     protected int getDataSize() {
-        short nameLen = getUsernameLength();
+        int nameLen = field_3_username_value.length();
         if (nameLen < 1) {
             return 6;
         }
index 890460f9e70714aa229cdc65ef31fff0b9ae4b16..3b0b4f3e30703ad1212149768d18fcac36967eba 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.StringUtil;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        Font Record - descrbes a font in the workbook (index = 0-3,5-infinity - skip 4)<P>
+ * Title:        Font Record (0x0031) <p/>
+ * - describes a font in the workbook (index = 0-3,5-infinity - skip 4)<P>
  * Description:  An element in the Font Table<P>
  * REFERENCE:  PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @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 <code>null</code> */
     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)
                ;
        }
index 0350d3a8cdc225f81c9c44715f2273a15646bde5..b08d3dca1105a664ee85efeee73343d42454bd69 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    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 <P>
+ * Title:        Footer Record (0x0015) <p/>
  * Description:  Specifies the footer for a sheet<P>
- * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02
  * @author Jason Height (jheight at chariot dot net dot au)
- * @version 2.0-pre
+ *
  */
+public final class FooterRecord extends HeaderFooterBase {
+    public final static short sid = 0x0015;
 
-public class FooterRecord
-    extends Record
-{
-    public final static short sid = 0x15;
-    private byte              field_1_footer_len;
-    private byte              field_2_reserved;
-    private byte              field_3_unicode_flag;
-    private String            field_4_footer;
-
-    public FooterRecord()
-    {
-    }
-
-    public FooterRecord(RecordInputStream in)
-    {
-        if (in.remaining() > 0)
-        {
-            field_1_footer_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_footer = in.readUnicodeLEString(LittleEndian.ubyteToInt( field_1_footer_len));
-                         }
-                         else
-                         {
-                field_4_footer = in.readCompressedUnicode(LittleEndian.ubyteToInt( field_1_footer_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);
+    public FooterRecord(String text) {
+       super(text);
     }
 
+    public FooterRecord(RecordInputStream in) {
+               super(in);
+       }
 
-    /**
-     * set the length of the footer string
-     *
-     * @param len  length of the footer string
-     * @see #setFooter(String)
-     */
-
-    public void setFooterLength(byte len)
-    {
-        field_1_footer_len = len;
-    }
-
-    /**
+     /**
      * set the footer string
      *
      * @param footer string to display
-     * @see #setFooterLength(byte)
-     */
-
-    public void setFooter(String footer)
-    {
-        field_4_footer = footer;
-        field_3_unicode_flag = 
-            (byte) (StringUtil.hasMultibyte(field_4_footer) ? 1 : 0);
-        // Check it'll fit into the space in the record
-        
-        if(field_4_footer == null) return;
-        if(field_3_unicode_flag == 1) {
-               if(field_4_footer.length() > 127) {
-                       throw new IllegalArgumentException("Footer string too long (limit is 127 for unicode strings)");
-               }
-        } else {
-               if(field_4_footer.length() > 255) {
-                       throw new IllegalArgumentException("Footer string too long (limit is 255 for non-unicode strings)");
-               }
-        }
-    }
-
-    /**
-     * get the length of the footer string
-     *
-     * @return length of the footer string
-     * @see #getFooter()
      */
-
-    public short getFooterLength()
-    {
-        return (short)(0xFF & field_1_footer_len); // [Shawn] Fixed needing unsigned byte
+    public void setFooter(String footer) {
+        setText(footer);
     }
 
     /**
      * get the footer string
      *
      * @return footer string to display
-     * @see #getFooterLength()
      */
-
-    public String getFooter()
-    {
-        return field_4_footer;
+    public String getFooter() {
+        return getText();
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[FOOTER]\n");
-        buffer.append("    .footerlen      = ")
-            .append(Integer.toHexString(getFooterLength())).append("\n");
-        buffer.append("    .footer         = ").append(getFooter())
-            .append("\n");
+        buffer.append("    .footer = ").append(getText()).append("\n");
         buffer.append("[/FOOTER]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        int len = 4;
-
-        if (getFooterLength() > 0)
-        {
-            len+=3; // [Shawn] Fixed for two null bytes in the length
-        }
-        short bytelen = (short)(isMultibyte() ?
-            getFooterLength()*2 : getFooterLength() );
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset,
-                              ( short ) ((len - 4) + bytelen ));
-        if (getFooterLength() > 0)
-        {
-            data[ 4 + offset ] = (byte)getFooterLength();
-            data[ 6 + offset ] = field_3_unicode_flag;
-            if(isMultibyte())
-            {
-                StringUtil.putUnicodeLE(getFooter(), data, 7 + offset);
-            }
-            else
-            {
-                StringUtil.putCompressedUnicode(getFooter(), data, 7 + offset); // [Shawn] Place the string in the correct offset
-            }
-        }
-        return getRecordSize();
-    }
-
-    protected int getDataSize() {
-        int retval = 0;
-
-        if (getFooterLength() > 0) {
-            retval+=3; // [Shawn] Fixed for two null bytes in the length
-        }
-        return retval + getFooterLength() * (isMultibyte() ? 2 : 1);
-    }
-
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
     public Object clone() {
-      FooterRecord rec = new FooterRecord();
-      rec.field_1_footer_len = field_1_footer_len;
-      rec.field_2_reserved = field_2_reserved;
-      rec.field_3_unicode_flag = field_3_unicode_flag;
-      rec.field_4_footer = field_4_footer;
-      return rec;
+        return new FooterRecord(getText());
     }
 }
index 6ea2ce96325b77d02b3ab0401db39e891d185dcb..2d2f238c5162aaaad6a0eb88f491a9d622d0640f 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        Format Record<P>
- * Description:  describes a number format -- those goofy strings like $(#,###)<P>
+ * Title:        Format Record (0x041E) <p/>
+ * Description:  describes a number format -- those goofy strings like $(#,###)<p/>
  *
- * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Shawn M. Laubach (slaubach at apache dot org)  
+ * @author Shawn M. Laubach (slaubach at apache dot org)
  */
-public final class FormatRecord extends Record {
+public final class FormatRecord extends StandardRecord {
     public final static short sid = 0x041E;
-    private short             field_1_index_code;
 
-    private short             field_3_unicode_len;      // unicode string length
-    private boolean          field_3_unicode_flag;     // it is not undocumented - it is unicode flag
-    private String            field_4_formatstring;
+    private final int field_1_index_code;
+    private final boolean field_3_hasMultibyte;
+    private final String field_4_formatstring;
 
-    public FormatRecord()
-    {
-    }
-
-    public FormatRecord(RecordInputStream in)
-    {
-        field_1_index_code       = in.readShort();
-        field_3_unicode_len      = in.readShort();
-        field_3_unicode_flag     = ( in.readByte() & (byte)0x01 ) != 0;
-                                              
-      if ( field_3_unicode_flag  ) {
-          // unicode
-          field_4_formatstring = in.readUnicodeLEString( field_3_unicode_len );
-      }
-      else {
-          // not unicode
-          field_4_formatstring = in.readCompressedUnicode( field_3_unicode_len );
-      }
-    }
-
-    /**
-     * set the format index code (for built in formats)
-     *
-     * @param index  the format index code
-     * @see org.apache.poi.hssf.model.Workbook
-     */
-
-    public void setIndexCode(short index)
-    {
-        field_1_index_code = index;
-    }
-
-    /**
-     * set the format string length
-     *
-     * @param len  the length of the format string
-     * @see #setFormatString(String)
-     */
-    
-    public void setFormatStringLength(byte len)
-    {
-
-       field_3_unicode_len = len;
-    }
-
-    /**
-     * set whether the string is unicode
-     *
-     * @param unicode flag for whether string is unicode
-     */
-
-    public void setUnicodeFlag(boolean unicode) {
-       field_3_unicode_flag = unicode;
+    public FormatRecord(int indexCode, String fs) {
+        field_1_index_code = indexCode;
+        field_4_formatstring = fs;
+        field_3_hasMultibyte = StringUtil.hasMultibyte(fs);
     }
 
-    /**
-     * set the format string
-     *
-     * @param fs  the format string
-     * @see #setFormatStringLength(byte)
-     */
+    public FormatRecord(RecordInputStream in) {
+        field_1_index_code = in.readShort();
+        int field_3_unicode_len = in.readUShort();
+        field_3_hasMultibyte = (in.readByte() & 0x01) != 0;
 
-    public void setFormatString(String fs)
-    {
-        field_4_formatstring = fs;
-        setUnicodeFlag(StringUtil.hasMultibyte(fs));
+        if (field_3_hasMultibyte) {
+            field_4_formatstring = in.readUnicodeLEString(field_3_unicode_len);
+        } else {
+            field_4_formatstring = in.readCompressedUnicode(field_3_unicode_len);
+        }
     }
 
     /**
@@ -110,95 +60,53 @@ public final class FormatRecord extends Record {
      * @return the format index code
      * @see org.apache.poi.hssf.model.Workbook
      */
-
-    public short getIndexCode()
-    {
+    public int getIndexCode() {
         return field_1_index_code;
     }
 
-    /**
-     * get the format string length
-     *
-     * @return the length of the format string
-     * @see #getFormatString()
-     */
-
-   /* public short getFormatStringLength()
-    {
-        return field_3_unicode_flag ? field_3_unicode_len : field_2_formatstring_len;
-    }*/
-
-    /**
-     * get whether the string is unicode
-     *
-     * @return flag for whether string is unicode
-     */
-
-    public boolean getUnicodeFlag() {
-       return field_3_unicode_flag;
-    }    
-
     /**
      * get the format string
      *
      * @return the format string
      */
-
-    public String getFormatString()
-    {
+    public String getFormatString() {
         return field_4_formatstring;
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[FORMAT]\n");
-        buffer.append("    .indexcode       = ")
-            .append(Integer.toHexString(getIndexCode())).append("\n");
-        /*
-        buffer.append("    .formatstringlen = ")
-            .append(Integer.toHexString(getFormatStringLength()))
-            .append("\n");
-        */
-        buffer.append("    .unicode length  = ")
-            .append(Integer.toHexString(field_3_unicode_len)).append("\n");
-        buffer.append("    .isUnicode       = ")
-            .append( field_3_unicode_flag ).append("\n");
-        buffer.append("    .formatstring    = ").append(getFormatString())
-            .append("\n");
+        buffer.append("    .indexcode       = ").append(HexDump.shortToHex(getIndexCode())).append("\n");
+        buffer.append("    .isUnicode       = ").append(field_3_hasMultibyte ).append("\n");
+        buffer.append("    .formatstring    = ").append(getFormatString()).append("\n");
         buffer.append("[/FORMAT]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, (short)( 2 + 2 + 1 + ( (field_3_unicode_flag) 
-                                                                  ? 2 * field_3_unicode_len 
-                                                                  : field_3_unicode_len ) ) );
-                                                  // index + len + flag + format string length
-        LittleEndian.putShort(data, 4 + offset, getIndexCode());
-        LittleEndian.putShort(data, 6 + offset, field_3_unicode_len);
-        data[ 8 + offset ] = (byte)( (field_3_unicode_flag) ? 0x01 : 0x00 );
-
-      if ( field_3_unicode_flag ) {
-          // unicode
-          StringUtil.putUnicodeLE( getFormatString(), data, 9 + offset );
-      }
-      else {
-          // not unicode
-          StringUtil.putCompressedUnicode( getFormatString(), data, 9 + offset );
+    public void serialize(LittleEndianOutput out) {
+        String formatString = getFormatString();
+        out.writeShort(getIndexCode());
+        out.writeShort(formatString.length());
+        out.writeByte(field_3_hasMultibyte ? 0x01 : 0x00);
+
+      if ( field_3_hasMultibyte ) {
+          StringUtil.putUnicodeLE( formatString, out);
+      }  else {
+          StringUtil.putCompressedUnicode( formatString, out);
       }
-      
-        return getRecordSize();
     }
     protected int getDataSize() {
-        return 5 + field_3_unicode_len * (field_3_unicode_flag ? 2 : 1);
+        return 5 // 2 shorts + 1 byte
+            + getFormatString().length() * (field_3_hasMultibyte ? 2 : 1);
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
+    @Override
+    public Object clone() {
+        // immutable
+        return this;
+    }
 }
diff --git a/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java b/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java
new file mode 100644 (file)
index 0000000..92ccf94
--- /dev/null
@@ -0,0 +1,109 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.record;\r
+\r
+import org.apache.poi.util.LittleEndianOutput;\r
+import org.apache.poi.util.StringUtil;\r
+\r
+/**\r
+ * Common header/footer base class\r
+ * \r
+ * @author Josh Micich\r
+ */\r
+abstract class HeaderFooterBase extends StandardRecord {\r
+       private boolean field_2_hasMultibyte;\r
+       private String field_3_text;\r
+\r
+       protected HeaderFooterBase(String text) {\r
+               setText(text);\r
+       }\r
+\r
+       protected HeaderFooterBase(RecordInputStream in) {\r
+               if (in.remaining() > 0) {\r
+                       int field_1_footer_len = in.readShort();\r
+                       field_2_hasMultibyte = in.readByte() != 0x00;\r
+\r
+                       if (field_2_hasMultibyte) {\r
+                               field_3_text = in.readUnicodeLEString(field_1_footer_len);\r
+                       } else {\r
+                               field_3_text = in.readCompressedUnicode(field_1_footer_len);\r
+                       }\r
+               } else {\r
+                       // Note - this is unusual: when the text is empty string, the whole record is empty (just the 4 byte BIFF header)\r
+                       field_3_text = "";\r
+               }\r
+       }\r
+\r
+       /**\r
+        * set the footer string\r
+        * \r
+        * @param text string to display\r
+        */\r
+       public final void setText(String text) {\r
+               if (text == null) {\r
+                       throw new IllegalArgumentException("text must not be null");\r
+               }\r
+               field_2_hasMultibyte = StringUtil.hasMultibyte(text);\r
+               field_3_text = text;\r
+               \r
+               // Check it'll fit into the space in the record\r
+               if (field_2_hasMultibyte) {\r
+                       if (field_3_text.length() > 127) {\r
+                               throw new IllegalArgumentException(\r
+                                               "Footer string too long (limit is 127 for unicode strings)");\r
+                       }\r
+               } else {\r
+                       if (field_3_text.length() > 255) {\r
+                               throw new IllegalArgumentException(\r
+                                               "Footer string too long (limit is 255 for non-unicode strings)");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * get the length of the footer string\r
+        * \r
+        * @return length of the footer string\r
+        */\r
+       private int getTextLength() {\r
+               return field_3_text.length();\r
+       }\r
+\r
+       public final String getText() {\r
+               return field_3_text;\r
+       }\r
+\r
+       public final void serialize(LittleEndianOutput out) {\r
+               if (getTextLength() > 0) {\r
+                       out.writeShort(getTextLength());\r
+                       out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00);\r
+                       if (field_2_hasMultibyte) {\r
+                               StringUtil.putUnicodeLE(field_3_text, out);\r
+                       } else {\r
+                               StringUtil.putCompressedUnicode(field_3_text, out);\r
+                       }\r
+               }\r
+       }\r
+\r
+       protected final int getDataSize() {\r
+               if (getTextLength() < 1) {\r
+                       return 0;\r
+               }\r
+               return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1);\r
+       }\r
+}\r
index aea321eacadbfc8e27b79ca36c8135257adf0547..188149d7df831807f87b01ff18feb5e5140da8f6 100644 (file)
@@ -17,8 +17,6 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.StringUtil;
 
 /**
  * Title:        Header Record<P>
@@ -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());
     }
 }
index 650d1258c8b526adea6ffc66e6719891c436c64e..63727bb946a7a6d438c1a25a9b110d427a7d2198 100644 (file)
 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<P>
+ * Title:        Index Record (0x020B)<p/>
  * Description:  Occurs right after BOF, tells you where the DBCELL records are for a sheet
- *               Important for locating cells<P>
+ *               Important for locating cells<p/>
  * NOT USED IN THIS RELEASE
- * REFERENCE:  PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * REFERENCE:  PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public class IndexRecord extends Record {
-    public final static short sid             = 0x020B;
-    public final static int   DBCELL_CAPACITY = 30;
-    public int                field_1_zero;            // reserved must be 0
-    public int                field_2_first_row;       // first row on the sheet
-    public int                field_3_last_row_add1;   // last row
-    public int                field_4_zero;            // reserved must be 0
-    public IntList            field_5_dbcells;         // array of offsets to DBCELL records
+public class IndexRecord extends StandardRecord {
+    public final static short sid = 0x020B;
+    private int                field_2_first_row;       // first row on the sheet
+    private int                field_3_last_row_add1;   // last row
+    private int                field_4_zero;            // supposed to be zero
+    private IntList            field_5_dbcells;         // array of offsets to DBCELL records
 
     public IndexRecord()
     {
@@ -44,16 +42,17 @@ public class IndexRecord extends Record {
 
     public IndexRecord(RecordInputStream in)
     {
-        field_5_dbcells       =
-            new IntList(DBCELL_CAPACITY);   // initial capacity of 30
-        field_1_zero          = in.readInt();
+        int field_1_zero          = in.readInt();
+        if (field_1_zero != 0) {
+               throw new RecordFormatException("Expected zero for field 1 but got " + field_1_zero);
+        }
         field_2_first_row     = in.readInt();
         field_3_last_row_add1 = in.readInt();
-        field_4_zero          = in.readInt();
-        while(in.remaining() > 0)
-        {
-
-            // System.out.println("getting " + k);
+        field_4_zero      = in.readInt();
+        
+        int nCells = in.remaining() / 4;
+        field_5_dbcells = new IntList(nCells);
+        for(int i=0; i<nCells; i++) {
             field_5_dbcells.add(in.readInt());
         }
     }
@@ -115,50 +114,43 @@ public class IndexRecord extends Record {
             .append(Integer.toHexString(getFirstRow())).append("\n");
         buffer.append("    .lastrowadd1    = ")
             .append(Integer.toHexString(getLastRowAdd1())).append("\n");
-        for (int k = 0; k < getNumDbcells(); k++)
-        {
-            buffer.append("    .dbcell_" + k + "       = ")
+        for (int k = 0; k < getNumDbcells(); k++) {
+            buffer.append("    .dbcell_").append(k).append(" = ")
                 .append(Integer.toHexString(getDbcellAt(k))).append("\n");
         }
         buffer.append("[/INDEX]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset,
-                              ( short ) (16 + (getNumDbcells() * 4)));
-        LittleEndian.putInt(data, 4 + offset, 0);
-        LittleEndian.putInt(data, 8 + offset, getFirstRow());
-        LittleEndian.putInt(data, 12 + offset, getLastRowAdd1());
-        LittleEndian.putInt(data, 16 + offset, 0);
-        for (int k = 0; k < getNumDbcells(); k++)
-        {
-            LittleEndian.putInt(data, (k * 4) + 20 + offset, getDbcellAt(k));
+    public void serialize(LittleEndianOutput out) {
+
+        out.writeInt(0);
+        out.writeInt(getFirstRow());
+        out.writeInt(getLastRowAdd1());
+        out.writeInt(field_4_zero);
+        for (int k = 0; k < getNumDbcells(); k++) {
+               out.writeInt(getDbcellAt(k));
         }
-        return getRecordSize();
     }
 
     protected int getDataSize() {
-        return 16 + (getNumDbcells() * 4);
+        return 16 // 4 ints
+               + getNumDbcells() * 4;
     }
     
-    /** Returns the size of an INdexRecord when it needs to index the specified number of blocks
-      *
-      */
-     public static int getRecordSizeForBlockCount(int blockCount) {
-       return 20 + (4 * blockCount);
-     }  
-
-    public short getSid()
-    {
+    /** 
+     * @return the size of an INdexRecord when it needs to index the specified number of blocks
+     */
+    public static int getRecordSizeForBlockCount(int blockCount) {
+        return 20 + 4 * blockCount;
+    }  
+
+    public short getSid() {
         return sid;
     }
 
     public Object clone() {
       IndexRecord rec = new IndexRecord();
-      rec.field_1_zero = field_1_zero;
       rec.field_2_first_row = field_2_first_row;
       rec.field_3_last_row_add1 = field_3_last_row_add1;
       rec.field_4_zero = field_4_zero;
diff --git a/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java b/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
deleted file mode 100644 (file)
index 36aeb7b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record;
-
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.util.LittleEndian;
-
-/**
- * Not implemented yet. May commit it anyway just so people can see
- * where I'm heading.
- *
- * @author Glen Stampoultzis (glens at apache.org)
- */
-public final class LinkedDataFormulaField {
-    private Ptg[] formulaTokens;
-
-    public int getSize()
-    {
-        return 2 + Ptg.getEncodedSize(formulaTokens);
-    }
-
-    public int fillField( RecordInputStream in )
-    {
-        int tokenSize = in.readUShort();
-        formulaTokens = Ptg.readTokens(tokenSize, in);
-        return tokenSize + 2;
-    }
-
-    public void toString( StringBuffer buffer )
-    {
-        for ( int k = 0; k < formulaTokens.length; k++ )
-        {
-               Ptg ptg = formulaTokens[k];
-            buffer.append( "Formula " )
-                    .append( k )
-                    .append( "=" )
-                    .append(ptg.toString() )
-                    .append( "\n" )
-                    .append(ptg.toString())
-                    .append( "\n" );
-        }
-    }
-
-    public String toString()
-    {
-        StringBuffer b = new StringBuffer();
-        toString( b );
-        return b.toString();
-    }
-
-    public int serializeField( int offset, byte[] data )
-    {
-        int size = getSize();
-        LittleEndian.putUShort(data, offset, size - 2);
-        int pos = offset + 2;
-        pos += Ptg.serializePtgs(formulaTokens, data, pos);
-        return size;
-    }
-
-    public void setFormulaTokens(Ptg[] ptgs)
-    {
-        this.formulaTokens = (Ptg[])ptgs.clone();
-    }
-
-    public Ptg[] getFormulaTokens()
-    {
-        return (Ptg[])this.formulaTokens.clone();
-    }
-
-       public LinkedDataFormulaField copy() {
-               LinkedDataFormulaField result = new LinkedDataFormulaField();
-               
-               result.formulaTokens = getFormulaTokens();
-               return result;
-       }
-}
index fe5b9002c726fdac9a35d96d7fe63879a73d12b1..75b6caab55a8cdac3b7e7cdad6e4ccb8affdd43f 100644 (file)
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.Formula;
 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;
 
 /**
- * Describes a linked data record.  This record referes to the series data or text.<p/>
+ * Describes a linked data record.  This record refers to the series data or text.<p/>
  * 
  * @author Glen Stampoultzis (glens at apache.org)
  */
-public final class LinkedDataRecord extends Record {
+public final class LinkedDataRecord extends StandardRecord {
     public final static short sid  = 0x1051;
 
     private static final BitField customNumberFormat= BitFieldFactory.getInstance(0x1);
@@ -44,7 +46,7 @@ public final class LinkedDataRecord extends Record {
     public final static byte        REFERENCE_TYPE_ERROR_REPORTED  = 4;
     private  short      field_3_options;
     private  short      field_4_indexNumberFmtRecord;
-    private  LinkedDataFormulaField field_5_formulaOfLink;
+    private  Formula field_5_formulaOfLink;
 
 
     public LinkedDataRecord()
@@ -58,8 +60,8 @@ public final class LinkedDataRecord extends Record {
         field_2_referenceType          = in.readByte();
         field_3_options                = in.readShort();
         field_4_indexNumberFmtRecord   = in.readShort();
-        field_5_formulaOfLink = new LinkedDataFormulaField();
-        field_5_formulaOfLink.fillField(in);
+        int encodedTokenLen = in.readUShort();
+               field_5_formulaOfLink = Formula.read(encodedTokenLen, in);
     }
 
     public String toString()
@@ -92,28 +94,19 @@ public final class LinkedDataRecord extends Record {
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte[] data)
-    {
-        int pos = 0;
-
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
-
-        data[ 4 + offset + pos ] = field_1_linkType;
-        data[ 5 + offset + pos ] = field_2_referenceType;
-        LittleEndian.putShort(data, 6 + offset + pos, field_3_options);
-        LittleEndian.putShort(data, 8 + offset + pos, field_4_indexNumberFmtRecord);
-        pos += field_5_formulaOfLink.serializeField( pos + 10 + offset, data );
-
-        return getRecordSize();
+    public void serialize(LittleEndianOutput out) {
+       out.writeByte(field_1_linkType);
+       out.writeByte(field_2_referenceType);
+       out.writeShort(field_3_options);
+       out.writeShort(field_4_indexNumberFmtRecord);
+        field_5_formulaOfLink.serialize(out);
     }
 
     protected int getDataSize() {
-        return 1 + 1 + 2 + 2 + field_5_formulaOfLink.getSize();
+        return 1 + 1 + 2 + 2 + field_5_formulaOfLink.getEncodedSize();
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
@@ -224,17 +217,16 @@ public final class LinkedDataRecord extends Record {
     /**
      * Get the formula of link field for the LinkedData record.
      */
-    public LinkedDataFormulaField getFormulaOfLink()
-    {
-        return field_5_formulaOfLink;
+    public Ptg[] getFormulaOfLink() {
+        return field_5_formulaOfLink.getTokens();
     }
 
     /**
      * Set the formula of link field for the LinkedData record.
      */
-    public void setFormulaOfLink(LinkedDataFormulaField field_5_formulaOfLink)
+    public void setFormulaOfLink(Ptg[] ptgs)
     {
-        this.field_5_formulaOfLink = field_5_formulaOfLink;
+        this.field_5_formulaOfLink = Formula.create(ptgs);
     }
 
     /**
index 5ecce79aa89681b9a43e8ce79b2dcb2eea54e102..c8a1379dcd1be9a053945e7cffb70645b211513b 100644 (file)
@@ -19,18 +19,15 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
  * Title: Merged Cells Record (0x00E5)
  * <br/>
- * Description:  Optional record defining a square area of cells to "merged" into
- *               one cell. <br>
- * REFERENCE:  NONE (UNDOCUMENTED PRESENTLY) <br>
+ * Description:  Optional record defining a square area of cells to "merged" into one cell. <br>
  * @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();
index 6ecaa20f9742967f9594ef655c1c927666f5721a..009148ea338f07e24fd64dc0116bfb64f87aa8ba 100644 (file)
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.util.LittleEndianOutput;
+
 /**
  * Title:        Multiple Blank cell record(0x00BE) <P/>
  * 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() {
index dbb41c10f0a5dfa09db0db1f58de9f56b417af24..3c1390d07ec2042166a81567b2f620096dfc5c1f 100644 (file)
@@ -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) <p/>
@@ -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() {
index a3717f40e000fb9e25ad48d9c8b2437590158e7b..d0f6e2af0bd3b92ecdd90fdbd2f1e4f0b048dfbe 100644 (file)
@@ -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;
 
 /**
  * <p>Record that contains the functionality page breaks (horizontal and vertical)</p>
@@ -36,11 +36,11 @@ import org.apache.poi.util.LittleEndian;
  * @see VerticalPageBreakRecord
  * @author Danny Mui (dmui at apache dot org)
  */
-public abstract class PageBreakRecord extends Record {
+public abstract class PageBreakRecord extends StandardRecord {
     private static final int[] EMPTY_INT_ARRAY = { };
 
-    private List _breaks;
-    private Map _breakMap;
+    private List<Break> _breaks;
+    private Map<Integer, Break> _breakMap;
 
     /**
      * Since both records store 2byte integers (short), no point in
@@ -49,7 +49,7 @@ public abstract class PageBreakRecord extends Record {
      * The subs (rows or columns, don't seem to be able to set but excel sets
      * them automatically)
      */
-    public class Break {
+    public static final class Break {
 
         public static final int ENCODED_SIZE = 6;
         public int main;
@@ -69,24 +69,23 @@ public abstract class PageBreakRecord extends Record {
             subTo = in.readUShort();
         }
 
-        public int serialize(int offset, byte[] data) {
-            LittleEndian.putUShort(data, offset + 0, main + 1);
-            LittleEndian.putUShort(data, offset + 2, subFrom);
-            LittleEndian.putUShort(data, offset + 4, subTo);
-            return ENCODED_SIZE;
+        public void serialize(LittleEndianOutput out) {
+            out.writeShort(main + 1);
+            out.writeShort(subFrom);
+            out.writeShort(subTo);
         }
     }
 
     protected PageBreakRecord() {
-        _breaks = new ArrayList();
-        _breakMap = new HashMap();
+        _breaks = new ArrayList<Break>();
+        _breakMap = new HashMap<Integer, Break>();
     }
 
     public PageBreakRecord(RecordInputStream in)
     {
         int nBreaks = in.readShort();
-        _breaks = new ArrayList(nBreaks + 2);
-        _breakMap = new HashMap();
+        _breaks = new ArrayList<Break>(nBreaks + 2);
+        _breakMap = new HashMap<Integer, Break>();
 
         for(int k = 0; k < nBreaks; k++) {
             Break br = new Break(in);
@@ -103,34 +102,25 @@ public abstract class PageBreakRecord extends Record {
         return 2 + _breaks.size() * Break.ENCODED_SIZE;
     }
 
-    public final int serialize(int offset, byte data[]) {
+    public final void serialize(LittleEndianOutput out) {
         int nBreaks = _breaks.size();
-        int dataSize = getDataSize();
-        LittleEndian.putUShort(data, offset + 0, getSid());
-        LittleEndian.putUShort(data, offset + 2, dataSize);
-        LittleEndian.putUShort(data, offset + 4, nBreaks);
-        int pos = 6;
+        out.writeShort(nBreaks);
         for (int i=0; i<nBreaks; i++) {
-            Break br = (Break)_breaks.get(i);
-            pos += br.serialize(offset+pos, data);
+            _breaks.get(i).serialize(out);
         }
-
-        return 4 + dataSize;
     }
 
     public int getNumBreaks() {
         return _breaks.size();
     }
 
-    public final Iterator getBreaksIterator() {
+    public final Iterator<Break> getBreaksIterator() {
         return _breaks.iterator();
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer retval = new StringBuffer();
 
-
         String label;
         String mainLabel;
         String subLabel;
@@ -148,10 +138,10 @@ public abstract class PageBreakRecord extends Record {
         retval.append("["+label+"]").append("\n");
         retval.append("     .sid        =").append(getSid()).append("\n");
         retval.append("     .numbreaks =").append(getNumBreaks()).append("\n");
-        Iterator iterator = getBreaksIterator();
+        Iterator<Break> iterator = getBreaksIterator();
         for(int k = 0; k < getNumBreaks(); k++)
         {
-            Break region = (Break)iterator.next();
+            Break region = iterator.next();
 
             retval.append("     .").append(mainLabel).append(" (zero-based) =").append(region.main).append("\n");
             retval.append("     .").append(subLabel).append("From    =").append(region.subFrom).append("\n");
@@ -171,7 +161,7 @@ public abstract class PageBreakRecord extends Record {
     public void addBreak(int main, int subFrom, int subTo) {
 
         Integer key = new Integer(main);
-        Break region = (Break)_breakMap.get(key);
+        Break region = _breakMap.get(key);
         if(region == null) {
             region = new Break(main, subFrom, subTo);
             _breakMap.put(key, region);
@@ -189,7 +179,7 @@ public abstract class PageBreakRecord extends Record {
      */
     public final void removeBreak(int main) {
         Integer rowKey = new Integer(main);
-        Break region = (Break)_breakMap.get(rowKey);
+        Break region = _breakMap.get(rowKey);
         _breaks.remove(region);
         _breakMap.remove(rowKey);
     }
@@ -201,7 +191,7 @@ public abstract class PageBreakRecord extends Record {
      */
     public final Break getBreak(int main) {
         Integer rowKey = new Integer(main);
-        return (Break)_breakMap.get(rowKey);
+        return _breakMap.get(rowKey);
     }
 
     public final int[] getBreaks() {
@@ -211,7 +201,7 @@ public abstract class PageBreakRecord extends Record {
         }
         int[] result = new int[count];
         for (int i=0; i<count; i++) {
-            Break breakItem = (Break)_breaks.get(i);
+            Break breakItem = _breaks.get(i);
             result[i] = breakItem.main;
         }
         return result;
index 75a13f6ad3897ebea3fa99541223c847f34af0ae..a58eea67d46b3233dbfae14f8b3084a7ebc9850e 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 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;
 
 /**
- * PaletteRecord - Supports custom palettes.
+ * PaletteRecord (0x0092) - Supports custom palettes.
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Brian Sanders (bsanders at risklabs dot com) - custom palette editing
- * @version 2.0-pre
+ *
  */
-
-public class PaletteRecord
-    extends Record
-{
-    public final static short sid = 0x92;
+public final class PaletteRecord extends StandardRecord {
+    public final static short sid = 0x0092;
     /** The standard size of an XLS palette */
     public final static byte STANDARD_PALETTE_SIZE = (byte) 56;
     /** The byte index of the first color */
     public final static short FIRST_COLOR_INDEX = (short) 0x8;
     
-    private short field_1_numcolors;
-    private List  field_2_colors;
+    private List<PColor>  field_2_colors;
 
     public PaletteRecord()
     {
-      createDefaultPalette();
+      PColor[] defaultPalette = createDefaultPalette();
+      field_2_colors    = new ArrayList<PColor>(defaultPalette.length);
+      for (int i = 0; i < defaultPalette.length; i++) {
+        field_2_colors.add(defaultPalette[i]);
+      }
     }
 
     public PaletteRecord(RecordInputStream in)
     {
-       field_1_numcolors = in.readShort();
-       field_2_colors    = new ArrayList(field_1_numcolors);
+       int field_1_numcolors = in.readShort();
+       field_2_colors    = new ArrayList<PColor>(field_1_numcolors);
        for (int k = 0; k < field_1_numcolors; k++) {
-           field_2_colors.add(new PColor(
-                                         in.readByte(),
-                                         in.readByte(),
-                                         in.readByte()
-                                        )
-                              );
-           //Read unused byte.
-           in.readByte();
+           field_2_colors.add(new PColor(in));
        } 
     }
 
@@ -69,35 +60,27 @@ public class PaletteRecord
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[PALETTE]\n");
-        buffer.append("  numcolors     = ").append(field_1_numcolors)
-              .append('\n');
-        for (int k = 0; k < field_1_numcolors; k++) {
-        PColor c = (PColor) field_2_colors.get(k);
-        buffer.append("* colornum      = ").append(k)
-              .append('\n');
-        buffer.append(c.toString());
-        buffer.append("/*colornum      = ").append(k)
-              .append('\n');
+        buffer.append("  numcolors     = ").append(field_2_colors.size()).append('\n');
+        for (int i = 0; i < field_2_colors.size(); i++) {
+            PColor c = field_2_colors.get(i);
+            buffer.append("* colornum      = ").append(i).append('\n');
+            buffer.append(c.toString());
+            buffer.append("/*colornum      = ").append(i).append('\n');
         }
         buffer.append("[/PALETTE]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
+    public void serialize(LittleEndianOutput out)
     {
-        LittleEndian.putShort(data, 0 + offset, sid);
-        LittleEndian.putShort(data, 2 + offset, (short) (getRecordSize() - 4));
-        LittleEndian.putShort(data, 4 + offset, field_1_numcolors);
-        for (int k = 0; k < field_1_numcolors; k++) {
-          PColor c = (PColor)field_2_colors.get(k);
-          c.serialize(data, (6+offset+(k*4)));
+        out.writeShort(field_2_colors.size());
+        for (int i = 0; i < field_2_colors.size(); i++) {
+          field_2_colors.get(i).serialize(out);
         }
-
-        return getRecordSize();
     }
 
     protected int getDataSize() {
-        return 2 + (field_1_numcolors * 4);
+        return 2 + field_2_colors.size() * PColor.ENCODED_SIZE;
     }
 
     public short getSid()
@@ -108,17 +91,16 @@ public class PaletteRecord
     /**
      * Returns the color value at a given index
      *
-     * @return the RGB triplet for the color, or null if the specified index
+     * @return the RGB triplet for the color, or <code>null</code> 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 PColor(RecordInputStream in) {
+    red=in.readByte();
+    green=in.readByte();
+    blue=in.readByte();
+    in.readByte(); // unused
   }
 
-  public void serialize(byte[] data, int offset) {
-     data[offset + 0] = red;
-     data[offset + 1] = green;
-     data[offset + 2] = blue;
-     data[offset + 3] = 0;
+  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
index 48a8c564f5d94c028aa3303834e40a724187af36..966aaf219cc9653ff07e4a7cd402bdcc29649e1b 100644 (file)
@@ -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)<p/>
  * 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).<P>
- * We support this in READ-ONLY mode.  HSSF converts these to NUMBER records<P>
+ *               cycles on this then leave on of those "valuable" records out).<p/>
+ * We support this in READ-ONLY mode.  HSSF converts these to NUMBER records<p/>
  *
  *
  *
@@ -36,7 +37,7 @@ import org.apache.poi.util.HexDump;
  * @author Jason Height (jheight at chariot dot net dot au)
  * @see org.apache.poi.hssf.record.NumberRecord
  */
-public final class RKRecord extends Record implements CellValueRecordInterface {
+public final class RKRecord extends StandardRecord implements CellValueRecordInterface {
     public final static short sid                      = 0x027E;
     public final static short RK_IEEE_NUMBER           = 0;
     public final static short RK_IEEE_NUMBER_TIMES_100 = 1;
@@ -47,7 +48,7 @@ public final class RKRecord extends Record implements CellValueRecordInterface {
     private int field_3_xf_index;
     private int field_4_rk_number;
 
-    public RKRecord()
+    private RKRecord()
     {
     }
 
@@ -133,7 +134,7 @@ public final class RKRecord extends Record implements CellValueRecordInterface {
         return sb.toString();
     }
 
-       public int serialize(int offset, byte [] data) {
+       public void serialize(LittleEndianOutput out) {
                throw new RecordFormatException( "Sorry, you can't serialize RK in this release");
        }
        protected int getDataSize() {
index d66e31089b1e8750abf25e6ccdf9b80eb455c396..00efceb6a7aba88c8fc2ba3bd5b76450e5b4e08d 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title: Recalc Id Record<P>
+ * Title: Recalc Id Record (0x01C1)<p/>
  * Description:  This record contains an ID that marks when a worksheet was last
  *               recalculated. It's an optimization Excel uses to determine if it
  *               needs to  recalculate the spreadsheet when it's opened. So far, only
@@ -28,100 +29,51 @@ import org.apache.poi.util.LittleEndian;
  *               (do not recalculate) and <code>0xC1 0x01 0x00 0x00 0x60 0x69 0x01
  *               0x00</code> have been seen. If the field <code>isNeeded</code> is
  *               set to false (default), then this record is swallowed during the
- *               serialization process<P>
- * REFERENCE:  http://chicago.sourceforge.net/devel/docs/excel/biff8.html<P>
+ *               serialization process<p/>
+ * REFERENCE:  http://chicago.sourceforge.net/devel/docs/excel/biff8.html<p/>
  * @author Luc Girardin (luc dot girardin at macrofocus dot com)
- * @version 2.0-pre
+ *
  * @see org.apache.poi.hssf.model.Workbook
  */
-
-public final class RecalcIdRecord extends Record {
-    public final static short sid = 0x1c1;
-    public short[]            field_1_recalcids;
-
-    private boolean isNeeded = true;
-
-    public RecalcIdRecord()
-    {
-    }
-
-    public RecalcIdRecord(RecordInputStream in)
-    {
-        field_1_recalcids = new short[ in.remaining() / 2 ];
-        for (int k = 0; k < field_1_recalcids.length; k++)
-        {
-            field_1_recalcids[ k ] = in.readShort();
-        }
-    }
-
-    /**
-     * set the recalc array.
-     * @param array of recalc id's
-     */
-
-    public void setRecalcIdArray(short [] array)
-    {
-        field_1_recalcids = array;
-    }
-
-    /**
-     * get the recalc array.
-     * @return array of recalc id's
-     */
-
-    public short [] getRecalcIdArray()
-    {
-        return field_1_recalcids;
-    }
-
-    public void setIsNeeded(boolean isNeeded) {
-        this.isNeeded = isNeeded;
+public final class RecalcIdRecord extends StandardRecord {
+    public final static short sid = 0x01C1;
+    private final int _reserved0;
+    private final int _engineId;
+
+    public RecalcIdRecord(RecordInputStream in) {
+       int rt = in.readUShort();
+       if (rt != sid) {
+               throw new RecordFormatException("expected " + sid + " but got " + rt);
+       }
+       _reserved0 = in.readUShort();
+       _engineId = in.readInt();
     }
 
     public boolean isNeeded() {
-        return isNeeded;
+        return true;
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[RECALCID]\n");
-        buffer.append("    .elements        = ").append(field_1_recalcids.length)
-            .append("\n");
-        for (int k = 0; k < field_1_recalcids.length; k++)
-        {
-            buffer.append("    .element_" + k + "       = ")
-                .append(field_1_recalcids[ k ]).append("\n");
-        }
+        buffer.append("    .reserved = ").append(HexDump.shortToHex(_reserved0));
+        buffer.append("    .engineId = ").append(HexDump.intToHex(_engineId));
         buffer.append("[/RECALCID]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        short[] tabids     = getRecalcIdArray();
-        short   length     = ( short ) (tabids.length * 2);
-        int     byteoffset = 4;
-
-        LittleEndian.putUShort(data, 0 + offset, sid);
-        LittleEndian.putUShort(data, 2 + offset, length);
-
-        // 2 (num bytes in a short)
-        for (int k = 0; k < (length / 2); k++)
-        {
-            LittleEndian.putShort(data, byteoffset + offset, tabids[ k ]);
-            byteoffset += 2;
-        }
-        return getRecordSize();
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(sid);
+        out.writeShort(_reserved0);
+        out.writeInt(_engineId);
     }
 
     protected int getDataSize() {
-        return (getRecalcIdArray().length * 2);
+        return 8;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 }
index 2898c8d142aef8654c66bba309f7edce6ed3172d..2a74992687a1d20b23350b83472244386d1f5511 100644 (file)
@@ -18,7 +18,9 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.hssf.util.CellRangeAddress8Bit;
+import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
  * Title:        Selection Record (0x001D)<P>
@@ -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();
-
-        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();
+        StringBuffer sb = new StringBuffer();
+
+        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() {
index a6ebefd255b4ba4bba2cfa636657a4fb834975eb..c8edda2aa5a46264d9052f8e8580a44f2a9405e7 100644 (file)
 
 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.<br/>
- * 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());
     }
 
     /**
index 9994dfcf77c90ca364a94406d56b550480de7ed5..f9541d59393d0f5b9364fae206f19951ad48f581 100644 (file)
@@ -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;
        }
 }
index 9478d008bf2957255e953c91e9bcab29320936a6..7c6803d4ea502655e201f88cc469d6f52f747ccd 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title: Sheet Tab Index Array Record<P>
+ * Title: Sheet Tab Index Array Record (0x013D)<p/>
  * Description:  Contains an array of sheet id's.  Sheets always keep their ID
- *               regardless of what their name is.<P>
- * REFERENCE:  PG 412 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ *               regardless of what their name is.<p/>
+ * REFERENCE:  PG 412 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
+ *
  */
-public final class TabIdRecord extends Record {
+public final class TabIdRecord extends StandardRecord {
     public final static short sid = 0x13d;
-    public short[]            field_1_tabids;
+       private static final short[] EMPTY_SHORT_ARRAY = { };
+       
+    public short[] _tabids;
 
-    public TabIdRecord()
-    {
+    public TabIdRecord() {
+       _tabids = EMPTY_SHORT_ARRAY;
     }
 
-    public TabIdRecord(RecordInputStream in)
-    {
-        field_1_tabids = new short[ in.remaining() / 2 ];
-        for (int k = 0; k < field_1_tabids.length; k++)
-        {
-            field_1_tabids[ k ] = in.readShort();
+    public TabIdRecord(RecordInputStream in) {
+       int nTabs = in.remaining() / 2;
+        _tabids = new short[nTabs];
+        for (int k = 0; k < _tabids.length; k++) {
+            _tabids[ k ] = in.readShort();
         }
     }
 
@@ -48,62 +49,36 @@ public final class TabIdRecord extends Record {
      * set the tab array.  (0,1,2).
      * @param array of tab id's {0,1,2}
      */
-
-    public void setTabIdArray(short [] array)
-    {
-        field_1_tabids = array;
+    public void setTabIdArray(short[] array) {
+        _tabids = array;
     }
 
-    /**
-     * get the tab array.  (0,1,2).
-     * @return array of tab id's {0,1,2}
-     */
-
-    public short [] getTabIdArray()
-    {
-        return field_1_tabids;
-    }
-
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[TABID]\n");
-        buffer.append("    .elements        = ").append(field_1_tabids.length)
-            .append("\n");
-        for (int k = 0; k < field_1_tabids.length; k++)
+        buffer.append("    .elements        = ").append(_tabids.length).append("\n");
+        for (int k = 0; k < _tabids.length; k++)
         {
-            buffer.append("    .element_" + k + "       = ")
-                .append(field_1_tabids[ k ]).append("\n");
+            buffer.append("    .element_").append(k).append(" = ").append(_tabids[ k ]).append("\n");
         }
         buffer.append("[/TABID]\n");
         return buffer.toString();
     }
 
-    public int serialize(int offset, byte [] data)
-    {
-        short[] tabids = getTabIdArray();
-        int length = tabids.length * 2;
-        int byteoffset = 4;
+    public void serialize(LittleEndianOutput out) {
+        short[] tabids = _tabids;
 
-        LittleEndian.putUShort(data, 0 + offset, sid);
-        LittleEndian.putUShort(data, 2 + offset, length);   // nubmer tabids *
-
-        // 2 (num bytes in a short)
-        for (int k = 0; k < (length / 2); k++)
-        {
-            LittleEndian.putShort(data, byteoffset + offset, tabids[ k ]);
-            byteoffset += 2;
+        for (int k = 0; k < tabids.length; k++) {
+            out.writeShort(tabids[ k ]);
         }
-        return getRecordSize();
     }
 
     protected int getDataSize() {
-        return (getTabIdArray().length * 2);
+        return _tabids.length * 2;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 }
index 6bbb0966379df43b9b174dc7332204b2c77da3b0..997c35642b8749690bef31c0571026cbfd843089 100644 (file)
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title:        Unknown Record (for debugging)<P>
+ * Title:        Unknown Record (for debugging)<p/>
  * Description:  Unknown record just tells you the sid so you can figure out
  *               what records you are missing.  Also helps us read/modify sheets we
- *               don't know all the records to.  (HSSF leaves these alone!) <P>
+ *               don't know all the records to.  (HSSF leaves these alone!) <p/>
  * Company:      SuperLink Software, Inc.<P>
  * @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;
        }
 }
index 5870a9ace4f816b501845dbcc6b8708f0df94d79..3ff094e7f6d23a23896e62970da5a3ce688c9d46 100644 (file)
@@ -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() {
index c4d1565970275b9e830c6b5af4a4a0348f9d4757..68d4559a369085084d64ce37aa450bb6f6ef18b7 100644 (file)
@@ -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<PageBreakRecord.Break> iterator = breaks.getBreaksIterator();
+               List<PageBreakRecord.Break> shiftedBreak = new ArrayList<PageBreakRecord.Break>();
                while(iterator.hasNext())
                {
-                       PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
+                       PageBreakRecord.Break breakItem = iterator.next();
                        int breakLocation = breakItem.main;
                        boolean inStart = (breakLocation >= start);
                        boolean inEnd = (breakLocation <= stop);
@@ -433,7 +411,7 @@ public final class PageSettingsBlock extends RecordAggregate {
 
                iterator = shiftedBreak.iterator();
                while (iterator.hasNext()) {
-                       PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next();
+                       PageBreakRecord.Break breakItem = iterator.next();
                        breaks.removeBreak(breakItem.main);
                        breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo);
                }
index 0d57edbc439a366f2a730e1144787c9a474f4241..075e3ae5d23dc123a5bab0607e91a0733c6586b3 100644 (file)
@@ -250,7 +250,7 @@ public final class RowRecordsAggregate extends RecordAggregate {
             // Serialize a block of cells for those rows
             final int startRowNumber = getStartRowNumberForBlock(blockIndex);
             final int endRowNumber = getEndRowNumberForBlock(blockIndex);
-            DBCellRecord cellRecord = new DBCellRecord();
+            DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder();
             // Note: Cell references start from the second row...
             int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE);
             for (int row = startRowNumber; row <= endRowNumber; row++) {
@@ -261,13 +261,12 @@ public final class RowRecordsAggregate extends RecordAggregate {
                     pos += rowCellSize;
                     // Add the offset to the first cell for the row into the
                     // DBCellRecord.
-                    cellRecord.addCellOffset((short) cellRefOffset);
+                    dbcrBuilder.addCellOffset(cellRefOffset);
                     cellRefOffset = rowCellSize;
                 }
             }
             // Calculate Offset from the start of a DBCellRecord to the first Row
-            cellRecord.setRowOffset(pos);
-            rv.visitRecord(cellRecord);
+            rv.visitRecord(dbcrBuilder.build(pos));
         }
         for (int i=0; i< _unknownRecords.size(); i++) {
             // Potentially breaking the file here since we don't know exactly where to write these records
index a2dbd4d919bc9ca1aa137d98b8452cb2d03f16e8..d3215120703f319f0256469fc447182c4d82a351 100644 (file)
@@ -1015,9 +1015,7 @@ public class HSSFCellStyle implements CellStyle
        if(workbook != source.workbook) {
                        // Then we need to clone the format string,
                        //  and update the format record for this
-               short fmt = workbook.createFormat(
-                               source.getDataFormatString()
-               );
+               short fmt = (short)workbook.createFormat(source.getDataFormatString() );
                setDataFormat(fmt);
                        
                        // Finally we need to clone the font,
index 2141c74f08064baa6a6ecb62395ed214ae0212d7..310abecefeb9f85d421cabef0e3591bb2914e13c 100644 (file)
    limitations under the License.
 ==================================================================== */
 
-
-/*
- * HSSFFont.java
- *
- * Created on December 9, 2001, 10:34 AM
- */
 package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.record.FontRecord;
@@ -29,16 +23,13 @@ import org.apache.poi.ss.usermodel.Font;
 /**
  * Represents a Font used in a workbook.
  *
- * @version 1.0-pre
+ *
  * @author  Andrew C. Oliver
  * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createFont()
  * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getFontAt(short)
  * @see org.apache.poi.hssf.usermodel.HSSFCellStyle#setFont(HSSFFont)
  */
-
-public class HSSFFont implements Font
-{
-
+public final class HSSFFont implements Font {
 
     private FontRecord         font;
     private short              index;
@@ -60,7 +51,6 @@ public class HSSFFont implements Font
     public void setFontName(String name)
     {
         font.setFontName(name);
-        font.setFontNameLength(( byte ) name.length());
     }
 
     /**
index 422af62c7f2874e88fa8fdcc18e25176f0f6925a..4f10ba8c9fbab683e9a1e098f6632219bbe880a0 100644 (file)
@@ -86,7 +86,6 @@ public class HSSFFooter extends HeaderFooter implements Footer {
                               "&C" + (center == null ? "" : center) +
                               "&L" + (left == null ? "" : left) +
                               "&R" + (right == null ? "" : right));
-       footerRecord.setFooterLength((byte)footerRecord.getFooter().length());
     }
 }
 
index c5247525a17a98ffbe64891a49209c1d96910037..36dfc969b049b05a5e73a7c9d7184e324967e180 100644 (file)
@@ -92,7 +92,6 @@ public class HSSFHeader extends HeaderFooter implements Header {
         headerRecord.setHeader( "&C" + ( center == null ? "" : center ) +
                 "&L" + ( left == null ? "" : left ) +
                 "&R" + ( right == null ? "" : right ) );
-        headerRecord.setHeaderLength( (byte) headerRecord.getHeader().length() );
     }
 
 }
index 3b1fd1e1e700ad54ca6afc31e9d4cec868bdb986..c0a1daaeb111357800a824fc9171f6189d454bbb 100644 (file)
@@ -47,12 +47,12 @@ import org.apache.poi.hssf.record.HCenterRecord;
 import org.apache.poi.hssf.record.HeaderRecord;
 import org.apache.poi.hssf.record.LegendRecord;
 import org.apache.poi.hssf.record.LineFormatRecord;
-import org.apache.poi.hssf.record.LinkedDataFormulaField;
 import org.apache.poi.hssf.record.LinkedDataRecord;
 import org.apache.poi.hssf.record.PlotAreaRecord;
 import org.apache.poi.hssf.record.PlotGrowthRecord;
 import org.apache.poi.hssf.record.PrintSetupRecord;
 import org.apache.poi.hssf.record.ProtectRecord;
+import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordBase;
 import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.SeriesIndexRecord;
@@ -96,12 +96,12 @@ public final class HSSFChart {
        public void createBarChart( HSSFWorkbook workbook, HSSFSheet sheet )
        {
 
-               List records = new ArrayList();
+               List<Record> records = new ArrayList<Record>();
                records.add( createMSDrawingObjectRecord() );
                records.add( createOBJRecord() );
                records.add( createBOFRecord() );
-               records.add( createHeaderRecord() );
-               records.add( createFooterRecord() );
+               records.add(new HeaderRecord(""));
+               records.add(new FooterRecord(""));
                records.add( createHCenterRecord() );
                records.add( createVCenterRecord() );
                records.add( createPrintSetupRecord() );
@@ -340,20 +340,6 @@ public final class HSSFChart {
                return r;
        }
 
-       private FooterRecord createFooterRecord()
-       {
-               FooterRecord r = new FooterRecord();
-               r.setFooter(null);
-               return r;
-       }
-
-       private HeaderRecord createHeaderRecord()
-       {
-               HeaderRecord r = new HeaderRecord();
-               r.setHeader(null);
-               return r;
-       }
-
        private BOFRecord createBOFRecord()
        {
                BOFRecord r = new BOFRecord();
@@ -447,7 +433,7 @@ public final class HSSFChart {
                r.setReferenceType(LinkedDataRecord.REFERENCE_TYPE_DIRECT);
                r.setCustomNumberFormat(false);
                r.setIndexNumberFmtRecord((short)0);
-               r.setFormulaOfLink( new LinkedDataFormulaField() );
+               r.setFormulaOfLink(null);
                return r;
        }
 
@@ -647,7 +633,7 @@ public final class HSSFChart {
                r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
                r.setCustomNumberFormat( false );
                r.setIndexNumberFmtRecord( (short) 0 );
-               r.setFormulaOfLink( new LinkedDataFormulaField() );
+               r.setFormulaOfLink(null);
                return r;
        }
 
@@ -758,11 +744,9 @@ public final class HSSFChart {
                r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
                r.setCustomNumberFormat( false );
                r.setIndexNumberFmtRecord( (short) 0 );
-               LinkedDataFormulaField formula = new LinkedDataFormulaField();
                Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
                        false, false, false, false, 0);
-               formula.setFormulaTokens(new Ptg[] { p, });
-               r.setFormulaOfLink( formula );
+               r.setFormulaOfLink(new Ptg[] { p, });
                return r;
        }
 
@@ -773,11 +757,9 @@ public final class HSSFChart {
                r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
                r.setCustomNumberFormat( false );
                r.setIndexNumberFmtRecord( (short) 0 );
-               LinkedDataFormulaField formula = new LinkedDataFormulaField();
                Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
                                false, false, false, false, 0);
-               formula.setFormulaTokens(new Ptg[] { p, });
-               r.setFormulaOfLink( formula );
+               r.setFormulaOfLink(new Ptg[] { p, });
                return r;
        }
 
@@ -788,7 +770,7 @@ public final class HSSFChart {
                r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
                r.setCustomNumberFormat( false );
                r.setIndexNumberFmtRecord( (short) 0 );
-               r.setFormulaOfLink( new LinkedDataFormulaField() );
+               r.setFormulaOfLink(null);
                return r;
        }
 
index 5a8855b66ea144bec5c1d9121592f0719dc3d097..3d5e053daa460693cf5c0592a3dae54e22e4a7ad 100644 (file)
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 package org.apache.poi.hssf.record;
 
 
 import junit.framework.TestCase;
 
 /**
- * Tests the serialization and deserialization of the FontRecord
- * class works correctly.  Test data taken directly from a real
- * Excel file.
+ * Tests the serialization and deserialization of the {@link FontRecord}
+ * class works correctly.  Test data taken directly from a real Excel file.
  */
 public final class TestFontRecord extends TestCase {
-       byte[] header = new byte[] {
-               0x31, 00, 0x1a, 00, // sid=31, 26 bytes long
-       };
-    byte[] data = new byte[] {
-               0xC8-256, 00,       // font height = xc8
-               00, 00,             // attrs = 0 
-               0xFF-256, 0x7F,     // colour palette = x7fff 
-               0x90-256, 0x01,     // bold weight = x190
-               00, 00,  // supersubscript
-               00, 00,  // underline, family
-               00, 00,  // charset, padding
-               05, 01,  // name length, unicode flag
-               0x41, 0x00, 0x72, 0x00, 0x69, // Arial, as unicode 
-               0x00, 0x61, 0x00, 0x6C, 0x00
+
+    private static final byte[] data = {
+            0xC8-256, 00,       // font height = xc8
+            00, 00,             // attrs = 0
+            0xFF-256, 0x7F,     // colour palette = x7fff
+            0x90-256, 0x01,     // bold weight = x190
+            00, 00,  // supersubscript
+            00, 00,  // underline, family
+            00, 00,  // charset, padding
+            05, 00,  // name length, unicode flag
+            0x41, 0x72, 0x69, 0x61, 0x6C, // Arial, as unicode
+
     };
 
     public void testLoad() {
 
         FontRecord record = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
-        assertEquals( 0xc8, record.getFontHeight());
-        assertEquals( 0x00, record.getAttributes());
-        assertFalse( record.isItalic());
-        assertFalse( record.isStruckout());
-        assertFalse( record.isMacoutlined());
-        assertFalse( record.isMacshadowed());
-        assertEquals( 0x7fff, record.getColorPaletteIndex());
-        assertEquals( 0x190, record.getBoldWeight());
-        assertEquals( 0x00, record.getSuperSubScript());
-        assertEquals( 0x00, record.getUnderline());
-        assertEquals( 0x00, record.getFamily());
-        assertEquals( 0x00, record.getCharset());
-        assertEquals( 0x05, record.getFontNameLength());
-        assertEquals( "Arial", record.getFontName());
-
-
-        assertEquals( 26 + 4, record.getRecordSize() );
+        assertEquals(0xc8, record.getFontHeight());
+        assertEquals(0x00, record.getAttributes());
+        assertFalse(record.isItalic());
+        assertFalse(record.isStruckout());
+        assertFalse(record.isMacoutlined());
+        assertFalse(record.isMacshadowed());
+        assertEquals(0x7fff, record.getColorPaletteIndex());
+        assertEquals(0x190, record.getBoldWeight());
+        assertEquals(0x00, record.getSuperSubScript());
+        assertEquals(0x00, record.getUnderline());
+        assertEquals(0x00, record.getFamily());
+        assertEquals(0x00, record.getCharset());
+        assertEquals("Arial", record.getFontName());
+
+        assertEquals(21 + 4, record.getRecordSize());
     }
 
-    public void testStore()
-    {
+    public void testStore() {
 //      .fontheight      = c8
 //      .attributes      = 0
 //           .italic     = false
@@ -90,7 +84,6 @@ public final class TestFontRecord extends TestCase {
         record.setUnderline((byte)0);
         record.setFamily((byte)0);
         record.setCharset((byte)0);
-        record.setFontNameLength((byte)5);
         record.setFontName("Arial");
 
         byte [] recordBytes = record.serialize();
@@ -98,10 +91,10 @@ public final class TestFontRecord extends TestCase {
         for (int i = 0; i < data.length; i++)
             assertEquals("At offset " + i, data[i], recordBytes[i+4]);
     }
-    
-    public void testCloneOnto() throws Exception {
+
+    public void testCloneOnto() {
         FontRecord base = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
-       
+
         FontRecord other = new FontRecord();
         other.cloneStyleFrom(base);
 
@@ -110,18 +103,18 @@ public final class TestFontRecord extends TestCase {
         for (int i = 0; i < data.length; i++)
             assertEquals("At offset " + i, data[i], recordBytes[i+4]);
     }
-    
+
     public void testSameProperties() throws Exception {
         FontRecord f1 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
         FontRecord f2 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
-       
+
         assertTrue(f1.sameProperties(f2));
-        
+
         f2.setFontName("Arial2");
         assertFalse(f1.sameProperties(f2));
         f2.setFontName("Arial");
         assertTrue(f1.sameProperties(f2));
-        
+
         f2.setFontHeight((short)11);
         assertFalse(f1.sameProperties(f2));
         f2.setFontHeight((short)0xc8);
index adca938147d37106b808591012a3e50c1ecf3776..6f6e8cc1317b5791d3895aafebc5b5a8ed3921fa 100644 (file)
@@ -167,7 +167,7 @@ recordid = 0x1051, size =8
         Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
                 false, false, false, false, 0);
         
-        Object ptgActual = record.getFormulaOfLink().getFormulaTokens()[0];
+        Ptg ptgActual = record.getFormulaOfLink()[0];
         assertEquals(ptgExpected.toString(),  ptgActual.toString());
 
         assertEquals( data.length + 4, record.getRecordSize() );
@@ -182,9 +182,7 @@ recordid = 0x1051, size =8
         record.setIndexNumberFmtRecord( (short)0 );
         Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
                        false, false, false, false, 0);
-        LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();
-        formulaOfLink.setFormulaTokens(new Ptg[] { ptg, });
-        record.setFormulaOfLink(formulaOfLink );
+        record.setFormulaOfLink(new Ptg[] { ptg, } );
 
         byte [] recordBytes = record.serialize();
         assertEquals(recordBytes.length - 4, data.length);