]> source.dussan.org Git - poi.git/commitdiff
Fix for bug 46693 - serialization errors in CHARTFORMAT, SHTPROPS, SXVD and SXVDEX...
authorJosh Micich <josh@apache.org>
Thu, 12 Feb 2009 02:28:43 +0000 (02:28 +0000)
committerJosh Micich <josh@apache.org>
Thu, 12 Feb 2009 02:28:43 +0000 (02:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@743601 13f79535-47bb-0310-9956-ffa450edef68

15 files changed:
src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java
src/java/org/apache/poi/hssf/record/chart/ChartRecord.java
src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java
src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java
src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java
src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
src/testcases/org/apache/poi/hssf/record/chart/AllChartRecordTests.java
src/testcases/org/apache/poi/hssf/record/chart/TestChartFormatRecord.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/chart/TestSheetPropertiesRecord.java
src/testcases/org/apache/poi/hssf/record/pivot/AllPivotRecordTests.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/pivot/TestExtendedPivotTableViewFieldsRecord.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/pivot/TestViewFieldsRecord.java [new file with mode: 0644]

index 120656ca95b433ba6ed02344051087e7821ecf5a..793448a3c7a2cdc2c4b0b52c98ab7294ab1c1910 100644 (file)
@@ -37,6 +37,7 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.5-beta6" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46693 - Fixed bugs serialization bugs in records: CHARTFORMAT, SHTPROPS, SXVD and SXVDEX</action>
            <action dev="POI-DEVELOPERS" type="fix">46627 - Fixed offset of added images if Pictures stream contains pictures with zero length</action>
         </release>
         <release version="3.5-beta5" date="2008-02-19">
index f8b6fb674d52e3624e648b9cd2e1a77d2b73e483..126a0876b9ede18195d500381eaa8998b9f1a495 100644 (file)
@@ -34,6 +34,7 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.5-beta6" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46693 - Fixed bugs serialization bugs in records: CHARTFORMAT, SHTPROPS, SXVD and SXVDEX</action>
            <action dev="POI-DEVELOPERS" type="fix">46627 - Fixed offset of added images if Pictures stream contains pictures with zero length</action>
         </release>
         <release version="3.5-beta5" date="2008-02-19">
index de17e46125eb12879962e9dc21d54766d2ef11df..d7bc8750ad3a038545a6df5202691decbc84ebd3 100644 (file)
@@ -21,14 +21,16 @@ import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Class ChartFormatRecord
+ * Class ChartFormatRecord (0x1014)<p/>
  *
+ * (As with all chart related records, documentation is lacking.
+ * See {@link ChartRecord} for more details)
  *
  * @author Glen Stampoultzis (glens at apache.org)
- * @version %I%, %G%
  */
 public final class ChartFormatRecord extends StandardRecord {
     public static final short sid = 0x1014;
@@ -36,40 +38,35 @@ public final class ChartFormatRecord extends StandardRecord {
     private static final BitField varyDisplayPattern = BitFieldFactory.getInstance(0x01);
 
     // ignored?
-    private int               field1_x_position;   // lower left
-    private int               field2_y_position;   // lower left
-    private int               field3_width;
-    private int               field4_height;
-    private short             field5_grbit;
+    private int field1_x_position; // lower left
+    private int field2_y_position; // lower left
+    private int field3_width;
+    private int field4_height;
+    private int field5_grbit;
+    private int field6_unknown;
 
-    public ChartFormatRecord()
-    {
+    public ChartFormatRecord() {
+        // fields uninitialised
     }
 
-    public ChartFormatRecord(RecordInputStream in)
-    {
+    public ChartFormatRecord(RecordInputStream in) {
         field1_x_position = in.readInt();
         field2_y_position = in.readInt();
-        field3_width      = in.readInt();
-        field4_height     = in.readInt();
-        field5_grbit      = in.readShort();
+        field3_width = in.readInt();
+        field4_height = in.readInt();
+        field5_grbit = in.readUShort();
+        field6_unknown = in.readUShort();
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[CHARTFORMAT]\n");
-        buffer.append("    .xPosition       = ").append(getXPosition())
-            .append("\n");
-        buffer.append("    .yPosition       = ").append(getYPosition())
-            .append("\n");
-        buffer.append("    .width           = ").append(getWidth())
-            .append("\n");
-        buffer.append("    .height          = ").append(getHeight())
-            .append("\n");
-        buffer.append("    .grBit           = ")
-            .append(Integer.toHexString(field5_grbit)).append("\n");
+        buffer.append("    .xPosition       = ").append(getXPosition()).append("\n");
+        buffer.append("    .yPosition       = ").append(getYPosition()).append("\n");
+        buffer.append("    .width           = ").append(getWidth()).append("\n");
+        buffer.append("    .height          = ").append(getHeight()).append("\n");
+        buffer.append("    .grBit           = ").append(HexDump.intToHex(field5_grbit)).append("\n");
         buffer.append("[/CHARTFORMAT]\n");
         return buffer.toString();
     }
@@ -80,65 +77,54 @@ public final class ChartFormatRecord extends StandardRecord {
         out.writeInt(getWidth());
         out.writeInt(getHeight());
         out.writeShort(field5_grbit);
+        out.writeShort(field6_unknown);
     }
 
     protected int getDataSize() {
-        return 18;
+        return 20; // 4 ints and 2 shorts
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
-    public int getXPosition()
-    {
+    public int getXPosition() {
         return field1_x_position;
     }
 
-    public void setXPosition(int xPosition)
-    {
-        this.field1_x_position = xPosition;
+    public void setXPosition(int xPosition) {
+        field1_x_position = xPosition;
     }
 
-    public int getYPosition()
-    {
+    public int getYPosition() {
         return field2_y_position;
     }
 
-    public void setYPosition(int yPosition)
-    {
-        this.field2_y_position = yPosition;
+    public void setYPosition(int yPosition) {
+        field2_y_position = yPosition;
     }
 
-    public int getWidth()
-    {
+    public int getWidth() {
         return field3_width;
     }
 
-    public void setWidth(int width)
-    {
-        this.field3_width = width;
+    public void setWidth(int width) {
+        field3_width = width;
     }
 
-    public int getHeight()
-    {
+    public int getHeight() {
         return field4_height;
     }
 
-    public void setHeight(int height)
-    {
-        this.field4_height = height;
+    public void setHeight(int height) {
+        field4_height = height;
     }
 
-    public boolean getVaryDisplayPattern()
-    {
+    public boolean getVaryDisplayPattern() {
         return varyDisplayPattern.isSet(field5_grbit);
     }
 
-    public void setVaryDisplayPattern(boolean value)
-    {
-        field5_grbit = varyDisplayPattern.setShortBoolean(field5_grbit,
-                value);
+    public void setVaryDisplayPattern(boolean value) {
+        field5_grbit = varyDisplayPattern.setBoolean(field5_grbit, value);
     }
 }
index 639a96027fe481933e9b43e503c990b4b6584218..4299e887d3f49119659d46c2d3494d96ae2fa7ae 100644 (file)
@@ -19,58 +19,56 @@ package org.apache.poi.hssf.record.chart;
 
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.StandardRecord;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * The chart record is used to define the location and size of a chart.
+ * CHART (0x1002) <p/>
+ * 
+ * The chart record is used to define the location and size of a chart.<p/>
+ * 
+ * Chart related records don't seem to be covered in either the 
+ * <A HREF="http://sc.openoffice.org/excelfileformat.pdf">OOO</A> 
+ *  or the  
+ * <A HREF="http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/Excel97-2007BinaryFileFormat(xls)Specification.pdf">MS</A> 
+ *  documentation. 
+ * 
+ * The book "Microsoft Excel 97 Developer's Kit" ISBN: (1-57231-498-2) seems to have an entire
+ * chapter (10) devoted to Chart records.  One  
+ * <A HREF="http://ooxmlisdefectivebydesign.blogspot.com/2008/03/bad-surprise-in-microsoft-office-binary.html">blog</A>
+ *  suggests that some documentation for these records is available in "MSDN Library, Feb 1998",
+ * but no later.
+ *  
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class ChartRecord extends StandardRecord {
-    public final static short      sid                             = 0x1002;
-    private  int        field_1_x;
-    private  int        field_2_y;
-    private  int        field_3_width;
-    private  int        field_4_height;
+    public final static short sid = 0x1002;
+    private int field_1_x;
+    private int field_2_y;
+    private int field_3_width;
+    private int field_4_height;
 
 
-    public ChartRecord()
-    {
-
+    public ChartRecord() {
+        // fields uninitialised
     }
 
-    public ChartRecord(RecordInputStream in)
-    {
-        field_1_x                      = in.readInt();
-        field_2_y                      = in.readInt();
-        field_3_width                  = in.readInt();
-        field_4_height                 = in.readInt();
+    public ChartRecord(RecordInputStream in) {
+        field_1_x = in.readInt();
+        field_2_y = in.readInt();
+        field_3_width = in.readInt();
+        field_4_height = in.readInt();
     }
 
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("[CHART]\n");
-        buffer.append("    .x                    = ")
-            .append("0x").append(HexDump.toHex(  getX ()))
-            .append(" (").append( getX() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
-        buffer.append("    .y                    = ")
-            .append("0x").append(HexDump.toHex(  getY ()))
-            .append(" (").append( getY() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
-        buffer.append("    .width                = ")
-            .append("0x").append(HexDump.toHex(  getWidth ()))
-            .append(" (").append( getWidth() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
-        buffer.append("    .height               = ")
-            .append("0x").append(HexDump.toHex(  getHeight ()))
-            .append(" (").append( getHeight() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
-
-        buffer.append("[/CHART]\n");
-        return buffer.toString();
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("[CHART]\n");
+        sb.append("    .x     = ").append(getX()).append('\n');
+        sb.append("    .y     = ").append(getY()).append('\n');
+        sb.append("    .width = ").append(getWidth()).append('\n');
+        sb.append("    .height= ").append(getHeight()).append('\n');
+        sb.append("[/CHART]\n");
+        return sb.toString();
     }
 
     public void serialize(LittleEndianOutput out) {
@@ -105,64 +103,56 @@ public final class ChartRecord extends StandardRecord {
     /**
      * Get the x field for the Chart record.
      */
-    public int getX()
-    {
+    public int getX() {
         return field_1_x;
     }
 
     /**
      * Set the x field for the Chart record.
      */
-    public void setX(int field_1_x)
-    {
-        this.field_1_x = field_1_x;
+    public void setX(int x) {
+        field_1_x = x;
     }
 
     /**
      * Get the y field for the Chart record.
      */
-    public int getY()
-    {
+    public int getY() {
         return field_2_y;
     }
 
     /**
      * Set the y field for the Chart record.
      */
-    public void setY(int field_2_y)
-    {
-        this.field_2_y = field_2_y;
+    public void setY(int y) {
+        field_2_y = y;
     }
 
     /**
      * Get the width field for the Chart record.
      */
-    public int getWidth()
-    {
+    public int getWidth() {
         return field_3_width;
     }
 
     /**
      * Set the width field for the Chart record.
      */
-    public void setWidth(int field_3_width)
-    {
-        this.field_3_width = field_3_width;
+    public void setWidth(int width) {
+        field_3_width = width;
     }
 
     /**
      * Get the height field for the Chart record.
      */
-    public int getHeight()
-    {
+    public int getHeight() {
         return field_4_height;
     }
 
     /**
      * Set the height field for the Chart record.
      */
-    public void setHeight(int field_4_height)
-    {
-        this.field_4_height = field_4_height;
+    public void setHeight(int height) {
+        field_4_height = height;
     }
 }
index 779ae05afebe89690f0d0a8f190459f383ea02b2..b67559f1940cbf1b72be5d487459074cf17f0087 100644 (file)
@@ -22,12 +22,12 @@ import org.apache.poi.hssf.record.StandardRecord;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * SERIESLIST (0x1016)
+ * SERIESLIST (0x1016)<p/>
  * 
  * The series list record defines the series displayed as an overlay to the main chart record.<br/>
- * 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
  * 
+ * (As with all chart related records, documentation is lacking.
+ * See {@link ChartRecord} for more details)
  * 
  * @author Glen Stampoultzis (glens at apache.org)
  */
@@ -73,8 +73,7 @@ public final class SeriesListRecord extends StandardRecord {
         return field_1_seriesNumbers.length * 2 + 2;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
@@ -88,14 +87,4 @@ public final class SeriesListRecord extends StandardRecord {
     public short[] getSeriesNumbers() {
         return field_1_seriesNumbers;
     }
-
-    /**
-     * Set the series numbers field for the SeriesList record.
-     */
-    public void setSeriesNumbers(short[] field_1_seriesNumbers) {
-        this.field_1_seriesNumbers = field_1_seriesNumbers;
-    }
 }
-
-
-
index 7ca006354a31dd44fdae50ad5f86f052af7fe820..eae23a4329f752c959660351592cb8ace3207783 100644 (file)
@@ -25,8 +25,11 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Describes a chart sheet properties record.<p/>
+ * Describes a chart sheet properties record. SHTPROPS (0x1044) <p/>
  * 
+ * (As with all chart related records, documentation is lacking.
+ * See {@link ChartRecord} for more details)
+ *
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class SheetPropertiesRecord extends StandardRecord {
@@ -38,42 +41,33 @@ public final class SheetPropertiesRecord extends StandardRecord {
     private static final BitField defaultPlotDimensions      = BitFieldFactory.getInstance(0x08);
     private static final BitField autoPlotArea               = BitFieldFactory.getInstance(0x10);
     
-    private  short      field_1_flags;
-    private  byte       field_2_empty;
+    private int field_1_flags;
+    private int field_2_empty;
     public final static byte        EMPTY_NOT_PLOTTED              = 0;
     public final static byte        EMPTY_ZERO                     = 1;
     public final static byte        EMPTY_INTERPOLATED             = 2;
 
 
-    public SheetPropertiesRecord()
-    {
-
+    public SheetPropertiesRecord() {
+        // fields uninitialised
     }
 
-    public SheetPropertiesRecord(RecordInputStream in)
-    {
-        field_1_flags                  = in.readShort();
-        field_2_empty                  = in.readByte();
+    public SheetPropertiesRecord(RecordInputStream in) {
+        field_1_flags = in.readUShort();
+        field_2_empty = in.readUShort();
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[SHTPROPS]\n");
-        buffer.append("    .flags                = ")
-            .append("0x").append(HexDump.toHex(  getFlags ()))
-            .append(" (").append( getFlags() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
-        buffer.append("         .chartTypeManuallyFormatted     = ").append(isChartTypeManuallyFormatted()).append('\n'); 
-        buffer.append("         .plotVisibleOnly          = ").append(isPlotVisibleOnly()).append('\n'); 
-        buffer.append("         .doNotSizeWithWindow      = ").append(isDoNotSizeWithWindow()).append('\n'); 
+        buffer.append("    .flags                = ").append(HexDump.shortToHex(field_1_flags)).append('\n');
+        buffer.append("         .chartTypeManuallyFormatted= ").append(isChartTypeManuallyFormatted()).append('\n'); 
+        buffer.append("         .plotVisibleOnly           = ").append(isPlotVisibleOnly()).append('\n'); 
+        buffer.append("         .doNotSizeWithWindow       = ").append(isDoNotSizeWithWindow()).append('\n'); 
         buffer.append("         .defaultPlotDimensions     = ").append(isDefaultPlotDimensions()).append('\n'); 
-        buffer.append("         .autoPlotArea             = ").append(isAutoPlotArea()).append('\n'); 
-        buffer.append("    .empty                = ")
-            .append("0x").append(HexDump.toHex(  getEmpty ()))
-            .append(" (").append( getEmpty() ).append(" )");
-        buffer.append(System.getProperty("line.separator")); 
+        buffer.append("         .autoPlotArea              = ").append(isAutoPlotArea()).append('\n'); 
+        buffer.append("    .empty                = ").append(HexDump.shortToHex(field_2_empty)).append('\n'); 
 
         buffer.append("[/SHTPROPS]\n");
         return buffer.toString();
@@ -81,15 +75,14 @@ public final class SheetPropertiesRecord extends StandardRecord {
 
     public void serialize(LittleEndianOutput out) {
         out.writeShort(field_1_flags);
-        out.writeByte(field_2_empty);
+        out.writeShort(field_2_empty);
     }
 
     protected int getDataSize() {
-        return 2 + 1;
+        return 2 + 2;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 
@@ -101,25 +94,13 @@ public final class SheetPropertiesRecord extends StandardRecord {
         return rec;
     }
 
-
-
-
     /**
      * Get the flags field for the SheetProperties record.
      */
-    public short getFlags()
-    {
+    public int getFlags() {
         return field_1_flags;
     }
 
-    /**
-     * Set the flags field for the SheetProperties record.
-     */
-    public void setFlags(short field_1_flags)
-    {
-        this.field_1_flags = field_1_flags;
-    }
-
     /**
      * Get the empty field for the SheetProperties record.
      *
@@ -128,40 +109,36 @@ public final class SheetPropertiesRecord extends StandardRecord {
      *        EMPTY_ZERO
      *        EMPTY_INTERPOLATED
      */
-    public byte getEmpty()
-    {
+    public int getEmpty() {
         return field_2_empty;
     }
 
     /**
      * Set the empty field for the SheetProperties record.
      *
-     * @param field_2_empty
+     * @param empty
      *        One of 
      *        EMPTY_NOT_PLOTTED
      *        EMPTY_ZERO
      *        EMPTY_INTERPOLATED
      */
-    public void setEmpty(byte field_2_empty)
-    {
-        this.field_2_empty = field_2_empty;
+    public void setEmpty(byte empty) {
+        this.field_2_empty = empty;
     }
 
     /**
      * Sets the chart type manually formatted field value.
      * Has the chart type been manually formatted?
      */
-    public void setChartTypeManuallyFormatted(boolean value)
-    {
-        field_1_flags = chartTypeManuallyFormatted.setShortBoolean(field_1_flags, value);
+    public void setChartTypeManuallyFormatted(boolean value) {
+        field_1_flags = chartTypeManuallyFormatted.setBoolean(field_1_flags, value);
     }
 
     /**
      * Has the chart type been manually formatted?
      * @return  the chart type manually formatted field value.
      */
-    public boolean isChartTypeManuallyFormatted()
-    {
+    public boolean isChartTypeManuallyFormatted() {
         return chartTypeManuallyFormatted.isSet(field_1_flags);
     }
 
@@ -169,17 +146,15 @@ public final class SheetPropertiesRecord extends StandardRecord {
      * Sets the plot visible only field value.
      * Only show visible cells on the chart.
      */
-    public void setPlotVisibleOnly(boolean value)
-    {
-        field_1_flags = plotVisibleOnly.setShortBoolean(field_1_flags, value);
+    public void setPlotVisibleOnly(boolean value) {
+        field_1_flags = plotVisibleOnly.setBoolean(field_1_flags, value);
     }
 
     /**
      * Only show visible cells on the chart.
      * @return  the plot visible only field value.
      */
-    public boolean isPlotVisibleOnly()
-    {
+    public boolean isPlotVisibleOnly() {
         return plotVisibleOnly.isSet(field_1_flags);
     }
 
@@ -187,17 +162,15 @@ public final class SheetPropertiesRecord extends StandardRecord {
      * Sets the do not size with window field value.
      * Do not size the chart when the window changes size
      */
-    public void setDoNotSizeWithWindow(boolean value)
-    {
-        field_1_flags = doNotSizeWithWindow.setShortBoolean(field_1_flags, value);
+    public void setDoNotSizeWithWindow(boolean value) {
+        field_1_flags = doNotSizeWithWindow.setBoolean(field_1_flags, value);
     }
 
     /**
      * Do not size the chart when the window changes size
      * @return  the do not size with window field value.
      */
-    public boolean isDoNotSizeWithWindow()
-    {
+    public boolean isDoNotSizeWithWindow() {
         return doNotSizeWithWindow.isSet(field_1_flags);
     }
 
@@ -205,17 +178,15 @@ public final class SheetPropertiesRecord extends StandardRecord {
      * Sets the default plot dimensions field value.
      * Indicates that the default area dimensions should be used.
      */
-    public void setDefaultPlotDimensions(boolean value)
-    {
-        field_1_flags = defaultPlotDimensions.setShortBoolean(field_1_flags, value);
+    public void setDefaultPlotDimensions(boolean value) {
+        field_1_flags = defaultPlotDimensions.setBoolean(field_1_flags, value);
     }
 
     /**
      * Indicates that the default area dimensions should be used.
      * @return  the default plot dimensions field value.
      */
-    public boolean isDefaultPlotDimensions()
-    {
+    public boolean isDefaultPlotDimensions() {
         return defaultPlotDimensions.isSet(field_1_flags);
     }
 
@@ -223,17 +194,15 @@ public final class SheetPropertiesRecord extends StandardRecord {
      * Sets the auto plot area field value.
      * ??
      */
-    public void setAutoPlotArea(boolean value)
-    {
-        field_1_flags = autoPlotArea.setShortBoolean(field_1_flags, value);
+    public void setAutoPlotArea(boolean value)  {
+        field_1_flags = autoPlotArea.setBoolean(field_1_flags, value);
     }
 
     /**
      * ??
      * @return  the auto plot area field value.
      */
-    public boolean isAutoPlotArea()
-    {
+    public boolean isAutoPlotArea() {
         return autoPlotArea.isSet(field_1_flags);
     }
 }
index 82cae7ac63573a50fb37163e3566c7483160e09b..92911a1f2b5e691afbc7616cda6338c02a426933 100644 (file)
@@ -31,61 +31,60 @@ import org.apache.poi.util.StringUtil;
 public final class ExtendedPivotTableViewFieldsRecord extends StandardRecord {
        public static final short sid = 0x0100;
 
-       /** the value of the <tt>cchSubName</tt> field when the subName is not present */
-       private static final int STRING_NOT_PRESENT_LEN = -1;
-       
-       private int grbit1;
-       private int grbit2;
-       private int citmShow;
-       private int isxdiSort;
-       private int isxdiShow;
-       private int reserved1;
-       private int reserved2;
-       private String subName;
-       
+       /** the value of the subname length when the {@link #_subName} is not present */
+       private static final int STRING_NOT_PRESENT_LEN = 0xFFFF;
+
+       private int _grbit1;
+       private int _grbit2;
+       private int _citmShow;
+       private int _isxdiSort;
+       private int _isxdiShow;
+       private int _reserved1;
+       private int _reserved2;
+       private String _subName;
+
        public ExtendedPivotTableViewFieldsRecord(RecordInputStream in) {
-               
-               grbit1 = in.readInt();
-               grbit2 = in.readUByte();
-               citmShow = in.readUByte();
-               isxdiSort = in.readUShort();
-               isxdiShow = in.readUShort();
+
+               _grbit1 = in.readInt();
+               _grbit2 = in.readUByte();
+               _citmShow = in.readUByte();
+               _isxdiSort = in.readUShort();
+               _isxdiShow = in.readUShort();
                int cchSubName = in.readUShort();
-               reserved1 = in.readInt();
-               reserved2 = in.readInt();
+               _reserved1 = in.readInt();
+               _reserved2 = in.readInt();
                if (cchSubName != STRING_NOT_PRESENT_LEN) {
-                       subName = in.readUnicodeLEString(cchSubName);
+                       _subName = in.readUnicodeLEString(cchSubName);
                }
        }
-       
+
        @Override
        protected void serialize(LittleEndianOutput out) {
-               
-               out.writeInt(grbit1);
-               out.writeByte(grbit2);
-               out.writeByte(citmShow);
-               out.writeShort(isxdiSort);
-               out.writeShort(isxdiShow);
-               
-               if (subName == null) {
+
+               out.writeInt(_grbit1);
+               out.writeByte(_grbit2);
+               out.writeByte(_citmShow);
+               out.writeShort(_isxdiSort);
+               out.writeShort(_isxdiShow);
+
+               if (_subName == null) {
                        out.writeShort(STRING_NOT_PRESENT_LEN);
                } else {
-                       out.writeShort(subName.length());
+                       out.writeShort(_subName.length());
                }
-               
-               out.writeInt(reserved1);
-               out.writeInt(reserved2);
-               if (subName != null) {
-                       StringUtil.putUnicodeLE(subName, out);
+
+               out.writeInt(_reserved1);
+               out.writeInt(_reserved2);
+               if (_subName != null) {
+                       StringUtil.putUnicodeLE(_subName, out);
                }
-               
        }
 
        @Override
        protected int getDataSize() {
                
                return 4 + 1 + 1 + 2 + 2 + 2 +  4 + 4 +
-                                       (subName == null ? 0 : (2*subName.length())); // in unicode
+                                       (_subName == null ? 0 : (2*_subName.length())); // in unicode
        }
 
        @Override
@@ -99,12 +98,12 @@ public final class ExtendedPivotTableViewFieldsRecord extends StandardRecord {
 
                buffer.append("[SXVDEX]\n");
 
-               buffer.append("    .grbit1 =").append(HexDump.intToHex(grbit1)).append("\n");
-               buffer.append("    .grbit2 =").append(HexDump.byteToHex(grbit2)).append("\n");
-               buffer.append("    .citmShow =").append(HexDump.byteToHex(citmShow)).append("\n");
-               buffer.append("    .isxdiSort =").append(HexDump.shortToHex(isxdiSort)).append("\n");
-               buffer.append("    .isxdiShow =").append(HexDump.shortToHex(isxdiShow)).append("\n");
-               buffer.append("    .subName =").append(subName).append("\n");
+               buffer.append("    .grbit1 =").append(HexDump.intToHex(_grbit1)).append("\n");
+               buffer.append("    .grbit2 =").append(HexDump.byteToHex(_grbit2)).append("\n");
+               buffer.append("    .citmShow =").append(HexDump.byteToHex(_citmShow)).append("\n");
+               buffer.append("    .isxdiSort =").append(HexDump.shortToHex(_isxdiSort)).append("\n");
+               buffer.append("    .isxdiShow =").append(HexDump.shortToHex(_isxdiShow)).append("\n");
+               buffer.append("    .subName =").append(_subName).append("\n");
                buffer.append("[/SXVDEX]\n");
                return buffer.toString();
        }
index 9e477ac8468a7bb8140cb6fb9bed18c304bc4c39..de73f8447bcb25f4ae0bb8d1bb93a14763f28b37 100644 (file)
@@ -31,18 +31,20 @@ import org.apache.poi.util.StringUtil;
 public final class ViewFieldsRecord extends StandardRecord {
        public static final short sid = 0x00B1;
 
-       /** the value of the <tt>cchName</tt> field when the name is not present */
-       private static final int STRING_NOT_PRESENT_LEN = -1;
+       /** the value of the <tt>cchName</tt> field when the {@link #_name} is not present */
+       private static final int STRING_NOT_PRESENT_LEN = 0xFFFF;
+       /** 5 shorts */
+       private static final int BASE_SIZE = 10;
 
-       private int sxaxis;
-       private int cSub;
-       private int grbitSub;
-       private int cItm;
+       private int _sxaxis;
+       private int _cSub;
+       private int _grbitSub;
+       private int _cItm;
        
-       private String name = null;
+       private String _name;
        
        /**
-        * values for the {@link ViewFieldsRecord#sxaxis} field
+        * values for the {@link ViewFieldsRecord#_sxaxis} field
         */
        private static final class Axis {
                public static final int NO_AXIS = 0;
@@ -53,27 +55,32 @@ public final class ViewFieldsRecord extends StandardRecord {
        }
 
        public ViewFieldsRecord(RecordInputStream in) {
-               sxaxis = in.readShort();
-               cSub = in.readShort();
-               grbitSub = in.readShort();
-               cItm = in.readShort();
+               _sxaxis = in.readShort();
+               _cSub = in.readShort();
+               _grbitSub = in.readShort();
+               _cItm = in.readShort();
                
-               int cchName = in.readShort();
+               int cchName = in.readUShort();
                if (cchName != STRING_NOT_PRESENT_LEN) {
-                       name = in.readCompressedUnicode(cchName);
+                       int flag = in.readByte();
+                       if ((flag & 0x01) != 0) {
+                               _name = in.readUnicodeLEString(cchName);
+                       } else {
+                               _name = in.readCompressedUnicode(cchName);
+                       }
                }
        }
        
        @Override
        protected void serialize(LittleEndianOutput out) {
                
-               out.writeShort(sxaxis);
-               out.writeShort(cSub);
-               out.writeShort(grbitSub);
-               out.writeShort(cItm);
+               out.writeShort(_sxaxis);
+               out.writeShort(_cSub);
+               out.writeShort(_grbitSub);
+               out.writeShort(_cItm);
                
-               if (name != null) {
-                       StringUtil.writeUnicodeString(out, name);
+               if (_name != null) {
+                       StringUtil.writeUnicodeString(out, _name);
                } else {
                        out.writeShort(STRING_NOT_PRESENT_LEN);
                }
@@ -81,12 +88,12 @@ public final class ViewFieldsRecord extends StandardRecord {
 
        @Override
        protected int getDataSize() {
-               
-               int cchName = 0;
-               if (name != null) {
-                       cchName = name.length();
+               if (_name == null) {
+                       return BASE_SIZE;
                }
-               return 2 +2 + 2 + 2 + 2 + cchName;
+               return BASE_SIZE 
+                       + 1 // unicode flag 
+                       + _name.length() * (StringUtil.hasMultibyte(_name) ? 2 : 1);
        }
 
        @Override
@@ -98,11 +105,11 @@ public final class ViewFieldsRecord extends StandardRecord {
        public String toString() {
                StringBuffer buffer = new StringBuffer();
                buffer.append("[SXVD]\n");
-               buffer.append("    .sxaxis    = ").append(HexDump.shortToHex(sxaxis)).append('\n');
-               buffer.append("    .cSub      = ").append(HexDump.shortToHex(cSub)).append('\n');
-               buffer.append("    .grbitSub  = ").append(HexDump.shortToHex(grbitSub)).append('\n');
-               buffer.append("    .cItm      = ").append(HexDump.shortToHex(cItm)).append('\n');
-               buffer.append("    .name      = ").append(name).append('\n');
+               buffer.append("    .sxaxis    = ").append(HexDump.shortToHex(_sxaxis)).append('\n');
+               buffer.append("    .cSub      = ").append(HexDump.shortToHex(_cSub)).append('\n');
+               buffer.append("    .grbitSub  = ").append(HexDump.shortToHex(_grbitSub)).append('\n');
+               buffer.append("    .cItm      = ").append(HexDump.shortToHex(_cItm)).append('\n');
+               buffer.append("    .name      = ").append(_name).append('\n');
                
                buffer.append("[/SXVD]\n");
                return buffer.toString();
index db6c7ff3f2a7f090aace9105fd65f1970ffab4ae..3458051ee74129e01a0ff187a78487309ee848a2 100755 (executable)
@@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.cf.TestCellRange;
 import org.apache.poi.hssf.record.chart.AllChartRecordTests;
 import org.apache.poi.hssf.record.constant.TestConstantValueParser;
 import org.apache.poi.hssf.record.formula.AllFormulaTests;
+import org.apache.poi.hssf.record.pivot.AllPivotRecordTests;
 
 /**
  * Collects all tests for package <tt>org.apache.poi.hssf.record</tt> and sub-packages.
@@ -38,6 +39,7 @@ public final class AllRecordTests {
 
                result.addTest(AllChartRecordTests.suite());
                result.addTest(AllFormulaTests.suite());
+               result.addTest(AllPivotRecordTests.suite());
                result.addTest(AllRecordAggregateTests.suite());
 
                result.addTestSuite(TestBOFRecord.class);
index 1714e91c02cfea01d0eeb83ba510ec5b73260c69..d2fcf2bd0516c169c476fdea662fdac82afe6783 100644 (file)
@@ -39,6 +39,7 @@ public final class AllChartRecordTests {
                result.addTestSuite(TestAxisUsedRecord.class);
                result.addTestSuite(TestBarRecord.class);
                result.addTestSuite(TestCategorySeriesAxisRecord.class);
+               result.addTestSuite(TestChartFormatRecord.class);
                result.addTestSuite(TestChartRecord.class);
                result.addTestSuite(TestChartTitleFormatRecord.class);
                result.addTestSuite(TestDatRecord.class);
diff --git a/src/testcases/org/apache/poi/hssf/record/chart/TestChartFormatRecord.java b/src/testcases/org/apache/poi/hssf/record/chart/TestChartFormatRecord.java
new file mode 100644 (file)
index 0000000..52b2505
--- /dev/null
@@ -0,0 +1,61 @@
+/* ====================================================================\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.chart;\r
+\r
+import java.util.Arrays;\r
+\r
+import org.apache.poi.hssf.record.RecordInputStream;\r
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;\r
+import org.apache.poi.util.HexRead;\r
+\r
+import junit.framework.AssertionFailedError;\r
+import junit.framework.TestCase;\r
+\r
+/**\r
+ * Tests for {@link ChartFormatRecord} Test data taken directly from a real\r
+ * Excel file.\r
+ * \r
+ * @author Josh Micich\r
+ */\r
+public final class TestChartFormatRecord extends TestCase {\r
+       /**\r
+        * This rather uninteresting data came from attachment 23347 of bug 46693 at\r
+        * offsets 0x6BB2 and 0x7BAF\r
+        */\r
+       private static final byte[] data = HexRead.readFromString(\r
+                       "14 10 14 00 " // BIFF header\r
+                       + "00 00 00 00 00 00 00 00 "\r
+                       + "00 00 00 00 00 00 00 00 "\r
+                       + "00 00 00 00");\r
+\r
+       /**\r
+        * The correct size of a {@link ChartFormatRecord} is 20 bytes (not including header).\r
+        */\r
+       public void testLoad() {\r
+               RecordInputStream in = TestcaseRecordInputStream.create(data);\r
+               ChartFormatRecord record = new ChartFormatRecord(in);\r
+               if (in.remaining() == 2) {\r
+                       throw new AssertionFailedError("Identified bug 44693d");\r
+               }\r
+               assertEquals(0, in.remaining());\r
+               assertEquals(24, record.getRecordSize());\r
+\r
+               byte[] data2 = record.serialize();\r
+               assertTrue(Arrays.equals(data, data2));\r
+       }\r
+}\r
index 51794029ef8881d94268b779ac2b2b8852aaa318..ba1415e4db17dcb4a6b338ea2cd7ab7dc8e04210 100644 (file)
 package org.apache.poi.hssf.record.chart;
 
 
+import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.TestcaseRecordInputStream;
 
+import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 /**
- * Tests the serialization and deserialization of the SheetPropertiesRecord
- * class works correctly.  Test data taken directly from a real
- * Excel file.
+ * Tests for {@link SheetPropertiesRecord}
+ * Test data taken directly from a real Excel file.
  *
-
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class TestSheetPropertiesRecord extends TestCase {
-    byte[] data = new byte[] {
+    private static final byte[] data = {
         (byte)0x0A,(byte)0x00,
-        (byte)0x00
-        //,(byte)0x00       // not sure where that last byte comes from
+        (byte)0x00,
+        (byte)0x00,      // not sure where that last byte comes from
     };
 
     public void testLoad() {
-        SheetPropertiesRecord record = new SheetPropertiesRecord(TestcaseRecordInputStream.create(0x1044, data));
+        RecordInputStream in = TestcaseRecordInputStream.create(0x1044, data);
+        SheetPropertiesRecord record = new SheetPropertiesRecord(in);
+        if (in.remaining() == 1) {
+            throw new AssertionFailedError("Identified bug 44693c");
+        }
+        assertEquals(0, in.remaining());
         assertEquals( 10, record.getFlags());
         assertEquals( false, record.isChartTypeManuallyFormatted() );
         assertEquals( true, record.isPlotVisibleOnly() );
@@ -47,12 +52,10 @@ public final class TestSheetPropertiesRecord extends TestCase {
         assertEquals( false, record.isAutoPlotArea() );
         assertEquals( 0, record.getEmpty());
 
-
-        assertEquals( 7, record.getRecordSize() );
+        assertEquals( 8, record.getRecordSize() );
     }
 
-    public void testStore()
-    {
+    public void testStore() {
         SheetPropertiesRecord record = new SheetPropertiesRecord();
         record.setChartTypeManuallyFormatted( false );
         record.setPlotVisibleOnly( true );
@@ -63,8 +66,6 @@ public final class TestSheetPropertiesRecord extends TestCase {
 
 
         byte [] recordBytes = record.serialize();
-        assertEquals(recordBytes.length - 4, data.length);
-        for (int i = 0; i < data.length; i++)
-            assertEquals("At offset " + i, data[i], recordBytes[i+4]);
+        TestcaseRecordInputStream.confirmRecordEncoding(SheetPropertiesRecord.sid, data, recordBytes);
     }
 }
diff --git a/src/testcases/org/apache/poi/hssf/record/pivot/AllPivotRecordTests.java b/src/testcases/org/apache/poi/hssf/record/pivot/AllPivotRecordTests.java
new file mode 100644 (file)
index 0000000..3954613
--- /dev/null
@@ -0,0 +1,36 @@
+/* ====================================================================
+   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.pivot;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Collects all tests for <tt>org.apache.poi.hssf.record.pivot</tt>.
+ * 
+ * @author Josh Micich
+ */
+public final class AllPivotRecordTests {
+       
+       public static Test suite() {
+               TestSuite result = new TestSuite(AllPivotRecordTests.class.getName());
+               
+               result.addTestSuite(TestExtendedPivotTableViewFieldsRecord.class);
+               return result;
+       }
+}
diff --git a/src/testcases/org/apache/poi/hssf/record/pivot/TestExtendedPivotTableViewFieldsRecord.java b/src/testcases/org/apache/poi/hssf/record/pivot/TestExtendedPivotTableViewFieldsRecord.java
new file mode 100644 (file)
index 0000000..7ba15d5
--- /dev/null
@@ -0,0 +1,54 @@
+/* ====================================================================
+   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.pivot;
+
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.hssf.record.pivottable.ExtendedPivotTableViewFieldsRecord;
+import org.apache.poi.util.HexRead;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link ExtendedPivotTableViewFieldsRecord}
+ * 
+ * @author Josh Micich
+ */
+public final class TestExtendedPivotTableViewFieldsRecord extends TestCase {
+       
+       public void testSubNameNotPresent_bug46693() {
+               // This data came from attachment 23347 of bug 46693 at offset 0xAA43
+               byte[] data = HexRead.readFromString(
+                               "00 01 14 00" + // BIFF header
+                               "1E 14 00 0A FF FF FF FF 00 00 FF FF 00 00 00 00 00 00 00 00");
+               RecordInputStream in = TestcaseRecordInputStream.create(data);
+               ExtendedPivotTableViewFieldsRecord rec;
+               try {
+                       rec = new ExtendedPivotTableViewFieldsRecord(in);
+               } catch (RecordFormatException e) {
+                       if (e.getMessage().equals("Expected to find a ContinueRecord in order to read remaining 65535 of 65535 chars")) {
+                               throw new AssertionFailedError("Identified bug 46693a");
+                       }
+                       throw e;
+               }
+               
+               assertEquals(data.length, rec.getRecordSize());
+       }
+}
diff --git a/src/testcases/org/apache/poi/hssf/record/pivot/TestViewFieldsRecord.java b/src/testcases/org/apache/poi/hssf/record/pivot/TestViewFieldsRecord.java
new file mode 100644 (file)
index 0000000..448a2ac
--- /dev/null
@@ -0,0 +1,64 @@
+/* ====================================================================
+   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.pivot;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.hssf.record.pivottable.ViewFieldsRecord;
+import org.apache.poi.util.HexRead;
+
+/**
+ * Tests for {@link ViewFieldsRecord}
+ * 
+ * @author Josh Micich
+ */
+public final class TestViewFieldsRecord extends TestCase {
+       
+       public void testUnicodeFlag_bug46693() {
+               byte[] data = HexRead.readFromString("01 00 01 00 01 00 04 00 05 00 00 6D 61 72 63 6F");
+               RecordInputStream in = TestcaseRecordInputStream.create(ViewFieldsRecord.sid, data);
+               ViewFieldsRecord rec = new ViewFieldsRecord(in);
+               if (in.remaining() == 1) {
+                       throw new AssertionFailedError("Identified bug 46693b");
+               }
+               assertEquals(0, in.remaining());
+               assertEquals(4+data.length, rec.getRecordSize());
+       }
+       
+       public void testSerialize() {
+               // This hex data was produced by changing the 'Custom Name' property, 
+               // available under 'Field Settings' from the 'PivotTable Field List' (Excel 2007)
+               confirmSerialize("00 00 01 00 01 00 00 00 FF FF");
+               confirmSerialize("01 00 01 00 01 00 04 00 05 00 00 6D 61 72 63 6F");
+               confirmSerialize("01 00 01 00 01 00 04 00 0A 00 01 48 00 69 00 73 00 74 00 6F 00 72 00 79 00 2D 00 82 69 81 89");
+       }
+
+       private static ViewFieldsRecord confirmSerialize(String hexDump) {
+               byte[] data = HexRead.readFromString(hexDump);
+               RecordInputStream in = TestcaseRecordInputStream.create(ViewFieldsRecord.sid, data);
+               ViewFieldsRecord rec = new ViewFieldsRecord(in);
+               assertEquals(0, in.remaining());
+               assertEquals(4+data.length, rec.getRecordSize());
+               byte[] data2 = rec.serialize();
+               TestcaseRecordInputStream.confirmRecordEncoding(ViewFieldsRecord.sid, data, data2);
+               return rec;
+       }
+}