KickJava   Java API By Example, From Geeks To Geeks.

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


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 shared string table record.
32  */

33 class SSTRecord extends WritableRecordData
34 {
35   /**
36    * The number of string references in the workbook
37    */

38   private int numReferences;
39   /**
40    * The number of strings in this table
41    */

42   private int numStrings;
43   /**
44    * The list of strings
45    */

46   private ArrayList JavaDoc strings;
47   /**
48    * The list of string lengths
49    */

50   private ArrayList JavaDoc stringLengths;
51   /**
52    * The binary data
53    */

54   private byte[] data;
55   /**
56    * The count of bytes needed so far to contain this record
57    */

58   private int byteCount;
59   /**
60    * The maximum amount of bytes available for the SST record
61    */

62   private static int maxBytes = 8228 - // max length
63
8 - // bytes for string count fields
64
4; // standard biff record header
65

66   /**
67    * Constructor
68    *
69    * @param numRefs the number of string references in the workbook
70    * @param s the number of strings
71    */

72   public SSTRecord(int numRefs, int s)
73   {
74     super(Type.SST);
75
76     numReferences = numRefs;
77     numStrings = s;
78     byteCount = 0;
79     strings = new ArrayList JavaDoc(50);
80     stringLengths = new ArrayList JavaDoc(50);
81   }
82
83   /**
84    * Adds a string to this SST record. It returns the number of string
85    * characters not added, due to space constraints. In the event
86    * of this being non-zero, a continue record will be needed
87    *
88    * @param s the string to add
89    * @return the number of characters not added
90    */

91   public int add(String JavaDoc s)
92   {
93     int bytes = s.length() * 2 + 3;
94
95     // Must be able to add at least the first character of the string
96
// onto the SST
97
if (byteCount >= maxBytes - 5)
98     {
99       return s.length();
100     }
101
102     stringLengths.add(new Integer JavaDoc(s.length()));
103
104     if (bytes + byteCount < maxBytes)
105     {
106       // add the string and return
107
strings.add(s);
108       byteCount += bytes;
109       return 0;
110     }
111
112     // Calculate the number of characters we can add
113
int bytesLeft = maxBytes - 3 - byteCount;
114     int charsAvailable = bytesLeft % 2 == 0 ? bytesLeft / 2 :
115                                              (bytesLeft - 1) / 2;
116
117     // Add what strings we can
118
strings.add(s.substring(0, charsAvailable));
119     byteCount += charsAvailable * 2 + 3;
120
121     return s.length() - charsAvailable;
122   }
123
124   /**
125    * Gets the current offset into this record, excluding the header fields
126    *
127    * @return the number of bytes after the header field
128    */

129   public int getOffset()
130   {
131     return byteCount + 8;
132   }
133
134   /**
135    * Gets the binary data for output to file
136    *
137    * @return the binary data
138    */

139   public byte[] getData()
140   {
141     data = new byte[byteCount+8];
142     IntegerHelper.getFourBytes(numReferences, data, 0);
143     IntegerHelper.getFourBytes(numStrings, data, 4);
144
145     int pos = 8;
146     int count = 0;
147
148     Iterator JavaDoc i = strings.iterator();
149     String JavaDoc s = null;
150     int length = 0;
151     while (i.hasNext())
152     {
153       s = (String JavaDoc) i.next();
154       length = ( (Integer JavaDoc) stringLengths.get(count)).intValue();
155       IntegerHelper.getTwoBytes(length, data, pos);
156       data[pos+2] = 0x01;
157       StringHelper.getUnicodeBytes(s, data, pos+3);
158       pos += s.length() * 2 + 3;
159       count++;
160     }
161     
162     return data;
163   }
164 }
165
Popular Tags