KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > write > biff > SSTContinueRecord


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.write.biff;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24
25 import jxl.biff.Type;
26 import jxl.biff.IntegerHelper;
27 import jxl.biff.WritableRecordData;
28 import jxl.biff.StringHelper;
29
30 /**
31  * A continuation of a shared string table record.
32  */

33 class SSTContinueRecord extends WritableRecordData
34 {
35   /**
36    * The first string is a special case
37    */

38   private String JavaDoc firstString;
39   /**
40    * Indicates whether or not we need to include the length information
41    * for the first string
42    */

43   private boolean includeLength;
44   /**
45    * The length of the first string
46    */

47   private int firstStringLength;
48   /**
49    * The list of strings
50    */

51   private ArrayList JavaDoc strings;
52   /**
53    * The list of string lengths
54    */

55   private ArrayList JavaDoc stringLengths;
56   /**
57    * The binary data
58    */

59   private byte[] data;
60   /**
61    * The count of bytes needed so far to contain this record
62    */

63   private int byteCount;
64   /**
65    * The maximum amount of bytes available for the SST record
66    */

67   private static int maxBytes = 8228 - // max length
68
4; // standard biff record stuff
69

70   /**
71    * Constructor
72    *
73    * @param numRefs the number of string references in the workbook
74    * @param s the number of strings
75    */

76   public SSTContinueRecord()
77   {
78     super(Type.CONTINUE);
79
80     byteCount = 0;
81     strings = new ArrayList JavaDoc(50);
82     stringLengths = new ArrayList JavaDoc(50);
83   }
84
85   /**
86    * Adds the first string to this SST record
87    *
88    * @param s the string to add
89    * @param b include the length information for the first string
90    * @return the number of characters not added
91    */

92   public int setFirstString(String JavaDoc s, boolean b)
93   {
94     includeLength = b;
95     firstStringLength = s.length();
96
97     int bytes = 0;
98
99     if (!includeLength)
100     {
101       bytes = s.length() * 2 + 1;
102     }
103     else
104     {
105       bytes = s.length() * 2 + 3;
106     }
107
108     if (bytes <= maxBytes)
109     {
110       firstString = s;
111       byteCount += bytes;
112       return 0;
113     }
114
115     // Calculate the number of characters we can add
116
// The bytes variable will always be an odd number
117
int charsAvailable = includeLength ? (maxBytes - 4) / 2 :
118                                          (maxBytes - 2) / 2;
119
120     // Add what part of the string we can
121
firstString = s.substring(0, charsAvailable);
122     byteCount = maxBytes - 1;
123
124     return s.length() - charsAvailable;
125   }
126
127   /**
128    * Gets the current offset into this record, excluding the header fields
129    *
130    * @return the number of bytes after the header field
131    */

132   public int getOffset()
133   {
134     return byteCount;
135   }
136
137   /**
138    * Adds a string to this record. It returns the number of string
139    * characters not added, due to space constraints. In the event
140    * of this being non-zero, a continue record will be needed
141    *
142    * @param s the string to add
143    * @return the number of characters not added
144    */

145   public int add(String JavaDoc s)
146   {
147     int bytes = s.length() * 2 + 3;
148
149     // Must be able to add at least the first character of the string
150
// onto the SST
151
if (byteCount >= maxBytes - 5)
152     {
153       return s.length();
154     }
155
156     stringLengths.add(new Integer JavaDoc(s.length()));
157
158     if (bytes + byteCount < maxBytes)
159     {
160       // add the string and return
161
strings.add(s);
162       byteCount += bytes;
163       return 0;
164     }
165
166     // Calculate the number of characters we can add
167
int bytesLeft = maxBytes - 3 - byteCount;
168     int charsAvailable = bytesLeft % 2 == 0 ? bytesLeft / 2 :
169                                              (bytesLeft - 1) / 2;
170
171     // Add what part of the string we can
172
strings.add(s.substring(0, charsAvailable));
173     byteCount += charsAvailable * 2 + 3;
174
175     return s.length() - charsAvailable;
176   }
177
178   /**
179    * Gets the binary data for output to file
180    *
181    * @return the binary data
182    */

183   public byte[] getData()
184   {
185     data = new byte[byteCount];
186
187     int pos = 0;
188
189     // Write out the first string
190
if (includeLength)
191     {
192       IntegerHelper.getTwoBytes(firstStringLength, data, 0);
193       data[2] = 0x01;
194       pos = 3;
195     }
196     else
197     {
198       // Just include the unicode indicator
199
data[0] = 0x01;
200       pos = 1;
201     }
202
203     StringHelper.getUnicodeBytes(firstString, data, pos);
204     pos += firstString.length() * 2;
205
206     // Now write out the remainder of the strings
207
Iterator JavaDoc i = strings.iterator();
208     String JavaDoc s = null;
209     int length = 0;
210     int count = 0;
211     while (i.hasNext())
212     {
213       s = (String JavaDoc) i.next();
214       length = ( (Integer JavaDoc) stringLengths.get(count)).intValue();
215       IntegerHelper.getTwoBytes(length, data, pos);
216       data[pos+2] = 0x01;
217       StringHelper.getUnicodeBytes(s, data, pos+3);
218       pos += s.length() * 2 + 3;
219       count++;
220     }
221     
222     return data;
223   }
224 }
225
Popular Tags