Preserve unread bytes when serializing the record
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@597653 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
52d3ba08e0
commit
9c7f6307c4
@ -43,8 +43,15 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
public String field_5_ole_classname; // Classname of the embedded OLE document (e.g. Word.Document.8)
|
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.
|
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()
|
public EmbeddedObjectRefSubRecord()
|
||||||
{
|
{
|
||||||
|
field_2_unknown = new short[0];
|
||||||
|
remainingBytes = new byte[0];
|
||||||
|
field_1_stream_id_offset = 6;
|
||||||
|
field_5_ole_classname = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,19 +100,25 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
|
|
||||||
// Padded with NUL bytes. The -2 is because field_1_stream_id_offset
|
// 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 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)
|
while (in.getRecordOffset() - 2 < field_1_stream_id_offset)
|
||||||
{
|
{
|
||||||
|
field_5_ole_classname_padding++;
|
||||||
in.readByte(); // discard
|
in.readByte(); // discard
|
||||||
}
|
}
|
||||||
|
|
||||||
field_6_stream_id = in.readInt();
|
field_6_stream_id = in.readInt();
|
||||||
|
remainingBytes = in.readRemainder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int serialize(int offset, byte[] data)
|
public int serialize(int offset, byte[] data)
|
||||||
{
|
{
|
||||||
int pos = offset;
|
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.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.putShortArray(data, pos, field_2_unknown); pos += field_2_unknown.length * 2 + 2;
|
||||||
LittleEndian.putShort(data, pos, field_3_unicode_len); pos += 2;
|
LittleEndian.putShort(data, pos, field_3_unicode_len); pos += 2;
|
||||||
@ -120,11 +133,14 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
StringUtil.putCompressedUnicode( field_5_ole_classname, data, pos ); pos += field_5_ole_classname.length();
|
StringUtil.putCompressedUnicode( field_5_ole_classname, data, pos ); pos += field_5_ole_classname.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padded with NUL bytes.
|
// Padded with the same number of NUL bytes as were originally skipped.
|
||||||
pos = field_1_stream_id_offset;
|
// 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;
|
LittleEndian.putInt(data, pos, field_6_stream_id); pos += 4;
|
||||||
|
|
||||||
|
System.arraycopy(remainingBytes, 0, data, pos, remainingBytes.length);
|
||||||
|
|
||||||
return getRecordSize();
|
return getRecordSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +149,9 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
*/
|
*/
|
||||||
public int getRecordSize()
|
public int getRecordSize()
|
||||||
{
|
{
|
||||||
// Conveniently this stores the length of all the crap before the final int value.
|
// The stream id offset is relative to after the stream ID.
|
||||||
return field_1_stream_id_offset + 4;
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,7 +177,7 @@ public class EmbeddedObjectRefSubRecord
|
|||||||
.append(System.getProperty("line.separator"));
|
.append(System.getProperty("line.separator"));
|
||||||
buffer.append(" .unknown = ")
|
buffer.append(" .unknown = ")
|
||||||
.append("0x").append(HexDump.toHex( field_2_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"));
|
.append(System.getProperty("line.separator"));
|
||||||
buffer.append(" .unicodeLen = ")
|
buffer.append(" .unicodeLen = ")
|
||||||
.append("0x").append(HexDump.toHex( field_3_unicode_len ))
|
.append("0x").append(HexDump.toHex( field_3_unicode_len ))
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.util.HexRead;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the serialization and deserialization of the TestEmbeddedObjectRefSubRecord
|
||||||
|
* class works correctly. Test data taken directly from a real
|
||||||
|
* Excel file.
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TestEmbeddedObjectRefSubRecord extends TestCase {
|
||||||
|
|
||||||
|
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, ]";
|
||||||
|
|
||||||
|
public void testStore() throws IOException {
|
||||||
|
|
||||||
|
byte[] src = HexRead.readFromString(data1);
|
||||||
|
src = TestcaseRecordInputStream.mergeDataAndSid(EmbeddedObjectRefSubRecord.sid, (short)src.length, src);
|
||||||
|
|
||||||
|
RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(src));
|
||||||
|
in.nextRecord();
|
||||||
|
|
||||||
|
EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in);
|
||||||
|
|
||||||
|
byte[] ser = record1.serialize();
|
||||||
|
|
||||||
|
RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
|
||||||
|
in2.nextRecord();
|
||||||
|
EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(src, ser));
|
||||||
|
assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);
|
||||||
|
assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));
|
||||||
|
assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);
|
||||||
|
assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);
|
||||||
|
assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);
|
||||||
|
assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);
|
||||||
|
assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreate() throws IOException {
|
||||||
|
|
||||||
|
|
||||||
|
EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord();
|
||||||
|
|
||||||
|
byte[] ser = record1.serialize();
|
||||||
|
RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
|
||||||
|
in2.nextRecord();
|
||||||
|
EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
|
||||||
|
|
||||||
|
assertEquals(record1.field_1_stream_id_offset, record2.field_1_stream_id_offset);
|
||||||
|
assertTrue(Arrays.equals(record1.field_2_unknown, record2.field_2_unknown));
|
||||||
|
assertEquals(record1.field_3_unicode_len, record2.field_3_unicode_len);
|
||||||
|
assertEquals(record1.field_4_unicode_flag, record2.field_4_unicode_flag);
|
||||||
|
assertEquals(record1.field_5_ole_classname, record2.field_5_ole_classname);
|
||||||
|
assertEquals(record1.field_6_stream_id, record2.field_6_stream_id);
|
||||||
|
assertTrue(Arrays.equals(record1.remainingBytes, record2.remainingBytes));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user