Index: src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java =================================================================== RCS file: /home/cvspublic/jakarta-poi/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java,v --- src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java 23 Nov 2002 18:58:17 -0000 1.2 +++ src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java 26 Feb 2003 10:50:00 -0000 @@ -89,7 +89,6 @@ import org.apache.poi.hssf.record.FontRecord; import org.apache.poi.hssf.record.FooterRecord; import org.apache.poi.hssf.record.FormatRecord; -import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.GridsetRecord; import org.apache.poi.hssf.record.GutsRecord; import org.apache.poi.hssf.record.HCenterRecord; @@ -151,6 +150,7 @@ * @author Andrew C. Oliver (acoliver@apache.org) - probably to blame for the bugs (so yank his chain on the list) * @author Marc Johnson (mjohnson at apache dot org) - methods taken from RecordFactory * @author Glen Stampoultzis (glens at apache.org) - methods taken from RecordFactory + * @author Csaba Nagy (ncsaba at yahoo dot com) */ public class EventRecordFactory { @@ -289,8 +289,6 @@ * @param in the InputStream from which the records will be * obtained * - * @return an array of Records created from the InputStream - * * @exception RecordFormatException on error processing the * InputStream */ @@ -337,7 +335,9 @@ if (record != null) { - if (rectype == ContinueRecord.sid) + if (rectype == ContinueRecord.sid && + ! (last_record instanceof ContinueRecord) && // include continuation records after + ! (last_record instanceof UnknownRecord) ) // unknown records or previous continuation records { if (last_record == null) { Index: src/java/org/apache/poi/hssf/record/ContinueRecord.java =================================================================== RCS file: /home/cvspublic/jakarta-poi/src/java/org/apache/poi/hssf/record/ContinueRecord.java,v --- src/java/org/apache/poi/hssf/record/ContinueRecord.java 2 Jun 2002 07:30:40 -0000 1.3 +++ src/java/org/apache/poi/hssf/record/ContinueRecord.java 26 Feb 2003 10:50:00 -0000 @@ -65,6 +65,7 @@ * stream; content is tailored to that prior record

* @author Marc Johnson (mjohnson at apache dot org) * @author Andrew C. Oliver (acoliver at apache dot org) + * @author Csaba Nagy (ncsaba at yahoo dot com) * @version 2.0-pre */ @@ -116,17 +117,19 @@ public byte [] serialize() { byte[] retval = new byte[ field_1_data.length + 4 ]; - - LittleEndian.putShort(retval, 0, sid); - LittleEndian.putShort(retval, 2, ( short ) field_1_data.length); - System.arraycopy(field_1_data, 0, retval, 4, field_1_data.length); + serialize(0, retval); return retval; } public int serialize(int offset, byte [] data) { - throw new RecordFormatException( - "You're not supposed to serialize Continue records like this directly"); + + LittleEndian.putShort(data, offset, sid); + LittleEndian.putShort(data, offset + 2, ( short ) field_1_data.length); + System.arraycopy(field_1_data, 0, data, offset + 4, field_1_data.length); + return field_1_data.length + 4; + // throw new RecordFormatException( + // "You're not supposed to serialize Continue records like this directly"); } /** @@ -212,7 +215,7 @@ protected void fillFields(byte [] ignored_parm1, short ignored_parm2) { - + this.field_1_data = ignored_parm1; // throw new RecordFormatException("Are you crazy? Don't fill a continue record"); // do nothing } Index: src/java/org/apache/poi/hssf/record/RecordFactory.java =================================================================== RCS file: /home/cvspublic/jakarta-poi/src/java/org/apache/poi/hssf/record/RecordFactory.java,v --- src/java/org/apache/poi/hssf/record/RecordFactory.java 28 Nov 2002 19:20:36 -0000 1.13 +++ src/java/org/apache/poi/hssf/record/RecordFactory.java 26 Feb 2003 10:50:00 -0000 @@ -69,10 +69,11 @@ * Description: Takes a stream and outputs an array of Record objects.

* * @deprecated use EventRecordFactory instead - * @see org.apache.poi.hssf.record.EventRecordFactory + * @see org.apache.poi.hssf.eventmodel.EventRecordFactory * @author Andrew C. Oliver (acoliver at apache dot org) * @author Marc Johnson (mjohnson at apache dot org) * @author Glen Stampoultzis (glens at apache.org) + * @author Csaba Nagy (ncsaba at yahoo dot com) * @version 1.0-pre */ @@ -208,7 +209,9 @@ if (record != null) { - if (rectype == ContinueRecord.sid) + if (rectype == ContinueRecord.sid && + ! (last_record instanceof ContinueRecord) && // include continuation records after + ! (last_record instanceof UnknownRecord) ) // unknown records or previous continuation records { if (last_record == null) { Index: src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java =================================================================== RCS file: /home/cvspublic/jakarta-poi/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java,v --- src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java 11 Nov 2002 01:34:00 -0000 1.1 +++ src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java 26 Feb 2003 10:50:01 -0000 @@ -3,10 +3,13 @@ import java.io.ByteArrayInputStream; import java.io.EOFException; import java.util.Iterator; +import java.util.Arrays; import org.apache.poi.hssf.record.BOFRecord; import org.apache.poi.hssf.record.EOFRecord; import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.UnknownRecord; +import org.apache.poi.hssf.record.ContinueRecord; import junit.framework.TestCase; @@ -14,6 +17,7 @@ * enclosing_type describe the purpose here * * @author Andrew C. Oliver acoliver@apache.org + * @author Csaba Nagy (ncsaba at yahoo dot com) */ public class TestEventRecordFactory extends TestCase { @@ -173,4 +177,59 @@ // fail("not implemented"); } + + /** + * TEST NAME: Test Creating ContinueRecords After Unknown Records From An InputStream

+ * OBJECTIVE: Test that the RecordFactory given an InputStream + * constructs the expected records.

+ * SUCCESS: Record factory creates the expected records.

+ * FAILURE: The wrong records are created or contain the wrong values

+ * + */ + public void testContinuedUnknownRecord() + { + final byte[] data = new byte[] + { + 0, -1, 0, 0, // an unknown record with 0 length + 0x3C , 0, 3, 0, 1, 2, 3, // a continuation record with 3 bytes of data + 0x3C , 0, 1, 0, 4 // one more continuation record with 1 byte of data + }; + + final int[] recCnt = { 0 }; + final int[] offset = { 0 }; + factory.registerListener( + new ERFListener() { + private String[] expectedRecordTypes = { + UnknownRecord.class.getName(), + ContinueRecord.class.getName(), + ContinueRecord.class.getName() + }; + public boolean processRecord(Record rec) + { + // System.out.println(rec.toString()); + assertEquals( + "Record type", + expectedRecordTypes[recCnt[0]], + rec.getClass().getName() + ); + compareData(rec, "Record " + recCnt[0] + ": "); + recCnt[0]++; + return true; + } + private void compareData(Record record, String message) { + byte[] recData = record.serialize(); + for (int i = 0; i < recData.length; i++) { + assertEquals(message + " data byte " + i, data[offset[0]++], recData[i]); + } + } + }, + new short[] {-256, 0x3C} + ); + + factory.processRecords(new ByteArrayInputStream(data)); + assertEquals("nr. of processed records", 3, recCnt[0]); + assertEquals("nr. of processed bytes", data.length, offset[0]); + } + + } Index: src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java =================================================================== RCS file: /home/cvspublic/jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java,v --- src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java 11 Feb 2002 04:23:10 -0000 1.2 +++ src/testcases/org/apache/poi/hssf/record/TestRecordFactory.java 26 Feb 2003 10:50:01 -0000 @@ -55,12 +55,15 @@ package org.apache.poi.hssf.record; +import java.io.ByteArrayInputStream; + import junit.framework.TestCase; /** * Tests the record factory * @author Glen Stampoultzis (glens at apache.org) * @author Andrew C. Oliver (acoliver at apache dot org) + * @author Csaba Nagy (ncsaba at yahoo dot com) */ public class TestRecordFactory @@ -156,6 +159,47 @@ assertEquals(515, numberRecord.getSid()); assertEquals(0.0, numberRecord.getValue(), 0.001); assertEquals(21, numberRecord.getXFIndex()); + } + + /** + * TEST NAME: Test Creating ContinueRecords After Unknown Records From An InputStream

+ * OBJECTIVE: Test that the RecordFactory given an InputStream + * constructs the expected array of records.

+ * SUCCESS: Record factory creates the expected records.

+ * FAILURE: The wrong records are created or contain the wrong values

+ * + */ + public void testContinuedUnknownRecord() + { + byte[] data = new byte[] + { + 0, -1, 0, 0, // an unknown record with 0 length + 0x3C , 0, 3, 0, 1, 2, 3, // a continuation record with 3 bytes of data + 0x3C , 0, 1, 0, 4 // one more continuation record with 1 byte of data + }; + + ByteArrayInputStream bois = new ByteArrayInputStream(data); + Record[] records = (Record[]) + RecordFactory.createRecords(bois).toArray(new Record[0]); + assertEquals("Created record count", 3, records.length); + assertEquals("1st record's type", + UnknownRecord.class.getName(), + records[ 0 ].getClass().getName()); + assertEquals("1st record's sid", (short)-256, records[0].getSid()); + assertEquals("2nd record's type", + ContinueRecord.class.getName(), + records[ 1 ].getClass().getName()); + ContinueRecord record = (ContinueRecord) records[1]; + assertEquals("2nd record's sid", 0x3C, record.getSid()); + assertEquals("1st data byte", 1, record.getData()[ 0 ]); + assertEquals("2nd data byte", 2, record.getData()[ 1 ]); + assertEquals("3rd data byte", 3, record.getData()[ 2 ]); + assertEquals("3rd record's type", + ContinueRecord.class.getName(), + records[ 2 ].getClass().getName()); + record = (ContinueRecord) records[2]; + assertEquals("3nd record's sid", 0x3C, record.getSid()); + assertEquals("4th data byte", 4, record.getData()[ 0 ]); } public static void main(String [] ignored_args)