KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hpsf > TypeReader


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

16
17 package org.apache.poi.hpsf;
18
19 import org.apache.poi.util.LittleEndian;
20
21 /**
22  * <p>Reader for specific data types.</p>
23  *
24  * @author Rainer Klute (klute@rainer-klute.de)
25  * @see Property
26  * @see Variant
27  * @version $Id: TypeReader.java,v 1.2.4.2 2004/02/22 11:54:45 glens Exp $
28  * @since 2002-12-09
29  */

30 public class TypeReader
31 {
32
33     /**
34      * <p>Reads a variant data type from a byte array.</p>
35      *
36      * @param src The byte array
37      * @param offset The offset in the byte array where the variant
38      * starts
39      * @param length The length of the variant including the variant
40      * type field
41      * @param type The variant type to read
42      * @return A Java object that corresponds best to the variant
43      * field. For example, a VT_I4 is returned as a {@link Long}, a
44      * VT_LPSTR as a {@link String}.
45      *
46      * @see Variant
47      */

48     public static Object JavaDoc read(final byte[] src, int offset, int length,
49                               final int type)
50     {
51         /*
52          * FIXME: Support reading more types and clean up this code!
53          */

54         Object JavaDoc value;
55         length = length - LittleEndian.INT_SIZE;
56         switch (type)
57         {
58             case Variant.VT_EMPTY:
59             {
60                 /*
61                  * FIXME: The value returned by this case relies on the
62                  * assumption that the value VT_EMPTY denotes consists of zero
63                  * bytes. I'd be glad if some could confirm or correct this.
64                  */

65                 value = null;
66                 break;
67             }
68             case Variant.VT_I2:
69             {
70                 /*
71                  * Read a short. In Java it is represented as an
72                  * Integer object.
73                  */

74                 value = new Integer JavaDoc(LittleEndian.getUShort(src, offset));
75                 break;
76             }
77             case Variant.VT_I4:
78             {
79                 /*
80                  * Read a word. In Java it is represented as a
81                  * Long object.
82                  */

83                 value = new Long JavaDoc(LittleEndian.getUInt(src, offset));
84                 break;
85             }
86             case Variant.VT_FILETIME:
87             {
88                 /*
89                  * Read a FILETIME object. In Java it is represented
90                  * as a Date object.
91                  */

92                 final long low = LittleEndian.getUInt(src, offset);
93                 offset += LittleEndian.INT_SIZE;
94                 final long high = LittleEndian.getUInt(src, offset);
95                 value = Util.filetimeToDate((int) high, (int) low);
96                 break;
97             }
98             case Variant.VT_LPSTR:
99             {
100                 /*
101                  * Read a byte string. In Java it is represented as a
102                  * String object. The 0x00 bytes at the end must be
103                  * stripped.
104                  *
105                  * FIXME: Reading an 8-bit string should pay attention
106                  * to the codepage. Currently the byte making out the
107                  * property's value are interpreted according to the
108                  * platform's default character set.
109                  */

110                 final int first = offset + LittleEndian.INT_SIZE;
111                 long last = first + LittleEndian.getUInt(src, offset) - 1;
112                 offset += LittleEndian.INT_SIZE;
113                 while (src[(int) last] == 0 && first <= last)
114                     last--;
115                 value = new String JavaDoc(src, (int) first, (int) (last - first + 1));
116                 break;
117             }
118             case Variant.VT_LPWSTR:
119             {
120                 /*
121                  * Read a Unicode string. In Java it is represented as
122                  * a String object. The 0x00 bytes at the end must be
123                  * stripped.
124                  */

125                 final int first = offset + LittleEndian.INT_SIZE;
126                 long last = first + LittleEndian.getUInt(src, offset) - 1;
127                 long l = last - first;
128                 offset += LittleEndian.INT_SIZE;
129                 StringBuffer JavaDoc b = new StringBuffer JavaDoc((int) (last - first));
130                 for (int i = 0; i <= l; i++)
131                 {
132                     final int i1 = offset + (i * 2);
133                     final int i2 = i1 + 1;
134                     b.append((char) ((src[i2] << 8) + src[i1]));
135                 }
136                 /* Strip 0x00 characters from the end of the string: */
137                 while (b.charAt(b.length() - 1) == 0x00)
138                     b.setLength(b.length() - 1);
139                 value = b.toString();
140                 break;
141             }
142             case Variant.VT_CF:
143             {
144                 final byte[] v = new byte[length];
145                 for (int i = 0; i < length; i++)
146                     v[i] = src[(int) (offset + i)];
147                 value = v;
148                 break;
149             }
150             case Variant.VT_BOOL:
151             {
152                 /*
153                  * The first four bytes in src, from src[offset] to
154                  * src[offset + 3] contain the DWord for VT_BOOL, so
155                  * skip it, we don't need it.
156                  */

157                 // final int first = offset + LittleEndian.INT_SIZE;
158
long bool = LittleEndian.getUInt(src, offset);
159                 if (bool != 0)
160                     value = new Boolean JavaDoc(true);
161                 else
162                     value = new Boolean JavaDoc(false);
163                 break;
164             }
165             default:
166             {
167                 final byte[] v = new byte[length];
168                 for (int i = 0; i < length; i++)
169                     v[i] = src[(int) (offset + i)];
170                 value = v;
171                 break;
172             }
173         }
174         return value;
175     }
176
177 }
178
Popular Tags