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]

Reply via email to