KickJava   Java API By Example, From Geeks To Geeks.

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


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.LittleEndian;
22 import org.apache.poi.util.StringUtil;
23
24 import java.io.UnsupportedEncodingException JavaDoc;
25
26 /**
27  * Title: Unicode String<P>
28  * Description: Unicode String record. We implement these as a record, although
29  * they are really just standard fields that are in several records.
30  * It is considered more desirable then repeating it in all of them.<P>
31  * REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
32  * @author Andrew C. Oliver
33  * @author Marc Johnson (mjohnson at apache dot org)
34  * @author Glen Stampoultzis (glens at apache.org)
35  * @version 2.0-pre
36  */

37
38 public class UnicodeString
39     extends Record
40     implements Comparable JavaDoc
41 {
42     public final static short sid = 0xFFF;
43     private short field_1_charCount; // = 0;
44
private byte field_2_optionflags; // = 0;
45
private String JavaDoc field_3_string; // = null;
46
private final int RICH_TEXT_BIT = 8;
47     private final int EXT_BIT = 4;
48
49     public UnicodeString()
50     {
51     }
52
53
54     public int hashCode()
55     {
56         int stringHash = 0;
57         if (field_3_string != null)
58             stringHash = field_3_string.hashCode();
59         return field_1_charCount + stringHash;
60     }
61
62     /**
63      * Our handling of equals is inconsistent with compareTo. The trouble is because we don't truely understand
64      * rich text fields yet it's difficult to make a sound comparison.
65      *
66      * @param o The object to compare.
67      * @return true if the object is actually equal.
68      */

69     public boolean equals(Object JavaDoc o)
70     {
71         if ((o == null) || (o.getClass() != this.getClass()))
72         {
73             return false;
74         }
75         UnicodeString other = ( UnicodeString ) o;
76
77         return ((field_1_charCount == other.field_1_charCount)
78                 && (field_2_optionflags == other.field_2_optionflags)
79                 && field_3_string.equals(other.field_3_string));
80     }
81
82     /**
83      * construct a unicode string record and fill its fields, ID is ignored
84      * @param id - ignored
85      * @param size - size of the data
86      * @param data - the bytes of the string/fields
87      */

88
89     public UnicodeString(short id, short size, byte [] data)
90     {
91         super(id, size, data);
92     }
93
94     /**
95      * construct a unicode string from a string fragment + data
96      */

97
98     public UnicodeString(short id, short size, byte [] data, String JavaDoc prefix)
99     {
100         this(id, size, data);
101         field_3_string = prefix + field_3_string;
102         setCharCount();
103     }
104
105     /**
106      * NO OP
107      */

108
109     protected void validateSid(short id)
110     {
111
112         // included only for interface compliance
113
}
114
115     protected void fillFields(byte [] data, short size)
116     {
117         field_1_charCount = LittleEndian.getShort(data, 0);
118         field_2_optionflags = data[ 2 ];
119         if ((field_2_optionflags & 1) == 0)
120         {
121             try {
122                 field_3_string = new String JavaDoc(data, 3, getCharCount(),
123                                         StringUtil.getPreferredEncoding());
124             } catch (UnsupportedEncodingException JavaDoc e) {
125                 // Extract the message out of our encoding
126
// error and then bubble a runtime exception.
127
String JavaDoc errorMessage = e.getMessage();
128                 
129                 // Make sure the message isn't null
130
if (errorMessage == null) {
131                     errorMessage = e.toString();
132             }
133                 throw new RuntimeException JavaDoc(errorMessage);
134             }
135         }
136         else
137         {
138             char[] array = new char[ getCharCount() ];
139
140             for (int j = 0; j < array.length; j++)
141             {
142                 array[ j ] = ( char ) LittleEndian.getShort(data,
143                                                             3 + (j * 2));
144             }
145             field_3_string = new String JavaDoc(array);
146         }
147     }
148
149     /**
150      * get the number of characters in the string
151      *
152      *
153      * @return number of characters
154      *
155      */

156
157     public short getCharCount()
158     {
159         return field_1_charCount;
160     }
161
162     /**
163      * set the number of characters in the string
164      * @param cc - number of characters
165      */

166
167     public void setCharCount(short cc)
168     {
169         field_1_charCount = cc;
170     }
171
172     /**
173      * sets the number of characters to whaterver number of characters is in the string
174      * currently. effectively setCharCount(getString.length()).
175      * @see #setString(String)
176      * @see #getString()
177      */

178
179     public void setCharCount()
180     {
181         field_1_charCount = ( short ) field_3_string.length();
182     }
183
184     /**
185      * get the option flags which among other things return if this is a 16-bit or
186      * 8 bit string
187      *
188      * @return optionflags bitmask
189      *
190      */

191
192     public byte getOptionFlags()
193     {
194         return field_2_optionflags;
195     }
196
197     /**
198      * set the option flags which among other things return if this is a 16-bit or
199      * 8 bit string
200      *
201      * @param of optionflags bitmask
202      *
203      */

204
205     public void setOptionFlags(byte of)
206     {
207         field_2_optionflags = of;
208     }
209
210     /**
211      * get the actual string this contains as a java String object
212      *
213      *
214      * @return String
215      *
216      */

217
218     public String JavaDoc getString()
219     {
220         return field_3_string;
221     }
222
223     /**
224      * set the actual string this contains
225      * @param string the text
226      */

227
228     public void setString(String JavaDoc string)
229     {
230         field_3_string = string;
231         if (getCharCount() < field_3_string.length())
232         {
233             setCharCount();
234         }
235     }
236
237     /**
238      * unlike the real records we return the same as "getString()" rather than debug info
239      * @see #getDebugInfo()
240      * @return String value of the record
241      */

242
243     public String JavaDoc toString()
244     {
245         return getString();
246     }
247
248     /**
249      * return a character representation of the fields of this record
250      *
251      *
252      * @return String of output for biffviewer etc.
253      *
254      */

255
256     public String JavaDoc getDebugInfo()
257     {
258         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
259
260         buffer.append("[UNICODESTRING]\n");
261         buffer.append(" .charcount = ")
262             .append(Integer.toHexString(getCharCount())).append("\n");
263         buffer.append(" .optionflags = ")
264             .append(Integer.toHexString(getOptionFlags())).append("\n");
265         buffer.append(" .string = ").append(getString())
266             .append("\n");
267         buffer.append("[/UNICODESTRING]\n");
268         return buffer.toString();
269     }
270
271     public int serialize(int offset, byte [] data)
272     {
273         int charsize = 1;
274
275         if (getOptionFlags() == 1)
276         {
277             charsize = 2;
278         }
279
280         // byte[] retval = new byte[ 3 + (getString().length() * charsize)];
281
LittleEndian.putShort(data, 0 + offset, getCharCount());
282         data[ 2 + offset ] = getOptionFlags();
283
284 // System.out.println("Unicode: We've got "+retval[2]+" for our option flag");
285
try {
286             String JavaDoc unicodeString = new String JavaDoc(getString().getBytes("Unicode"),"Unicode");
287             if (getOptionFlags() == 0)
288             {
289                 StringUtil.putCompressedUnicode(unicodeString, data, 0x3 +offset);
290             }
291             else
292             {
293                 StringUtil.putUnicodeLE(unicodeString, data,
294                                                     0x3 + offset);
295             }
296         }
297         catch (Exception JavaDoc e) {
298             if (getOptionFlags() == 0)
299             {
300                 StringUtil.putCompressedUnicode(getString(), data, 0x3 +
301                                                 offset);
302             }
303             else
304             {
305                 StringUtil.putUnicodeLE(getString(), data,
306                                                   0x3 + offset);
307             }
308         }
309         return getRecordSize();
310     }
311
312     private boolean isUncompressedUnicode()
313     {
314         return (getOptionFlags() & 0x01) == 1;
315     }
316
317     public int getRecordSize()
318     {
319         int charsize = isUncompressedUnicode() ? 2 : 1;
320         return 3 + (getString().length() * charsize);
321     }
322
323     public short getSid()
324     {
325         return this.sid;
326     }
327
328     /**
329      * called by the constructor, should set class level fields. Should throw
330      * runtime exception for bad/icomplete data.
331      *
332      * @param data raw data
333      * @param size size of data
334      * @param offset of the records data (provided a big array of the file)
335      */

336
337     protected void fillFields(byte [] data, short size, int offset)
338     {
339     }
340
341     public int compareTo(Object JavaDoc obj)
342     {
343         UnicodeString str = ( UnicodeString ) obj;
344
345         return this.getString().compareTo(str.getString());
346     }
347
348     public boolean isRichText()
349     {
350         return (getOptionFlags() & RICH_TEXT_BIT) != 0;
351     }
352
353     int maxBrokenLength(final int proposedBrokenLength)
354     {
355         int rval = proposedBrokenLength;
356
357         if (isUncompressedUnicode())
358         {
359             int proposedStringLength = proposedBrokenLength - 3;
360
361             if ((proposedStringLength % 2) == 1)
362             {
363                 proposedStringLength--;
364             }
365             rval = proposedStringLength + 3;
366         }
367         return rval;
368     }
369
370     public boolean isExtendedText()
371     {
372         return (getOptionFlags() & EXT_BIT) != 0;
373     }
374
375 }
376
Popular Tags