You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by gl...@apache.org on 2003/06/26 14:33:36 UTC
cvs commit: jakarta-poi/src/java/org/apache/poi/hssf/record ExtSSTInfoSubRecord.java ExtSSTRecord.java RecordProcessor.java SSTRecord.java SSTRecordSizeCalculator.java SSTSerializer.java
glens 2003/06/26 05:33:36
Modified: src/java/org/apache/poi/hssf/model Tag: REL_2_BRANCH
Workbook.java
src/java/org/apache/poi/hssf/record Tag: REL_2_BRANCH
ExtSSTInfoSubRecord.java ExtSSTRecord.java
RecordProcessor.java SSTRecord.java
SSTRecordSizeCalculator.java SSTSerializer.java
Log:
A real implementation of the ExtSST record. The old implementation just wrote a fake record
Revision Changes Path
No revision
No revision
1.29.2.1 +59 -59 jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java
Index: Workbook.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java,v
retrieving revision 1.29
retrieving revision 1.29.2.1
diff -u -r1.29 -r1.29.2.1
--- Workbook.java 30 Apr 2003 04:39:16 -0000 1.29
+++ Workbook.java 26 Jun 2003 12:33:35 -0000 1.29.2.1
@@ -686,37 +686,27 @@
*
* @return byte array containing the HSSF-only portions of the POIFS file.
*/
-
- public byte [] serialize() {
- log.log(DEBUG, "Serializing Workbook!");
- byte[] retval = null;
-
- // ArrayList bytes = new ArrayList(records.size());
- int arraysize = getSize();
- int pos = 0;
-
- // for (int k = 0; k < records.size(); k++)
- // {
- // bytes.add((( Record ) records.get(k)).serialize());
- // }
- // for (int k = 0; k < bytes.size(); k++)
- // {
- // arraysize += (( byte [] ) bytes.get(k)).length;
- // }
- retval = new byte[ arraysize ];
- for (int k = 0; k < records.size(); k++) {
-
- // byte[] rec = (( byte [] ) bytes.get(k));
- // System.arraycopy(rec, 0, retval, pos, rec.length);
- Record record = records.get(k);
- // Let's skip RECALCID records, as they are only use for optimization
- if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
- pos += record.serialize(pos, retval); // rec.length;
- }
- }
- log.log(DEBUG, "Exiting serialize workbook");
- return retval;
- }
+ // GJS: Not used so why keep it.
+// public byte [] serialize() {
+// log.log(DEBUG, "Serializing Workbook!");
+// byte[] retval = null;
+//
+//// ArrayList bytes = new ArrayList(records.size());
+// int arraysize = getSize();
+// int pos = 0;
+//
+// retval = new byte[ arraysize ];
+// for (int k = 0; k < records.size(); k++) {
+//
+// Record record = records.get(k);
+//// Let's skip RECALCID records, as they are only use for optimization
+// if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
+// pos += record.serialize(pos, retval); // rec.length;
+// }
+// }
+// log.log(DEBUG, "Exiting serialize workbook");
+// return retval;
+// }
/**
* Serializes all records int the worksheet section into a big byte array. Use
@@ -725,44 +715,54 @@
* @param data array of bytes to write this to
*/
- public int serialize(int offset, byte [] data) {
- log.log(DEBUG, "Serializing Workbook with offsets");
+ public int serialize( int offset, byte[] data )
+ {
+ log.log( DEBUG, "Serializing Workbook with offsets" );
+
+ int pos = 0;
+
+ SSTRecord sst = null;
+ int sstPos = 0;
+ for ( int k = 0; k < records.size(); k++ )
+ {
- // ArrayList bytes = new ArrayList(records.size());
- // int arraysize = getSize(); // 0;
- int pos = 0;
-
- // for (int k = 0; k < records.size(); k++)
- // {
- // bytes.add((( Record ) records.get(k)).serialize());
- //
- // }
- // for (int k = 0; k < bytes.size(); k++)
- // {
- // arraysize += (( byte [] ) bytes.get(k)).length;
- // }
- for (int k = 0; k < records.size(); k++) {
-
- // byte[] rec = (( byte [] ) bytes.get(k));
- // System.arraycopy(rec, 0, data, offset + pos, rec.length);
- Record record = records.get(k);
+ Record record = records.get( k );
// Let's skip RECALCID records, as they are only use for optimization
- if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
- pos += record.serialize(pos + offset, data); // rec.length;
+ if ( record.getSid() != RecalcIdRecord.sid || ( (RecalcIdRecord) record ).isNeeded() )
+ {
+ if (record instanceof SSTRecord)
+ {
+ sst = (SSTRecord)record;
+ sstPos = pos;
+ }
+ if (record.getSid() == ExtSSTRecord.sid && sst != null)
+ {
+ record = sst.createExtSSTRecord(sstPos + offset);
+ }
+ pos += record.serialize( pos + offset, data ); // rec.length;
}
}
- log.log(DEBUG, "Exiting serialize workbook");
+ log.log( DEBUG, "Exiting serialize workbook" );
return pos;
}
- public int getSize() {
+ public int getSize()
+ {
int retval = 0;
- for (int k = 0; k < records.size(); k++) {
- Record record = records.get(k);
+ SSTRecord sst = null;
+ for ( int k = 0; k < records.size(); k++ )
+ {
+ Record record = records.get( k );
// Let's skip RECALCID records, as they are only use for optimization
- if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
- retval += record.getRecordSize();
+ if ( record.getSid() != RecalcIdRecord.sid || ( (RecalcIdRecord) record ).isNeeded() )
+ {
+ if (record instanceof SSTRecord)
+ sst = (SSTRecord)record;
+ if (record.getSid() == ExtSSTRecord.sid && sst != null)
+ retval += sst.calcExtSSTRecordSize();
+ else
+ retval += record.getRecordSize();
}
}
return retval;
No revision
No revision
1.2.2.1 +2 -2 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
retrieving revision 1.2.2.1
diff -u -r1.2 -r1.2.2.1
--- ExtSSTInfoSubRecord.java 30 Apr 2003 04:38:48 -0000 1.2
+++ ExtSSTInfoSubRecord.java 26 Jun 2003 12:33:35 -0000 1.2.2.1
@@ -114,7 +114,7 @@
field_1_stream_pos = pos;
}
- public void setBucketSSTOffset(short offset)
+ public void setBucketRecordOffset(short offset)
{
field_2_bucket_sst_offset = offset;
}
@@ -159,6 +159,6 @@
public short getSid()
{
- return this.sid;
+ return sid;
}
}
1.3.2.1 +20 -6 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
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
--- ExtSSTRecord.java 30 Apr 2003 04:38:47 -0000 1.3
+++ ExtSSTRecord.java 26 Jun 2003 12:33:35 -0000 1.3.2.1
@@ -79,6 +79,7 @@
private short field_1_strings_per_bucket;
private ArrayList field_2_sst_info;
+
public ExtSSTRecord()
{
field_2_sst_info = new ArrayList();
@@ -189,26 +190,39 @@
public int serialize(int offset, byte [] data)
{
LittleEndian.putShort(data, 0 + offset, sid);
-
-// LittleEndian.putShort(data,2,(short)(2 + (getNumInfoRecords() *8)));
- LittleEndian.putShort(data, 2 + offset, ( short ) (2 + (0x3fa - 2)));
- int pos = 4;
+ LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
+ LittleEndian.putShort(data, 4 + offset, field_1_strings_per_bucket);
+ int pos = 6;
for (int k = 0; k < getNumInfoRecords(); k++)
{
System.arraycopy(getInfoRecordAt(k).serialize(), 0, data,
pos + offset, 8);
+ pos += getInfoRecordAt(k).getRecordSize();
}
return getRecordSize();
}
public int getRecordSize()
{
- return 6 + 0x3fa - 2;
+ return 4 + 2 + field_2_sst_info.size() * 8;
}
public short getSid()
{
- return this.sid;
+ return sid;
+ }
+
+ public void setBucketOffsets( int[] bucketAbsoluteOffsets, int[] bucketRelativeOffsets )
+ {
+ this.field_2_sst_info = new ArrayList(bucketAbsoluteOffsets.length);
+ for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )
+ {
+ ExtSSTInfoSubRecord r = new ExtSSTInfoSubRecord();
+ r.setBucketRecordOffset((short)bucketRelativeOffsets[i]);
+ r.setStreamPos(bucketAbsoluteOffsets[i]);
+ field_2_sst_info.add(r);
+ }
}
+
}
1.4.2.1 +5 -0 jakarta-poi/src/java/org/apache/poi/hssf/record/RecordProcessor.java
Index: RecordProcessor.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/RecordProcessor.java,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -r1.4 -r1.4.2.1
--- RecordProcessor.java 30 Apr 2003 04:38:48 -0000 1.4
+++ RecordProcessor.java 26 Jun 2003 12:33:35 -0000 1.4.2.1
@@ -156,5 +156,10 @@
recordOffset += amount;
available -= amount;
}
+
+ public int getRecordOffset()
+ {
+ return recordOffset;
+ }
}
1.7.2.1 +59 -9 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
retrieving revision 1.7.2.1
diff -u -r1.7 -r1.7.2.1
--- SSTRecord.java 30 Apr 2003 04:38:48 -0000 1.7
+++ SSTRecord.java 26 Jun 2003 12:33:35 -0000 1.7.2.1
@@ -60,7 +60,6 @@
import java.util.Iterator;
import java.util.List;
-import java.util.ArrayList;
/**
* Title: Static String Table Record
@@ -73,7 +72,7 @@
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Marc Johnson (mjohnson at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
- * @version 2.0-pre
+ *
* @see org.apache.poi.hssf.record.LabelSSTRecord
* @see org.apache.poi.hssf.record.ContinueRecord
*/
@@ -112,10 +111,14 @@
private List _record_lengths = null;
private SSTDeserializer deserializer;
+ /** Offsets from the beginning of the SST record (even across continuations) */
+ int[] bucketAbsoluteOffsets;
+ /** Offsets relative the start of the current SST or continue record */
+ int[] bucketRelativeOffsets;
+
/**
* default constructor
*/
-
public SSTRecord()
{
field_1_num_strings = 0;
@@ -220,7 +223,7 @@
field_1_num_strings++;
String str = ( string == null ) ? ""
: string;
- int rval = -1;
+ int rval;
UnicodeString ucs = new UnicodeString();
ucs.setString( str );
@@ -334,7 +337,7 @@
for ( int k = 0; k < field_3_strings.size(); k++ )
{
buffer.append( " .string_" + k + " = " )
- .append( ( (UnicodeString) field_3_strings
+ .append( ( field_3_strings
.get( new Integer( k ) ) ).toString() ).append( "\n" );
}
buffer.append( "[/SST]\n" );
@@ -394,7 +397,7 @@
* The data consists of sets of string data. This string data is
* arranged as follows:
* <P>
- * <CODE>
+ * <CODE><pre>
* short string_length; // length of string data
* byte string_flag; // flag specifying special string
* // handling
@@ -407,7 +410,7 @@
* // array is run_count)
* byte[] extension; // optional extension (length of array
* // is extend_length)
- * </CODE>
+ * </pre></CODE>
* <P>
* The string_flag is bit mapped as follows:
* <P>
@@ -507,14 +510,22 @@
* Subclasses should implement this so that their data is passed back in a
* byte array.
*
- * @return byte array containing instance data
+ * @return size
*/
public int serialize( int offset, byte[] data )
{
SSTSerializer serializer = new SSTSerializer(
_record_lengths, field_3_strings, getNumStrings(), getNumUniqueStrings() );
- return serializer.serialize( getRecordSize(), offset, data );
+ int bytes = serializer.serialize( getRecordSize(), offset, data );
+ bucketAbsoluteOffsets = serializer.getBucketAbsoluteOffsets();
+ bucketRelativeOffsets = serializer.getBucketRelativeOffsets();
+// for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )
+// {
+// System.out.println( "bucketAbsoluteOffset = " + bucketAbsoluteOffsets[i] );
+// System.out.println( "bucketRelativeOffset = " + bucketRelativeOffsets[i] );
+// }
+ return bytes;
}
@@ -537,6 +548,45 @@
public void processContinueRecord( byte[] record )
{
deserializer.processContinueRecord( record );
+ }
+
+ /**
+ * Creates an extended string record based on the current contents of
+ * the current SST record. The offset within the stream to the SST record
+ * is required because the extended string record points directly to the
+ * strings in the SST record.
+ * <p>
+ * NOTE: THIS FUNCTION MUST ONLY BE CALLED AFTER THE SST RECORD HAS BEEN
+ * SERIALIZED.
+ *
+ * @param sstOffset The offset in the stream to the start of the
+ * SST record.
+ * @return The new SST record.
+ */
+ public ExtSSTRecord createExtSSTRecord(int sstOffset)
+ {
+ if (bucketAbsoluteOffsets == null || bucketAbsoluteOffsets == null)
+ throw new IllegalStateException("SST record has not yet been serialized.");
+
+ ExtSSTRecord extSST = new ExtSSTRecord();
+ extSST.setNumStringsPerBucket((short)8);
+ int[] absoluteOffsets = (int[]) bucketAbsoluteOffsets.clone();
+ int[] relativeOffsets = (int[]) bucketRelativeOffsets.clone();
+ for ( int i = 0; i < absoluteOffsets.length; i++ )
+ absoluteOffsets[i] += sstOffset;
+ extSST.setBucketOffsets(absoluteOffsets, relativeOffsets);
+ return extSST;
+ }
+
+ /**
+ * Calculates the size in bytes of the EXTSST record as it would be if the
+ * record was serialized.
+ *
+ * @return The size of the ExtSST record in bytes.
+ */
+ public int calcExtSSTRecordSize()
+ {
+ return 4 + 2 + ((field_3_strings.size() / SSTSerializer.DEFAULT_BUCKET_SIZE) + 1) * 8;
}
}
1.3.2.1 +3 -1 jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecordSizeCalculator.java
Index: SSTRecordSizeCalculator.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecordSizeCalculator.java,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -r1.3 -r1.3.2.1
--- SSTRecordSizeCalculator.java 30 Apr 2003 04:38:48 -0000 1.3
+++ SSTRecordSizeCalculator.java 26 Jun 2003 12:33:35 -0000 1.3.2.1
@@ -61,7 +61,9 @@
import java.util.Map;
/**
- * Used to calculate the record sizes for a particular record.
+ * Used to calculate the record sizes for a particular record. This kind of
+ * sucks because it's similar to the SST serialization code. In general
+ * the SST serialization code needs to be rewritten.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
1.6.2.1 +35 -1 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
retrieving revision 1.6.2.1
diff -u -r1.6 -r1.6.2.1
--- SSTSerializer.java 30 Apr 2003 04:38:47 -0000 1.6
+++ SSTSerializer.java 26 Jun 2003 12:33:35 -0000 1.6.2.1
@@ -77,6 +77,14 @@
private int numUniqueStrings;
private SSTRecordHeader sstRecordHeader;
+ /** Offsets from the beginning of the SST record (even across continuations) */
+ int[] bucketAbsoluteOffsets;
+ /** 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 )
{
this.recordLengths = recordLengths;
@@ -84,6 +92,9 @@
this.numStrings = numStrings;
this.numUniqueStrings = numUniqueStrings;
this.sstRecordHeader = new SSTRecordHeader( numStrings, numUniqueStrings );
+
+ this.bucketAbsoluteOffsets = new int[strings.size()/DEFAULT_BUCKET_SIZE+1];
+ this.bucketRelativeOffsets = new int[strings.size()/DEFAULT_BUCKET_SIZE+1];
}
/**
@@ -133,7 +144,6 @@
/**
* This case is chosen when an SST record does not span over to a continue record.
- *
*/
private void serializeSingleSSTRecord( byte[] data, int offset, int record_length_index )
{
@@ -144,6 +154,11 @@
for ( int k = 0; k < strings.size(); k++ )
{
+ if (k % DEFAULT_BUCKET_SIZE == 0)
+ {
+ bucketAbsoluteOffsets[k / DEFAULT_BUCKET_SIZE] = pos;
+ bucketRelativeOffsets[k / DEFAULT_BUCKET_SIZE] = pos;
+ }
System.arraycopy( getUnicodeString( k ).serialize(), 0, data, pos + offset, getUnicodeString( k ).getRecordSize() );
pos += getUnicodeString( k ).getRecordSize();
}
@@ -157,6 +172,8 @@
private void serializeLargeRecord( int record_size, int record_length_index, byte[] buffer, int offset )
{
+ startOfSST = offset;
+
byte[] stringReminant = null;
int stringIndex = 0;
boolean lastneedcontinue = false;
@@ -170,6 +187,7 @@
recordLength, numStrings, numUniqueStrings );
// write the appropriate header
+ startOfRecord = offset + totalWritten;
recordProcessor.writeRecordHeader( offset, totalWritten, recordLength, first_record );
first_record = false;
@@ -189,6 +207,12 @@
{
UnicodeString unistr = getUnicodeString( stringIndex );
+ if (stringIndex % DEFAULT_BUCKET_SIZE == 0)
+ {
+ bucketAbsoluteOffsets[stringIndex / DEFAULT_BUCKET_SIZE] = offset + totalWritten + recordProcessor.getRecordOffset() - startOfSST;
+ bucketRelativeOffsets[stringIndex / DEFAULT_BUCKET_SIZE] = offset + totalWritten + recordProcessor.getRecordOffset() - startOfRecord;
+ }
+
if ( unistr.getRecordSize() <= recordProcessor.getAvailable() )
{
recordProcessor.writeWholeString( unistr, offset, totalWritten );
@@ -234,5 +258,15 @@
public List getRecordLengths()
{
return recordLengths;
+ }
+
+ public int[] getBucketAbsoluteOffsets()
+ {
+ return bucketAbsoluteOffsets;
+ }
+
+ public int[] getBucketRelativeOffsets()
+ {
+ return bucketRelativeOffsets;
}
}
Re: cvs commit: jakarta-poi/src/java/org/apache/poi/hssf/record
ExtSSTInfoSubRecord.java ExtSSTRecord.java RecordProcessor.java
SSTRecord.java SSTRecordSizeCalculator.java SSTSerializer.java
Posted by "Andrew C. Oliver" <ac...@apache.org>.
Great work glen... That¹s been bugging us forever. I don't think even OO.o
writes ExtSST.
On 6/26/03 8:33 AM, "glens@apache.org" <gl...@apache.org> wrote:
> glens 2003/06/26 05:33:36
>
> Modified: src/java/org/apache/poi/hssf/model Tag: REL_2_BRANCH
> Workbook.java
> src/java/org/apache/poi/hssf/record Tag: REL_2_BRANCH
> ExtSSTInfoSubRecord.java ExtSSTRecord.java
> RecordProcessor.java SSTRecord.java
> SSTRecordSizeCalculator.java SSTSerializer.java
> Log:
> A real implementation of the ExtSST record. The old implementation just wrote
> a fake record
>
> Revision Changes Path
> No revision
>
>
> No revision
>
>
> 1.29.2.1 +59 -59
> jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java
>
> Index: Workbook.java
> ===================================================================
> RCS file:
> /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java,v
> retrieving revision 1.29
> retrieving revision 1.29.2.1
> diff -u -r1.29 -r1.29.2.1
> --- Workbook.java 30 Apr 2003 04:39:16 -0000 1.29
> +++ Workbook.java 26 Jun 2003 12:33:35 -0000 1.29.2.1
> @@ -686,37 +686,27 @@
> *
> * @return byte array containing the HSSF-only portions of the POIFS
> file.
> */
> -
> - public byte [] serialize() {
> - log.log(DEBUG, "Serializing Workbook!");
> - byte[] retval = null;
> -
> - // ArrayList bytes = new ArrayList(records.size());
> - int arraysize = getSize();
> - int pos = 0;
> -
> - // for (int k = 0; k < records.size(); k++)
> - // {
> - // bytes.add((( Record ) records.get(k)).serialize());
> - // }
> - // for (int k = 0; k < bytes.size(); k++)
> - // {
> - // arraysize += (( byte [] ) bytes.get(k)).length;
> - // }
> - retval = new byte[ arraysize ];
> - for (int k = 0; k < records.size(); k++) {
> -
> - // byte[] rec = (( byte [] ) bytes.get(k));
> - // System.arraycopy(rec, 0, retval, pos, rec.length);
> - Record record = records.get(k);
> - // Let's skip RECALCID records, as they are only use for
> optimization
> - if(record.getSid() != RecalcIdRecord.sid ||
> ((RecalcIdRecord)record).isNeeded()) {
> - pos += record.serialize(pos, retval); // rec.length;
> - }
> - }
> - log.log(DEBUG, "Exiting serialize workbook");
> - return retval;
> - }
> + // GJS: Not used so why keep it.
> +// public byte [] serialize() {
> +// log.log(DEBUG, "Serializing Workbook!");
> +// byte[] retval = null;
> +//
> +//// ArrayList bytes = new ArrayList(records.size());
> +// int arraysize = getSize();
> +// int pos = 0;
> +//
> +// retval = new byte[ arraysize ];
> +// for (int k = 0; k < records.size(); k++) {
> +//
> +// Record record = records.get(k);
> +//// Let's skip RECALCID records, as they are only use for
> optimization
> +// if(record.getSid() != RecalcIdRecord.sid ||
> ((RecalcIdRecord)record).isNeeded()) {
> +// pos += record.serialize(pos, retval); // rec.length;
> +// }
> +// }
> +// log.log(DEBUG, "Exiting serialize workbook");
> +// return retval;
> +// }
>
> /**
> * Serializes all records int the worksheet section into a big byte
> array. Use
> @@ -725,44 +715,54 @@
> * @param data array of bytes to write this to
> */
>
> - public int serialize(int offset, byte [] data) {
> - log.log(DEBUG, "Serializing Workbook with offsets");
> + public int serialize( int offset, byte[] data )
> + {
> + log.log( DEBUG, "Serializing Workbook with offsets" );
> +
> + int pos = 0;
> +
> + SSTRecord sst = null;
> + int sstPos = 0;
> + for ( int k = 0; k < records.size(); k++ )
> + {
>
> - // ArrayList bytes = new ArrayList(records.size());
> - // int arraysize = getSize(); // 0;
> - int pos = 0;
> -
> - // for (int k = 0; k < records.size(); k++)
> - // {
> - // bytes.add((( Record ) records.get(k)).serialize());
> - //
> - // }
> - // for (int k = 0; k < bytes.size(); k++)
> - // {
> - // arraysize += (( byte [] ) bytes.get(k)).length;
> - // }
> - for (int k = 0; k < records.size(); k++) {
> -
> - // byte[] rec = (( byte [] ) bytes.get(k));
> - // System.arraycopy(rec, 0, data, offset + pos, rec.length);
> - Record record = records.get(k);
> + Record record = records.get( k );
> // Let's skip RECALCID records, as they are only use for
> optimization
> - if(record.getSid() != RecalcIdRecord.sid ||
> ((RecalcIdRecord)record).isNeeded()) {
> - pos += record.serialize(pos + offset, data); // rec.length;
> + if ( record.getSid() != RecalcIdRecord.sid || ( (RecalcIdRecord)
> record ).isNeeded() )
> + {
> + if (record instanceof SSTRecord)
> + {
> + sst = (SSTRecord)record;
> + sstPos = pos;
> + }
> + if (record.getSid() == ExtSSTRecord.sid && sst != null)
> + {
> + record = sst.createExtSSTRecord(sstPos + offset);
> + }
> + pos += record.serialize( pos + offset, data ); //
> rec.length;
> }
> }
> - log.log(DEBUG, "Exiting serialize workbook");
> + log.log( DEBUG, "Exiting serialize workbook" );
> return pos;
> }
>
> - public int getSize() {
> + public int getSize()
> + {
> int retval = 0;
>
> - for (int k = 0; k < records.size(); k++) {
> - Record record = records.get(k);
> + SSTRecord sst = null;
> + for ( int k = 0; k < records.size(); k++ )
> + {
> + Record record = records.get( k );
> // Let's skip RECALCID records, as they are only use for
> optimization
> - if(record.getSid() != RecalcIdRecord.sid ||
> ((RecalcIdRecord)record).isNeeded()) {
> - retval += record.getRecordSize();
> + if ( record.getSid() != RecalcIdRecord.sid || ( (RecalcIdRecord)
> record ).isNeeded() )
> + {
> + if (record instanceof SSTRecord)
> + sst = (SSTRecord)record;
> + if (record.getSid() == ExtSSTRecord.sid && sst != null)
> + retval += sst.calcExtSSTRecordSize();
> + else
> + retval += record.getRecordSize();
> }
> }
> return retval;
>
>
>
> No revision
>
>
> No revision
>
>
> 1.2.2.1 +2 -2
> 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
> retrieving revision 1.2.2.1
> diff -u -r1.2 -r1.2.2.1
> --- ExtSSTInfoSubRecord.java 30 Apr 2003 04:38:48 -0000 1.2
> +++ ExtSSTInfoSubRecord.java 26 Jun 2003 12:33:35 -0000 1.2.2.1
> @@ -114,7 +114,7 @@
> field_1_stream_pos = pos;
> }
>
> - public void setBucketSSTOffset(short offset)
> + public void setBucketRecordOffset(short offset)
> {
> field_2_bucket_sst_offset = offset;
> }
> @@ -159,6 +159,6 @@
>
> public short getSid()
> {
> - return this.sid;
> + return sid;
> }
> }
>
>
>
> 1.3.2.1 +20 -6
> 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
> retrieving revision 1.3.2.1
> diff -u -r1.3 -r1.3.2.1
> --- ExtSSTRecord.java 30 Apr 2003 04:38:47 -0000 1.3
> +++ ExtSSTRecord.java 26 Jun 2003 12:33:35 -0000 1.3.2.1
> @@ -79,6 +79,7 @@
> private short field_1_strings_per_bucket;
> private ArrayList field_2_sst_info;
>
> +
> public ExtSSTRecord()
> {
> field_2_sst_info = new ArrayList();
> @@ -189,26 +190,39 @@
> public int serialize(int offset, byte [] data)
> {
> LittleEndian.putShort(data, 0 + offset, sid);
> -
> -// LittleEndian.putShort(data,2,(short)(2 + (getNumInfoRecords() *8)));
> - LittleEndian.putShort(data, 2 + offset, ( short ) (2 + (0x3fa - 2)));
> - int pos = 4;
> + LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() -
> 4));
> + LittleEndian.putShort(data, 4 + offset, field_1_strings_per_bucket);
> + int pos = 6;
>
> for (int k = 0; k < getNumInfoRecords(); k++)
> {
> System.arraycopy(getInfoRecordAt(k).serialize(), 0, data,
> pos + offset, 8);
> + pos += getInfoRecordAt(k).getRecordSize();
> }
> return getRecordSize();
> }
>
> public int getRecordSize()
> {
> - return 6 + 0x3fa - 2;
> + return 4 + 2 + field_2_sst_info.size() * 8;
> }
>
> public short getSid()
> {
> - return this.sid;
> + return sid;
> + }
> +
> + public void setBucketOffsets( int[] bucketAbsoluteOffsets, int[]
> bucketRelativeOffsets )
> + {
> + this.field_2_sst_info = new ArrayList(bucketAbsoluteOffsets.length);
> + for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )
> + {
> + ExtSSTInfoSubRecord r = new ExtSSTInfoSubRecord();
> + r.setBucketRecordOffset((short)bucketRelativeOffsets[i]);
> + r.setStreamPos(bucketAbsoluteOffsets[i]);
> + field_2_sst_info.add(r);
> + }
> }
> +
> }
>
>
>
> 1.4.2.1 +5 -0
> jakarta-poi/src/java/org/apache/poi/hssf/record/RecordProcessor.java
>
> Index: RecordProcessor.java
> ===================================================================
> RCS file:
> /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/RecordProcessor.java
> ,v
> retrieving revision 1.4
> retrieving revision 1.4.2.1
> diff -u -r1.4 -r1.4.2.1
> --- RecordProcessor.java 30 Apr 2003 04:38:48 -0000 1.4
> +++ RecordProcessor.java 26 Jun 2003 12:33:35 -0000 1.4.2.1
> @@ -156,5 +156,10 @@
> recordOffset += amount;
> available -= amount;
> }
> +
> + public int getRecordOffset()
> + {
> + return recordOffset;
> + }
> }
>
>
>
>
> 1.7.2.1 +59 -9
> 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
> retrieving revision 1.7.2.1
> diff -u -r1.7 -r1.7.2.1
> --- SSTRecord.java 30 Apr 2003 04:38:48 -0000 1.7
> +++ SSTRecord.java 26 Jun 2003 12:33:35 -0000 1.7.2.1
> @@ -60,7 +60,6 @@
>
> import java.util.Iterator;
> import java.util.List;
> -import java.util.ArrayList;
>
> /**
> * Title: Static String Table Record
> @@ -73,7 +72,7 @@
> * @author Andrew C. Oliver (acoliver at apache dot org)
> * @author Marc Johnson (mjohnson at apache dot org)
> * @author Glen Stampoultzis (glens at apache.org)
> - * @version 2.0-pre
> + *
> * @see org.apache.poi.hssf.record.LabelSSTRecord
> * @see org.apache.poi.hssf.record.ContinueRecord
> */
> @@ -112,10 +111,14 @@
> private List _record_lengths = null;
> private SSTDeserializer deserializer;
>
> + /** Offsets from the beginning of the SST record (even across
> continuations) */
> + int[] bucketAbsoluteOffsets;
> + /** Offsets relative the start of the current SST or continue record */
> + int[] bucketRelativeOffsets;
> +
> /**
> * default constructor
> */
> -
> public SSTRecord()
> {
> field_1_num_strings = 0;
> @@ -220,7 +223,7 @@
> field_1_num_strings++;
> String str = ( string == null ) ? ""
> : string;
> - int rval = -1;
> + int rval;
> UnicodeString ucs = new UnicodeString();
>
> ucs.setString( str );
> @@ -334,7 +337,7 @@
> for ( int k = 0; k < field_3_strings.size(); k++ )
> {
> buffer.append( " .string_" + k + " = " )
> - .append( ( (UnicodeString) field_3_strings
> + .append( ( field_3_strings
> .get( new Integer( k ) ) ).toString() ).append( "\n" );
> }
> buffer.append( "[/SST]\n" );
> @@ -394,7 +397,7 @@
> * The data consists of sets of string data. This string data is
> * arranged as follows:
> * <P>
> - * <CODE>
> + * <CODE><pre>
> * short string_length; // length of string data
> * byte string_flag; // flag specifying special string
> * // handling
> @@ -407,7 +410,7 @@
> * // array is run_count)
> * byte[] extension; // optional extension (length of array
> * // is extend_length)
> - * </CODE>
> + * </pre></CODE>
> * <P>
> * The string_flag is bit mapped as follows:
> * <P>
> @@ -507,14 +510,22 @@
> * Subclasses should implement this so that their data is passed back in
> a
> * byte array.
> *
> - * @return byte array containing instance data
> + * @return size
> */
>
> public int serialize( int offset, byte[] data )
> {
> SSTSerializer serializer = new SSTSerializer(
> _record_lengths, field_3_strings, getNumStrings(),
> getNumUniqueStrings() );
> - return serializer.serialize( getRecordSize(), offset, data );
> + int bytes = serializer.serialize( getRecordSize(), offset, data );
> + bucketAbsoluteOffsets = serializer.getBucketAbsoluteOffsets();
> + bucketRelativeOffsets = serializer.getBucketRelativeOffsets();
> +// for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )
> +// {
> +// System.out.println( "bucketAbsoluteOffset = " +
> bucketAbsoluteOffsets[i] );
> +// System.out.println( "bucketRelativeOffset = " +
> bucketRelativeOffsets[i] );
> +// }
> + return bytes;
> }
>
>
> @@ -537,6 +548,45 @@
> public void processContinueRecord( byte[] record )
> {
> deserializer.processContinueRecord( record );
> + }
> +
> + /**
> + * Creates an extended string record based on the current contents of
> + * the current SST record. The offset within the stream to the SST
> record
> + * is required because the extended string record points directly to the
> + * strings in the SST record.
> + * <p>
> + * NOTE: THIS FUNCTION MUST ONLY BE CALLED AFTER THE SST RECORD HAS BEEN
> + * SERIALIZED.
> + *
> + * @param sstOffset The offset in the stream to the start of the
> + * SST record.
> + * @return The new SST record.
> + */
> + public ExtSSTRecord createExtSSTRecord(int sstOffset)
> + {
> + if (bucketAbsoluteOffsets == null || bucketAbsoluteOffsets == null)
> + throw new IllegalStateException("SST record has not yet been
> serialized.");
> +
> + ExtSSTRecord extSST = new ExtSSTRecord();
> + extSST.setNumStringsPerBucket((short)8);
> + int[] absoluteOffsets = (int[]) bucketAbsoluteOffsets.clone();
> + int[] relativeOffsets = (int[]) bucketRelativeOffsets.clone();
> + for ( int i = 0; i < absoluteOffsets.length; i++ )
> + absoluteOffsets[i] += sstOffset;
> + extSST.setBucketOffsets(absoluteOffsets, relativeOffsets);
> + return extSST;
> + }
> +
> + /**
> + * Calculates the size in bytes of the EXTSST record as it would be if
> the
> + * record was serialized.
> + *
> + * @return The size of the ExtSST record in bytes.
> + */
> + public int calcExtSSTRecordSize()
> + {
> + return 4 + 2 + ((field_3_strings.size() /
> SSTSerializer.DEFAULT_BUCKET_SIZE) + 1) * 8;
> }
> }
>
>
>
>
> 1.3.2.1 +3 -1
> jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecordSizeCalculator.java
>
> Index: SSTRecordSizeCalculator.java
> ===================================================================
> RCS file:
> /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/SSTRecordSizeCalcula
> tor.java,v
> retrieving revision 1.3
> retrieving revision 1.3.2.1
> diff -u -r1.3 -r1.3.2.1
> --- SSTRecordSizeCalculator.java 30 Apr 2003 04:38:48 -0000 1.3
> +++ SSTRecordSizeCalculator.java 26 Jun 2003 12:33:35 -0000 1.3.2.1
> @@ -61,7 +61,9 @@
> import java.util.Map;
>
> /**
> - * Used to calculate the record sizes for a particular record.
> + * Used to calculate the record sizes for a particular record. This kind of
> + * sucks because it's similar to the SST serialization code. In general
> + * the SST serialization code needs to be rewritten.
> *
> * @author Glen Stampoultzis (glens at apache.org)
> */
>
>
>
> 1.6.2.1 +35 -1
> 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
> retrieving revision 1.6.2.1
> diff -u -r1.6 -r1.6.2.1
> --- SSTSerializer.java 30 Apr 2003 04:38:47 -0000 1.6
> +++ SSTSerializer.java 26 Jun 2003 12:33:35 -0000 1.6.2.1
> @@ -77,6 +77,14 @@
> private int numUniqueStrings;
> private SSTRecordHeader sstRecordHeader;
>
> + /** Offsets from the beginning of the SST record (even across
> continuations) */
> + int[] bucketAbsoluteOffsets;
> + /** 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 )
> {
> this.recordLengths = recordLengths;
> @@ -84,6 +92,9 @@
> this.numStrings = numStrings;
> this.numUniqueStrings = numUniqueStrings;
> this.sstRecordHeader = new SSTRecordHeader( numStrings,
> numUniqueStrings );
> +
> + this.bucketAbsoluteOffsets = new
> int[strings.size()/DEFAULT_BUCKET_SIZE+1];
> + this.bucketRelativeOffsets = new
> int[strings.size()/DEFAULT_BUCKET_SIZE+1];
> }
>
> /**
> @@ -133,7 +144,6 @@
>
> /**
> * This case is chosen when an SST record does not span over to a
> continue record.
> - *
> */
> private void serializeSingleSSTRecord( byte[] data, int offset, int
> record_length_index )
> {
> @@ -144,6 +154,11 @@
>
> for ( int k = 0; k < strings.size(); k++ )
> {
> + if (k % DEFAULT_BUCKET_SIZE == 0)
> + {
> + bucketAbsoluteOffsets[k / DEFAULT_BUCKET_SIZE] = pos;
> + bucketRelativeOffsets[k / DEFAULT_BUCKET_SIZE] = pos;
> + }
> System.arraycopy( getUnicodeString( k ).serialize(), 0, data, pos
> + offset, getUnicodeString( k ).getRecordSize() );
> pos += getUnicodeString( k ).getRecordSize();
> }
> @@ -157,6 +172,8 @@
> private void serializeLargeRecord( int record_size, int
> record_length_index, byte[] buffer, int offset )
> {
>
> + startOfSST = offset;
> +
> byte[] stringReminant = null;
> int stringIndex = 0;
> boolean lastneedcontinue = false;
> @@ -170,6 +187,7 @@
> recordLength, numStrings, numUniqueStrings );
>
> // write the appropriate header
> + startOfRecord = offset + totalWritten;
> recordProcessor.writeRecordHeader( offset, totalWritten,
> recordLength, first_record );
> first_record = false;
>
> @@ -189,6 +207,12 @@
> {
> UnicodeString unistr = getUnicodeString( stringIndex );
>
> + if (stringIndex % DEFAULT_BUCKET_SIZE == 0)
> + {
> + bucketAbsoluteOffsets[stringIndex / DEFAULT_BUCKET_SIZE]
> = offset + totalWritten + recordProcessor.getRecordOffset() - startOfSST;
> + bucketRelativeOffsets[stringIndex / DEFAULT_BUCKET_SIZE]
> = offset + totalWritten + recordProcessor.getRecordOffset() - startOfRecord;
> + }
> +
> if ( unistr.getRecordSize() <= recordProcessor.getAvailable()
> )
> {
> recordProcessor.writeWholeString( unistr, offset,
> totalWritten );
> @@ -234,5 +258,15 @@
> public List getRecordLengths()
> {
> return recordLengths;
> + }
> +
> + public int[] getBucketAbsoluteOffsets()
> + {
> + return bucketAbsoluteOffsets;
> + }
> +
> + public int[] getBucketRelativeOffsets()
> + {
> + return bucketRelativeOffsets;
> }
> }
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: poi-dev-help@jakarta.apache.org
>
--
Andrew C. Oliver
http://www.superlinksoftware.com/poi.jsp
Custom enhancements and Commercial Implementation for Jakarta POI
http://jakarta.apache.org/poi
For Java and Excel, Got POI?