diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index 120656ca9..793448a3c 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -37,6 +37,7 @@
+ 46693 - Fixed bugs serialization bugs in records: CHARTFORMAT, SHTPROPS, SXVD and SXVDEX
46627 - Fixed offset of added images if Pictures stream contains pictures with zero length
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index f8b6fb674..126a0876b 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -34,6 +34,7 @@
+ 46693 - Fixed bugs serialization bugs in records: CHARTFORMAT, SHTPROPS, SXVD and SXVDEX
46627 - Fixed offset of added images if Pictures stream contains pictures with zero length
diff --git a/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java b/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java
index de17e4612..d7bc8750a 100644
--- a/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java
+++ b/src/java/org/apache/poi/hssf/record/chart/ChartFormatRecord.java
@@ -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)
*
+ * (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);
}
}
diff --git a/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java b/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java
index 639a96027..4299e887d 100644
--- a/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java
+++ b/src/java/org/apache/poi/hssf/record/chart/ChartRecord.java
@@ -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)
+ *
+ * The chart record is used to define the location and size of a chart.
+ *
+ * Chart related records don't seem to be covered in either the
+ * OOO
+ * or the
+ * MS
+ * 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
+ * blog
+ * 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();
+ public String toString() {
+ StringBuffer sb = 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();
+ 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;
}
}
diff --git a/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java b/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java
index 779ae05af..b67559f19 100644
--- a/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java
+++ b/src/java/org/apache/poi/hssf/record/chart/SeriesListRecord.java
@@ -22,12 +22,12 @@ import org.apache.poi.hssf.record.StandardRecord;
import org.apache.poi.util.LittleEndianOutput;
/**
- * SERIESLIST (0x1016)
+ * SERIESLIST (0x1016)
*
* The series list record defines the series displayed as an overlay to the main chart record.
- * 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;
- }
}
-
-
-
diff --git a/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java b/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java
index 7ca006354..eae23a432 100644
--- a/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java
+++ b/src/java/org/apache/poi/hssf/record/chart/SheetPropertiesRecord.java
@@ -25,8 +25,11 @@ import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
- * Describes a chart sheet properties record.
+ * Describes a chart sheet properties record. SHTPROPS (0x1044)
*
+ * (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);
}
}
diff --git a/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java b/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
index 82cae7ac6..92911a1f2 100644
--- a/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
+++ b/src/java/org/apache/poi/hssf/record/pivottable/ExtendedPivotTableViewFieldsRecord.java
@@ -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 cchSubName 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();
}
diff --git a/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java b/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java
index 9e477ac84..de73f8447 100644
--- a/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java
+++ b/src/java/org/apache/poi/hssf/record/pivottable/ViewFieldsRecord.java
@@ -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 cchName field when the name is not present */
- private static final int STRING_NOT_PRESENT_LEN = -1;
+ /** the value of the cchName 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();
diff --git a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
index db6c7ff3f..3458051ee 100755
--- a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
+++ b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
@@ -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 org.apache.poi.hssf.record 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);
diff --git a/src/testcases/org/apache/poi/hssf/record/chart/AllChartRecordTests.java b/src/testcases/org/apache/poi/hssf/record/chart/AllChartRecordTests.java
index 1714e91c0..d2fcf2bd0 100644
--- a/src/testcases/org/apache/poi/hssf/record/chart/AllChartRecordTests.java
+++ b/src/testcases/org/apache/poi/hssf/record/chart/AllChartRecordTests.java
@@ -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
index 000000000..52b25057d
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/chart/TestChartFormatRecord.java
@@ -0,0 +1,61 @@
+/* ====================================================================
+ 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.chart;
+
+import java.util.Arrays;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.util.HexRead;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link ChartFormatRecord} Test data taken directly from a real
+ * Excel file.
+ *
+ * @author Josh Micich
+ */
+public final class TestChartFormatRecord extends TestCase {
+ /**
+ * This rather uninteresting data came from attachment 23347 of bug 46693 at
+ * offsets 0x6BB2 and 0x7BAF
+ */
+ private static final byte[] data = HexRead.readFromString(
+ "14 10 14 00 " // BIFF header
+ + "00 00 00 00 00 00 00 00 "
+ + "00 00 00 00 00 00 00 00 "
+ + "00 00 00 00");
+
+ /**
+ * The correct size of a {@link ChartFormatRecord} is 20 bytes (not including header).
+ */
+ public void testLoad() {
+ RecordInputStream in = TestcaseRecordInputStream.create(data);
+ ChartFormatRecord record = new ChartFormatRecord(in);
+ if (in.remaining() == 2) {
+ throw new AssertionFailedError("Identified bug 44693d");
+ }
+ assertEquals(0, in.remaining());
+ assertEquals(24, record.getRecordSize());
+
+ byte[] data2 = record.serialize();
+ assertTrue(Arrays.equals(data, data2));
+ }
+}
diff --git a/src/testcases/org/apache/poi/hssf/record/chart/TestSheetPropertiesRecord.java b/src/testcases/org/apache/poi/hssf/record/chart/TestSheetPropertiesRecord.java
index 51794029e..ba1415e4d 100644
--- a/src/testcases/org/apache/poi/hssf/record/chart/TestSheetPropertiesRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/chart/TestSheetPropertiesRecord.java
@@ -18,27 +18,32 @@
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
index 000000000..39546135a
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/pivot/AllPivotRecordTests.java
@@ -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 org.apache.poi.hssf.record.pivot.
+ *
+ * @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
index 000000000..7ba15d5c2
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/pivot/TestExtendedPivotTableViewFieldsRecord.java
@@ -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
index 000000000..448a2acb3
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/pivot/TestViewFieldsRecord.java
@@ -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;
+ }
+}