KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > record > SSTRecordSizeCalculator


1
2 /* ====================================================================
3    Copyright 2002-2004 Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================== */

17         
18
19 package org.apache.poi.hssf.record;
20
21 import org.apache.poi.util.LittleEndianConsts;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 /**
28  * Used to calculate the record sizes for a particular record. This kind of
29  * sucks because it's similar to the SST serialization code. In general
30  * the SST serialization code needs to be rewritten.
31  *
32  * @author Glen Stampoultzis (glens at apache.org)
33  * @author Jason Height (jheight at apache.org)
34  */

35 class SSTRecordSizeCalculator
36 {
37     private UnicodeString unistr = null;
38     private int stringReminant = 0;
39     private int unipos = 0;
40     /** Is there any more string to be written? */
41     private boolean isRemainingString = false;
42     private int totalBytesWritten = 0;
43     private boolean finished = false;
44     private boolean firstRecord = true;
45     private int totalWritten = 0;
46     private int recordSize = 0;
47     private List JavaDoc recordLengths = new ArrayList JavaDoc();
48     private int pos = 0;
49     private Map JavaDoc strings;
50
51     public SSTRecordSizeCalculator(Map JavaDoc strings)
52     {
53         this.strings = strings;
54     }
55
56     private boolean canFitStringInRecord(int recordLength) {
57       return (recordLength+SSTRecord.STRING_MINIMAL_OVERHEAD) < SSTRecord.MAX_RECORD_SIZE;
58                     }
59
60     public int getRecordSize() {
61        //Indicates how much of the current base or continue record has
62
//been written
63
int continueSize = SSTRecord.SST_RECORD_OVERHEAD;
64        int recordSize = 0;
65         for (int i=0; i < strings.size(); i++ )
66         {
67           Integer JavaDoc intunipos = new Integer JavaDoc(i);
68           UnicodeString unistr = ( (UnicodeString) strings.get(intunipos));
69           final int stringLength = unistr.getRecordSize();
70           if ((continueSize + stringLength) <= SSTRecord.MAX_RECORD_SIZE) {
71             //String can fit within the bounds of the current record (SST or Continue)
72
continueSize += stringLength;
73             
74             if ((i < (strings.size()-1)) && !canFitStringInRecord(continueSize)) {
75               //Start new continueRecord if there is another string
76
recordLengths.add(new Integer JavaDoc(continueSize));
77               recordSize += continueSize;
78               //Minimum ammount of space for a new continue record.
79
continueSize = 4;
80             }
81           } else {
82             int stringRemainder = stringLength;
83             while (stringRemainder != 0) {
84               if ( (continueSize + stringRemainder) > SSTRecord.MAX_RECORD_SIZE) {
85                 //Determine number of bytes that can be written in the space
86
//available
87
int bytesWritten = Math.min((SSTRecord.MAX_RECORD_SIZE - continueSize), stringRemainder);
88
89                 //Ensure that the Unicode String writes both the high and low
90
//byte in the one action. Since the string overhead is 3 bytes
91
//if the bytes that can be written is even, then we need to
92
//write one less byte to capture both the high and low bytes.
93
bytesWritten = unistr.maxBrokenLength(bytesWritten);
94                 continueSize += bytesWritten;
95                 stringRemainder -= bytesWritten;
96                 recordLengths.add(new Integer JavaDoc(continueSize));
97                 recordSize += continueSize;
98                 //Minimum ammount of space for a new continue record.
99
continueSize = 4;
100                 //Add one to the size of the string that is remaining, since the
101
//first byte for the next continue record will be compressed unicode indicator
102
stringRemainder++;
103               } else {
104                 //Remainder of string can fit within the bounds of the current
105
//continue record
106
continueSize += stringRemainder;
107                 stringRemainder = 0;
108                 if ((i < (strings.size()-1)) && !canFitStringInRecord(continueSize)) {
109                   //Start new continueRecord if there is another string
110
recordLengths.add(new Integer JavaDoc(continueSize));
111                   recordSize += continueSize;
112                   //Minimum ammount of space for a new continue record.
113
continueSize = 4;
114         }
115     }
116         }
117             }
118         }
119         recordLengths.add(new Integer JavaDoc(continueSize));
120         recordSize += continueSize;
121         return recordSize;
122     }
123
124     public List JavaDoc getRecordLengths()
125     {
126         return recordLengths;
127     }
128 }
129
Popular Tags