jheight 2003/09/25 01:08:05 Modified: src/java/org/apache/poi/hssf/record Tag: REL_2_BRANCH ExtSSTInfoSubRecord.java ExtSSTRecord.java SSTRecord.java SSTSerializer.java Log: ExtSST serialization pacth to fix corruption when there are a large number of strings in the SST record. It seems that only 128 buckets can be serialized. This patch addresses this excel oddity. Revision Changes Path No revision No revision 1.2.2.3 +1 -0 jakarta-poi/src/java/org/apache/poi/hssf/record/ExtSSTInfoSubRecord.java Index: ExtSSTInfoSubRecord.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/ExtSSTInfoSubRecord.java,v retrieving revision 1.2.2.2 retrieving revision 1.2.2.3 diff -u -r1.2.2.2 -r1.2.2.3 --- ExtSSTInfoSubRecord.java 23 Sep 2003 00:35:16 -0000 1.2.2.2 +++ ExtSSTInfoSubRecord.java 25 Sep 2003 08:08:05 -0000 1.2.2.3 @@ -73,6 +73,7 @@ public class ExtSSTInfoSubRecord extends Record { + public static final int INFO_SIZE = 8; public final static short sid = 0xFFF; // only here for conformance, doesn't really have an sid private int field_1_stream_pos; // stream pointer to the SST record 1.3.2.3 +20 -0 jakarta-poi/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java Index: ExtSSTRecord.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -u -r1.3.2.2 -r1.3.2.3 --- ExtSSTRecord.java 23 Sep 2003 00:35:16 -0000 1.3.2.2 +++ ExtSSTRecord.java 25 Sep 2003 08:08:05 -0000 1.3.2.3 @@ -76,6 +76,9 @@ extends Record { public static final int DEFAULT_BUCKET_SIZE = 8; + //Cant seem to find this documented but from the biffviewer it is clear that + //Excel only records the indexes for the first 128 buckets. + public static final int MAX_BUCKETS = 128; public final static short sid = 0xff; private short field_1_strings_per_bucket = DEFAULT_BUCKET_SIZE; private ArrayList field_2_sst_info; @@ -202,9 +205,26 @@ return pos; } + /** Returns the size of this record */ public int getRecordSize() { return 6 + 8*getNumInfoRecords(); + } + + public static final int getNumberOfInfoRecsForStrings(int numStrings) { + int infoRecs = (numStrings / DEFAULT_BUCKET_SIZE); + if ((numStrings % DEFAULT_BUCKET_SIZE) != 0) + infoRecs ++; + //Excel seems to max out after 128 info records. + //This isnt really documented anywhere... + if (infoRecs > MAX_BUCKETS) + infoRecs = MAX_BUCKETS; + return infoRecs; + } + + /** Given a number of strings (in the sst), returns the size of the extsst record*/ + public static final int getRecordSizeForStrings(int numStrings) { + return 4 + 2 + (getNumberOfInfoRecsForStrings(numStrings) * 8); } public short getSid() 1.7.2.3 +1 -4 jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecord.java Index: SSTRecord.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecord.java,v retrieving revision 1.7.2.2 retrieving revision 1.7.2.3 diff -u -r1.7.2.2 -r1.7.2.3 --- SSTRecord.java 23 Sep 2003 00:35:16 -0000 1.7.2.2 +++ SSTRecord.java 25 Sep 2003 08:08:05 -0000 1.7.2.3 @@ -586,10 +586,7 @@ */ public int calcExtSSTRecordSize() { - int infoRecs = (field_3_strings.size() / SSTSerializer.DEFAULT_BUCKET_SIZE); - if ((field_3_strings.size() % SSTSerializer.DEFAULT_BUCKET_SIZE) != 0) - infoRecs ++; - return 4 + 2 + (infoRecs * 8); + return ExtSSTRecord.getRecordSizeForStrings(field_3_strings.size()); } } 1.6.2.3 +16 -11 jakarta-poi/src/java/org/apache/poi/hssf/record/SSTSerializer.java Index: SSTSerializer.java =================================================================== RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/SSTSerializer.java,v retrieving revision 1.6.2.2 retrieving revision 1.6.2.3 diff -u -r1.6.2.2 -r1.6.2.3 --- SSTSerializer.java 23 Sep 2003 00:35:16 -0000 1.6.2.2 +++ SSTSerializer.java 25 Sep 2003 08:08:05 -0000 1.6.2.3 @@ -82,8 +82,6 @@ /** Offsets relative the start of the current SST or continue record */ int[] bucketRelativeOffsets; int startOfSST, startOfRecord; - /** The default bucket size (this is used for ExternSST) */ - final static int DEFAULT_BUCKET_SIZE = 8; public SSTSerializer( List recordLengths, BinaryTree strings, int numStrings, int numUniqueStrings ) { @@ -93,9 +91,7 @@ this.numUniqueStrings = numUniqueStrings; this.sstRecordHeader = new SSTRecordHeader( numStrings, numUniqueStrings ); - int infoRecs = (strings.size() / SSTSerializer.DEFAULT_BUCKET_SIZE); - if ((strings.size() % SSTSerializer.DEFAULT_BUCKET_SIZE) != 0) - infoRecs ++; + int infoRecs = ExtSSTRecord.getNumberOfInfoRecsForStrings(strings.size()); this.bucketAbsoluteOffsets = new int[infoRecs]; this.bucketRelativeOffsets = new int[infoRecs]; } @@ -157,10 +153,14 @@ for ( int k = 0; k < strings.size(); k++ ) { - if (k % DEFAULT_BUCKET_SIZE == 0) + if (k % ExtSSTRecord.DEFAULT_BUCKET_SIZE == 0) { - bucketAbsoluteOffsets[k / DEFAULT_BUCKET_SIZE] = pos; - bucketRelativeOffsets[k / DEFAULT_BUCKET_SIZE] = pos; + int index = k/ExtSSTRecord.DEFAULT_BUCKET_SIZE; + if (index < ExtSSTRecord.MAX_BUCKETS) { + //Excel only indexes the first 128 buckets. + bucketAbsoluteOffsets[index] = pos; + bucketRelativeOffsets[index] = pos; + } } System.arraycopy( getUnicodeString( k ).serialize(), 0, data, pos + offset, getUnicodeString( k ).getRecordSize() ); pos += getUnicodeString( k ).getRecordSize(); @@ -210,10 +210,15 @@ { UnicodeString unistr = getUnicodeString( stringIndex ); - if (stringIndex % DEFAULT_BUCKET_SIZE == 0) + if (stringIndex % ExtSSTRecord.DEFAULT_BUCKET_SIZE == 0) { - bucketAbsoluteOffsets[stringIndex / DEFAULT_BUCKET_SIZE] = offset + totalWritten + recordProcessor.getRecordOffset() - startOfSST; - bucketRelativeOffsets[stringIndex / DEFAULT_BUCKET_SIZE] = offset + totalWritten + recordProcessor.getRecordOffset() - startOfRecord; + int index = stringIndex / ExtSSTRecord.DEFAULT_BUCKET_SIZE; + if (index < ExtSSTRecord.MAX_BUCKETS) { + bucketAbsoluteOffsets[index] = offset + totalWritten + + recordProcessor.getRecordOffset() - startOfSST; + bucketRelativeOffsets[index] = offset + totalWritten + + recordProcessor.getRecordOffset() - startOfRecord; + } } if ( unistr.getRecordSize() <= recordProcessor.getAvailable() )
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]