<!-- Don't forget to update status.xml too! -->
<release version="3.5-beta4" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">46189 - added chart records: CHARTFRTINFO, STARTBLOCK, ENDBLOCK, STARTOBJECT, ENDOBJECT, and CATLAB</action>
<action dev="POI-DEVELOPERS" type="fix">46199 - More tweaks to EmbeddedObjectRefSubRecord</header>
<action dev="POI-DEVELOPERS" type="add">Changes to formula evaluation allowing for reduced memory usage</action>
<action dev="POI-DEVELOPERS" type="fix">45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list</header>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.5-beta4" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">46189 - added chart records: CHARTFRTINFO, STARTBLOCK, ENDBLOCK, STARTOBJECT, ENDOBJECT, and CATLAB</action>
<action dev="POI-DEVELOPERS" type="fix">46199 - More tweaks to EmbeddedObjectRefSubRecord</header>
<action dev="POI-DEVELOPERS" type="add">Changes to formula evaluation allowing for reduced memory usage</action>
<action dev="POI-DEVELOPERS" type="fix">45290 - Support odd files where the POIFS header block comes after the data blocks, and is on the data blocks list</header>
import java.util.Map;
import java.util.Set;
+import org.apache.poi.hssf.record.chart.*;
+
/**
* Title: Record Factory<P>
* Description: Takes a stream and outputs an array of Record objects.<P>
WriteAccessRecord.class,
WriteProtectRecord.class,
WSBoolRecord.class,
+
+ LinkedDataRecord.class,
+
+ ChartFRTInfoRecord.class,
+ ChartStartBlockRecord.class,
+ ChartEndBlockRecord.class,
+ ChartStartObjectRecord.class,
+ ChartEndObjectRecord.class,
+ CatLabRecord.class,
+
+ BeginRecord.class,
+ EndRecord.class,
+ SeriesToChartGroupRecord.class,
};
/**
--- /dev/null
+/* ====================================================================\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.LittleEndianByteArrayOutputStream;\r
+import org.apache.poi.util.LittleEndianOutput;\r
+\r
+/**\r
+ * Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for\r
+ * some simplification of serialization logic\r
+ * \r
+ * @author Josh Micich\r
+ */\r
+public abstract class StandardRecord extends Record {\r
+ @Override\r
+ public final int serialize(int offset, byte[] data) {\r
+ int dataSize = getDataSize();\r
+ int recSize = 4 + dataSize;\r
+ LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);\r
+ out.writeShort(getSid());\r
+ out.writeShort(dataSize);\r
+ serialize(out);\r
+ if (out.getWriteIndex() - offset != recSize) {\r
+ throw new IllegalStateException("Incorrect number of bytes written - expected " \r
+ + recSize + " but got " + (out.getWriteIndex() - offset));\r
+ }\r
+ return recSize;\r
+ }\r
+\r
+ /**\r
+ * Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields\r
+ * have already been written by the superclass.<br/>\r
+ * \r
+ * The subclass must write the exact number of bytes as reported by {@link Record#getDataSize()}\r
+ */\r
+ protected abstract void serialize(LittleEndianOutput out);\r
+}\r
case 0x0803: return "DBQUERYEXT";
case 0x0805: return "TXTQUERY";
+ case 0x0812: return "CONTINUEFRT";
case QUICKTIP_0800: return "QUICKTIP";
- case 0x0850: return "CHARTFRTINFO";
- case 0x0852: return "STARTBLOCK";
- case 0x0853: return "ENDBLOCK";
- case 0x0856: return "CATLAB";
case SHEETEXT_0862: return "SHEETEXT";
case 0x0863: return "BOOKEXT";
case SHEETPROTECTION_0867: return "SHEETPROTECTION";
case 0x087B: return "CFEX";
case 0x087C: return "XFCRC";
case 0x087D: return "XFEXT";
+ case 0x087F: return "CONTINUEFRT12";
case 0x088B: return "PLV";
case 0x088C: return "COMPAT12";
case 0x088D: return "DXF";
case 0x089A: return "MTRSETTINGS";
case 0x089B: return "COMPRESSPICTURES";
case 0x089C: return "HEADERFOOTER";
+ case 0x08A1: return "SHAPEPROPSSTREAM";
case 0x08A3: return "FORCEFULLCALCULATION";
case 0x08A4: return "SHAPEPROPSSTREAM";
case 0x08A5: return "TEXTPROPSSTREAM";
case 0x08C8: return "PLV{Mac Excel}";
- case 0x1051: return "SHAPEPROPSSTREAM";
}
if (isObservedButUnknown(sid)) {
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * CATLAB - Category Labels (0x0856)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class CatLabRecord extends StandardRecord {
+ public static final short sid = 0x0856;
+
+ private short rt;
+ private short grbitFrt;
+ private short wOffset;
+ private short at;
+ private short grbit;
+ private short unused;
+
+ public CatLabRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ wOffset = in.readShort();
+ at = in.readShort();
+ grbit = in.readShort();
+ unused = in.readShort();
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 2 + 2 + 2 + 2;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeShort(wOffset);
+ out.writeShort(at);
+ out.writeShort(grbit);
+ out.writeShort(unused);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[CATLAB]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt=").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .wOffset =").append(HexDump.shortToHex(wOffset)).append('\n');
+ buffer.append(" .at =").append(HexDump.shortToHex(at)).append('\n');
+ buffer.append(" .grbit =").append(HexDump.shortToHex(grbit)).append('\n');
+ buffer.append(" .unused =").append(HexDump.shortToHex(unused)).append('\n');
+
+ buffer.append("[/CATLAB]\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * ENDBLOCK - Chart Future Record Type End Block (0x0853)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class ChartEndBlockRecord extends StandardRecord {
+ public static final short sid = 0x0853;
+
+ private short rt;
+ private short grbitFrt;
+ private short iObjectKind;
+ private byte[] unused;
+
+ public ChartEndBlockRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ iObjectKind = in.readShort();
+
+ unused = new byte[6];
+ in.readFully(unused);
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 2 + 6;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeShort(iObjectKind);
+ // 6 bytes unused
+ out.write(unused);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[ENDBLOCK]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .iObjectKind=").append(HexDump.shortToHex(iObjectKind)).append('\n');
+ buffer.append(" .unused =").append(HexDump.toHex(unused)).append('\n');
+ buffer.append("[/ENDBLOCK]\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * ENDOBJECT - Chart Future Record Type End Object (0x0855)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class ChartEndObjectRecord extends StandardRecord {
+ public static final short sid = 0x0855;
+
+ private short rt;
+ private short grbitFrt;
+ private short iObjectKind;
+ private byte[] unused;
+
+ public ChartEndObjectRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ iObjectKind = in.readShort();
+
+ unused = new byte[6];
+ in.readFully(unused);
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 2 + 6;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeShort(iObjectKind);
+ // 6 bytes unused
+ out.write(unused);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[ENDOBJECT]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .iObjectKind=").append(HexDump.shortToHex(iObjectKind)).append('\n');
+ buffer.append(" .unused =").append(HexDump.toHex(unused)).append('\n');
+ buffer.append("[/ENDOBJECT]\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * CHARTFRTINFO - Chart Future Record Type Info (0x0850)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class ChartFRTInfoRecord extends StandardRecord {
+ public static final short sid = 0x850;
+
+ private short rt;
+ private short grbitFrt;
+ private byte verOriginator;
+ private byte verWriter;
+ private CFRTID[] rgCFRTID;
+
+ private static final class CFRTID {
+ public static final int ENCODED_SIZE = 4;
+ private int rtFirst;
+ private int rtLast;
+
+ public CFRTID(RecordInputStream in) {
+ rtFirst = in.readShort();
+ rtLast = in.readShort();
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(rtFirst);
+ out.writeShort(rtLast);
+ }
+ }
+
+ public ChartFRTInfoRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ verOriginator = in.readByte();
+ verWriter = in.readByte();
+ int cCFRTID = in.readShort();
+
+ rgCFRTID = new CFRTID[cCFRTID];
+ for (int i = 0; i < cCFRTID; i++) {
+ rgCFRTID[i] = new CFRTID(in);
+ }
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 1 + 1 + 2 + rgCFRTID.length * CFRTID.ENCODED_SIZE;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeByte(verOriginator);
+ out.writeByte(verWriter);
+ int nCFRTIDs = rgCFRTID.length;
+ out.writeShort(nCFRTIDs);
+
+ for (int i = 0; i < nCFRTIDs; i++) {
+ rgCFRTID[i].serialize(out);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[CHARTFRTINFO]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .verOriginator=").append(HexDump.byteToHex(verOriginator)).append('\n');
+ buffer.append(" .verWriter =").append(HexDump.byteToHex(verOriginator)).append('\n');
+ buffer.append(" .nCFRTIDs =").append(HexDump.shortToHex(rgCFRTID.length)).append('\n');
+ buffer.append("[/CHARTFRTINFO]\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * STARTBLOCK - Chart Future Record Type Start Block (0x0852)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class ChartStartBlockRecord extends StandardRecord {
+ public static final short sid = 0x0852;
+
+ private short rt;
+ private short grbitFrt;
+ private short iObjectKind;
+ private short iObjectContext;
+ private short iObjectInstance1;
+ private short iObjectInstance2;
+
+ public ChartStartBlockRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ iObjectKind = in.readShort();
+ iObjectContext = in.readShort();
+ iObjectInstance1 = in.readShort();
+ iObjectInstance2 = in.readShort();
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 2 + 2 + 2 + 2;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeShort(iObjectKind);
+ out.writeShort(iObjectContext);
+ out.writeShort(iObjectInstance1);
+ out.writeShort(iObjectInstance2);
+ }
+
+ public String toString() {
+
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[STARTBLOCK]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .iObjectKind =").append(HexDump.shortToHex(iObjectKind)).append('\n');
+ buffer.append(" .iObjectContext =").append(HexDump.shortToHex(iObjectContext)).append('\n');
+ buffer.append(" .iObjectInstance1=").append(HexDump.shortToHex(iObjectInstance1)).append('\n');
+ buffer.append(" .iObjectInstance2=").append(HexDump.shortToHex(iObjectInstance2)).append('\n');
+ buffer.append("[/STARTBLOCK]\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ 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 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;
+
+/**
+ * STARTOBJECT - Chart Future Record Type Start Object (0x0854)<br/>
+ *
+ * @author Patrick Cheng
+ */
+public final class ChartStartObjectRecord extends StandardRecord {
+ public static final short sid = 0x0854;
+
+ private short rt;
+ private short grbitFrt;
+ private short iObjectKind;
+ private short iObjectContext;
+ private short iObjectInstance1;
+ private short iObjectInstance2;
+
+ public ChartStartObjectRecord(RecordInputStream in) {
+ rt = in.readShort();
+ grbitFrt = in.readShort();
+ iObjectKind = in.readShort();
+ iObjectContext = in.readShort();
+ iObjectInstance1 = in.readShort();
+ iObjectInstance2 = in.readShort();
+ }
+
+ @Override
+ protected int getDataSize() {
+ return 2 + 2 + 2 + 2 + 2 + 2;
+ }
+
+ @Override
+ public short getSid() {
+ return sid;
+ }
+
+ @Override
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(rt);
+ out.writeShort(grbitFrt);
+ out.writeShort(iObjectKind);
+ out.writeShort(iObjectContext);
+ out.writeShort(iObjectInstance1);
+ out.writeShort(iObjectInstance2);
+ }
+
+ public String toString() {
+
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[STARTOBJECT]\n");
+ buffer.append(" .rt =").append(HexDump.shortToHex(rt)).append('\n');
+ buffer.append(" .grbitFrt =").append(HexDump.shortToHex(grbitFrt)).append('\n');
+ buffer.append(" .iObjectKind =").append(HexDump.shortToHex(iObjectKind)).append('\n');
+ buffer.append(" .iObjectContext =").append(HexDump.shortToHex(iObjectContext)).append('\n');
+ buffer.append(" .iObjectInstance1=").append(HexDump.shortToHex(iObjectInstance1)).append('\n');
+ buffer.append(" .iObjectInstance2=").append(HexDump.shortToHex(iObjectInstance2)).append('\n');
+ buffer.append("[/STARTOBJECT]\n");
+ return buffer.toString();
+ }
+}