public String field_5_ole_classname; // Classname of the embedded OLE document (e.g. Word.Document.8)
public int field_6_stream_id; // ID of the OLE stream containing the actual data.
+ private int field_5_ole_classname_padding; // developer laziness...
+ public byte[] remainingBytes;
+
public EmbeddedObjectRefSubRecord()
{
+ field_2_unknown = new short[0];
+ remainingBytes = new byte[0];
+ field_1_stream_id_offset = 6;
+ field_5_ole_classname = "";
}
/**
// Padded with NUL bytes. The -2 is because field_1_stream_id_offset
// is relative to after the offset field, whereas in.getRecordOffset()
- // is relative to the start of this record.
+ // is relative to the start of this record (minus the header.)
+ field_5_ole_classname_padding = 0;
while (in.getRecordOffset() - 2 < field_1_stream_id_offset)
{
+ field_5_ole_classname_padding++;
in.readByte(); // discard
}
field_6_stream_id = in.readInt();
+ remainingBytes = in.readRemainder();
}
public int serialize(int offset, byte[] data)
{
int pos = offset;
+ LittleEndian.putShort(data, pos, sid); pos += 2;
+ LittleEndian.putShort(data, pos, (short)(getRecordSize() - 4)); pos += 2;
+
LittleEndian.putShort(data, pos, field_1_stream_id_offset); pos += 2;
LittleEndian.putShortArray(data, pos, field_2_unknown); pos += field_2_unknown.length * 2 + 2;
LittleEndian.putShort(data, pos, field_3_unicode_len); pos += 2;
StringUtil.putCompressedUnicode( field_5_ole_classname, data, pos ); pos += field_5_ole_classname.length();
}
- // Padded with NUL bytes.
- pos = field_1_stream_id_offset;
-
+ // Padded with the same number of NUL bytes as were originally skipped.
+ // XXX: This is only accurate until we make the classname mutable.
+ pos += field_5_ole_classname_padding;
+
LittleEndian.putInt(data, pos, field_6_stream_id); pos += 4;
+ System.arraycopy(remainingBytes, 0, data, pos, remainingBytes.length);
+
return getRecordSize();
}
*/
public int getRecordSize()
{
- // Conveniently this stores the length of all the crap before the final int value.
- return field_1_stream_id_offset + 4;
+ // The stream id offset is relative to after the stream ID.
+ // Add 2 bytes for the stream id offset and 4 bytes for the stream id itself and 4 byts for the record header.
+ return remainingBytes.length + field_1_stream_id_offset + 2 + 4 + 4;
}
/**
.append(System.getProperty("line.separator"));
buffer.append(" .unknown = ")
.append("0x").append(HexDump.toHex( field_2_unknown ))
- .append(" (").append( field_2_unknown ).append(" )")
+ .append(" (").append( field_2_unknown.length ).append(" )")
.append(System.getProperty("line.separator"));
buffer.append(" .unicodeLen = ")
.append("0x").append(HexDump.toHex( field_3_unicode_len ))
--- /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
+package org.apache.poi.hssf.record;\r
+\r
+import junit.framework.TestCase;\r
+import org.apache.poi.util.HexRead;\r
+\r
+import java.io.IOException;\r
+import java.io.ByteArrayInputStream;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * Tests the serialization and deserialization of the TestEmbeddedObjectRefSubRecord\r
+ * class works correctly. Test data taken directly from a real\r
+ * Excel file.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestEmbeddedObjectRefSubRecord extends TestCase {\r
+\r
+ String data1 = "[20, 00, 05, 00, FC, 10, 76, 01, 02, 24, 14, DF, 00, 03, 10, 00, 00, 46, 6F, 72, 6D, 73, 2E, 43, 68, 65, 63, 6B, 42, 6F, 78, 2E, 31, 00, 00, 00, 00, 00, 70, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, ]";\r
+\r
+ public void testStore() throws IOException {\r
+\r
+ byte[] src = HexRead.readFromString(data1);\r
+ src = TestcaseRecordInputStream.mergeDataAndSid(EmbeddedObjectRefSubRecord.sid, (short)src.length, src);\r
+\r
+ RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(src));\r
+ in.nextRecord();\r
+\r
+ EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in);\r
+\r
+ byte[] ser = record1.serialize();\r
+\r
+ RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));\r
+ in2.nextRecord();\r
+ EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);\r
+\r
+ assertTrue(Arrays.equals(src, ser));\r
+ assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);\r
+ assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));\r
+ assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);\r
+ assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);\r
+ assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);\r
+ assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);\r
+ assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));\r
+ }\r
+\r
+ public void testCreate() throws IOException {\r
+\r
+\r
+ EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord();\r
+\r
+ byte[] ser = record1.serialize();\r
+ RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));\r
+ in2.nextRecord();\r
+ EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);\r
+\r
+ assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);\r
+ assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));\r
+ assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);\r
+ assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);\r
+ assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);\r
+ assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);\r
+ assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));\r
+\r
+ }\r
+}\r