You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2007/11/23 13:51:47 UTC

svn commit: r597653 - in /poi/trunk/src: java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java

Author: yegor
Date: Fri Nov 23 04:51:44 2007
New Revision: 597653

URL: http://svn.apache.org/viewvc?rev=597653&view=rev
Log:
Preserve unread bytes when serializing the record

Added:
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java?rev=597653&r1=597652&r2=597653&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java Fri Nov 23 04:51:44 2007
@@ -43,8 +43,15 @@
     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 = "";
     }
 
     /**
@@ -93,19 +100,25 @@
 
         // 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;
@@ -120,11 +133,14 @@
             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();
     }
 
@@ -133,8 +149,9 @@
      */
     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;
     }
 
     /**
@@ -160,7 +177,7 @@
             .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 ))

Added: poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java?rev=597653&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java Fri Nov 23 04:51:44 2007
@@ -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));
+
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org