KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > util > LittleEndian


1 /* ====================================================================
2    Copyright 2003-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.util;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.util.Arrays JavaDoc;
22
23 /**
24  * a utility class for handling little-endian numbers, which the 80x86 world is
25  * replete with. The methods are all static, and input/output is from/to byte
26  * arrays, or from InputStreams.
27  *
28  *@author Marc Johnson (mjohnson at apache dot org)
29  *@author Andrew Oliver (acoliver at apache dot org)
30  */

31
32 public class LittleEndian
33          implements LittleEndianConsts {
34
35     // all methods are static, so an accessible constructor makes no
36
// sense
37
/**
38      * Constructor for the LittleEndian object
39      */

40     private LittleEndian() { }
41
42
43     /**
44      * get a short value from a byte array
45      *
46      *@param data the byte array
47      *@param offset a starting offset into the byte array
48      *@return the short (16-bit) value
49      */

50
51     public static short getShort(final byte[] data, final int offset) {
52         return (short) getNumber(data, offset, SHORT_SIZE);
53     }
54
55
56     /**
57      * get an unsigned short value from a byte array
58      *
59      *@param data the byte array
60      *@param offset a starting offset into the byte array
61      *@return the unsigned short (16-bit) value in an integer
62      */

63     public static int getUShort(final byte[] data, final int offset) {
64         short num = (short) getNumber(data, offset, SHORT_SIZE);
65         int retNum;
66         if (num < 0) {
67             retNum = ((int) Short.MAX_VALUE + 1) * 2 + (int) num;
68         } else {
69             retNum = (int) num;
70         }
71         return retNum;
72     }
73
74
75     /**
76      * get a short array from a byte array.
77      *
78      *@param data Description of the Parameter
79      *@param offset Description of the Parameter
80      *@param size Description of the Parameter
81      *@return The simpleShortArray value
82      */

83     public static short[] getSimpleShortArray(final byte[] data, final int offset, final int size) {
84         short[] results = new short[size];
85         for (int i = 0; i < size; i++) {
86             results[i] = getShort(data, offset + 2 + (i * 2));
87         }
88         return results;
89     }
90
91
92     /**
93      * get a short array from a byte array. The short array is assumed to start
94      * with a word describing the length of the array.
95      *
96      *@param data Description of the Parameter
97      *@param offset Description of the Parameter
98      *@return The shortArray value
99      */

100     public static short[] getShortArray(final byte[] data, final int offset) {
101         int size = (int) getNumber(data, offset, SHORT_SIZE);
102         short[] results = getSimpleShortArray(data, offset, size);
103         return results;
104     }
105
106
107     /**
108      * get a short value from the beginning of a byte array
109      *
110      *@param data the byte array
111      *@return the short (16-bit) value
112      */

113
114     public static short getShort(final byte[] data) {
115         return getShort(data, 0);
116     }
117
118
119     /**
120      * get an unsigned short value from the beginning of a byte array
121      *
122      *@param data the byte array
123      *@return the unsigned short (16-bit) value in an int
124      */

125     public static int getUShort(final byte[] data) {
126         return getUShort(data, 0);
127     }
128
129
130     /**
131      * get an int value from a byte array
132      *
133      *@param data the byte array
134      *@param offset a starting offset into the byte array
135      *@return the int (32-bit) value
136      */

137
138     public static int getInt(final byte[] data, final int offset) {
139         return (int) getNumber(data, offset, INT_SIZE);
140     }
141
142
143     /**
144      * get an int value from the beginning of a byte array
145      *
146      *@param data the byte array
147      *@return the int (32-bit) value
148      */

149
150     public static int getInt(final byte[] data) {
151         return getInt(data, 0);
152     }
153
154
155     /**
156      * get an unsigned int value from a byte array
157      *
158      *@param data the byte array
159      *@param offset a starting offset into the byte array
160      *@return the unsigned int (32-bit) value in a long
161      */

162     public static long getUInt(final byte[] data, final int offset) {
163         int num = (int) getNumber(data, offset, INT_SIZE);
164         long retNum;
165         if (num < 0) {
166             retNum = ((long) Integer.MAX_VALUE + 1) * 2 + (long) num;
167         } else {
168             retNum = (int) num;
169         }
170         return retNum;
171     }
172
173     /**
174      * get an unsigned int value from a byte array
175      *
176      *@param data the byte array
177      *@return the unsigned int (32-bit) value in a long
178      */

179     public static long getUInt(final byte[] data) {
180     return getUInt(data,0);
181     }
182
183     /**
184      * get a long value from a byte array
185      *
186      *@param data the byte array
187      *@param offset a starting offset into the byte array
188      *@return the long (64-bit) value
189      */

190
191     public static long getLong(final byte[] data, final int offset) {
192         return getNumber(data, offset, LONG_SIZE);
193     }
194
195
196     /**
197      * get a long value from the beginning of a byte array
198      *
199      *@param data the byte array
200      *@return the long (64-bit) value
201      */

202
203     public static long getLong(final byte[] data) {
204         return getLong(data, 0);
205     }
206
207
208     /**
209      * get a double value from a byte array, reads it in little endian format
210      * then converts the resulting revolting IEEE 754 (curse them) floating
211      * point number to a happy java double
212      *
213      *@param data the byte array
214      *@param offset a starting offset into the byte array
215      *@return the double (64-bit) value
216      */

217
218     public static double getDouble(final byte[] data, final int offset) {
219         return Double.longBitsToDouble(getNumber(data, offset, DOUBLE_SIZE));
220     }
221
222
223     /**
224      * get a double value from the beginning of a byte array
225      *
226      *@param data the byte array
227      *@return the double (64-bit) value
228      */

229
230     public static double getDouble(final byte[] data) {
231         return getDouble(data, 0);
232     }
233
234
235     /**
236      * put a short value into a byte array
237      *
238      *@param data the byte array
239      *@param offset a starting offset into the byte array
240      *@param value the short (16-bit) value
241      */

242     public static void putShort(final byte[] data, final int offset,
243             final short value) {
244         putNumber(data, offset, value, SHORT_SIZE);
245     }
246
247
248     /**
249      * put a array of shorts into a byte array
250      *
251      *@param data the byte array
252      *@param offset a starting offset into the byte array
253      *@param value the short array
254      */

255     public static void putShortArray(final byte[] data, final int offset, final short[] value) {
256         putNumber(data, offset, value.length, SHORT_SIZE);
257         for (int i = 0; i < value.length; i++) {
258             putNumber(data, offset + 2 + (i * 2), value[i], SHORT_SIZE);
259         }
260     }
261
262     /**
263      * put an unsigned short value into a byte array
264      *
265      * @param data the byte array
266      * @param offset a starting offset into the byte array
267      * @param value the short (16-bit) value
268      *
269      * @exception ArrayIndexOutOfBoundsException may be thrown
270      */

271     public static void putUShort(final byte[] data, final int offset,
272                                 final int value)
273     {
274         putNumber(data, offset, value, SHORT_SIZE);
275     }
276
277     /**
278      * put a short value into beginning of a byte array
279      *
280      *@param data the byte array
281      *@param value the short (16-bit) value
282      */

283
284     public static void putShort(final byte[] data, final short value) {
285         putShort(data, 0, value);
286     }
287
288
289     /**
290      * put an int value into a byte array
291      *
292      *@param data the byte array
293      *@param offset a starting offset into the byte array
294      *@param value the int (32-bit) value
295      */

296
297     public static void putInt(final byte[] data, final int offset,
298             final int value) {
299         putNumber(data, offset, value, INT_SIZE);
300     }
301
302
303     /**
304      * put an int value into beginning of a byte array
305      *
306      *@param data the byte array
307      *@param value the int (32-bit) value
308      */

309
310     public static void putInt(final byte[] data, final int value) {
311         putInt(data, 0, value);
312     }
313
314
315     /**
316      * put a long value into a byte array
317      *
318      *@param data the byte array
319      *@param offset a starting offset into the byte array
320      *@param value the long (64-bit) value
321      */

322
323     public static void putLong(final byte[] data, final int offset,
324             final long value) {
325         putNumber(data, offset, value, LONG_SIZE);
326     }
327
328
329     /**
330      * put a long value into beginning of a byte array
331      *
332      *@param data the byte array
333      *@param value the long (64-bit) value
334      */

335
336     public static void putLong(final byte[] data, final long value) {
337         putLong(data, 0, value);
338     }
339
340
341     /**
342      * put a double value into a byte array
343      *
344      *@param data the byte array
345      *@param offset a starting offset into the byte array
346      *@param value the double (64-bit) value
347      */

348
349     public static void putDouble(final byte[] data, final int offset,
350             final double value) {
351         // Excel likes NaN to be a specific value.
352
if (Double.isNaN(value))
353             putNumber(data, offset, -276939487313920L, DOUBLE_SIZE);
354         else
355             putNumber(data, offset, Double.doubleToLongBits(value), DOUBLE_SIZE);
356     }
357
358
359     /**
360      * put a double value into beginning of a byte array
361      *
362      *@param data the byte array
363      *@param value the double (64-bit) value
364      */

365
366     public static void putDouble(final byte[] data, final double value) {
367         putDouble(data, 0, value);
368     }
369
370
371     /**
372      * Exception to handle buffer underruns
373      *
374      *@author Marc Johnson (mjohnson at apache dot org)
375      */

376
377     public static class BufferUnderrunException
378              extends IOException JavaDoc {
379
380         /**
381          * simple constructor
382          */

383
384         BufferUnderrunException() {
385             super("buffer underrun");
386         }
387     }
388
389
390     /**
391      * get a short value from an InputStream
392      *
393      *@param stream the InputStream from which the short
394      * is to be read
395      *@return the short (16-bit) value
396      *@exception IOException will be propagated back to the caller
397      *@exception BufferUnderrunException if the stream cannot provide enough
398      * bytes
399      */

400
401     public static short readShort(final InputStream JavaDoc stream)
402              throws IOException JavaDoc, BufferUnderrunException {
403         return getShort(readFromStream(stream, SHORT_SIZE));
404     }
405
406
407     /**
408      * get an int value from an InputStream
409      *
410      *@param stream the InputStream from which the int is
411      * to be read
412      *@return the int (32-bit) value
413      *@exception IOException will be propagated back to the caller
414      *@exception BufferUnderrunException if the stream cannot provide enough
415      * bytes
416      */

417
418     public static int readInt(final InputStream JavaDoc stream)
419              throws IOException JavaDoc, BufferUnderrunException {
420         return getInt(readFromStream(stream, INT_SIZE));
421     }
422
423
424     /**
425      * get a long value from an InputStream
426      *
427      *@param stream the InputStream from which the long
428      * is to be read
429      *@return the long (64-bit) value
430      *@exception IOException will be propagated back to the caller
431      *@exception BufferUnderrunException if the stream cannot provide enough
432      * bytes
433      */

434
435     public static long readLong(final InputStream JavaDoc stream)
436              throws IOException JavaDoc, BufferUnderrunException {
437         return getLong(readFromStream(stream, LONG_SIZE));
438     }
439
440     /**
441      * Read the appropriate number of bytes from the stream and return them to
442      * the caller. <p>
443      *
444      * However, for the purposes of the POI project, this risk is deemed
445      * negligible. It is, however, so noted.
446      *
447      *@param stream the InputStream we're reading from
448      *@param size the number of bytes to read; in
449      * 99.99% of cases, this will be SHORT_SIZE, INT_SIZE, or LONG_SIZE --
450      * but it doesn't have to be.
451      *@return the byte array containing the
452      * required number of bytes. The array will contain all zero's on end
453      * of stream
454      *@exception IOException will be propagated back to the caller
455      *@exception BufferUnderrunException if the stream cannot provide enough
456      * bytes
457      */

458
459     public static byte[] readFromStream(final InputStream JavaDoc stream,
460             final int size)
461              throws IOException JavaDoc, BufferUnderrunException {
462         byte[] buffer = new byte[size];
463
464         int count = stream.read(buffer);
465
466         if (count == -1) {
467
468             // return a zero-filled buffer
469
Arrays.fill(buffer, (byte) 0);
470         } else if (count != size) {
471             throw new BufferUnderrunException();
472         }
473         return buffer;
474     }
475
476
477     /**
478      * Gets the number attribute of the LittleEndian class
479      *
480      *@param data Description of the Parameter
481      *@param offset Description of the Parameter
482      *@param size Description of the Parameter
483      *@return The number value
484      */

485     private static long getNumber(final byte[] data, final int offset,
486             final int size) {
487         long result = 0;
488
489         for (int j = offset + size - 1; j >= offset; j--) {
490             result <<= 8;
491             result |= 0xff & data[j];
492         }
493         return result;
494     }
495
496
497     /**
498      * Description of the Method
499      *
500      *@param data Description of the Parameter
501      *@param offset Description of the Parameter
502      *@param value Description of the Parameter
503      *@param size Description of the Parameter
504      */

505     private static void putNumber(final byte[] data, final int offset,
506             final long value, final int size) {
507         int limit = size + offset;
508         long v = value;
509
510         for (int j = offset; j < limit; j++) {
511             data[j] = (byte) (v & 0xFF);
512             v >>= 8;
513         }
514     }
515
516
517     /**
518      * Convert an 'unsigned' byte to an integer. ie, don't carry across the
519      * sign.
520      *
521      *@param b Description of the Parameter
522      *@return Description of the Return Value
523      */

524     public static int ubyteToInt(byte b) {
525         return ((b & 0x80) == 0 ? (int) b : (int) (b & (byte) 0x7f) + 0x80);
526     }
527
528
529     /**
530      * get the unsigned value of a byte.
531      *
532      *@param data the byte array.
533      *@param offset a starting offset into the byte array.
534      *@return the unsigned value of the byte as a 32 bit integer
535      */

536     public static int getUnsignedByte(final byte[] data, final int offset) {
537         return (int) getNumber(data, offset, BYTE_SIZE);
538     }
539
540
541     /**
542      * get the unsigned value of a byte.
543      *
544      *@param data the byte array
545      *@return the unsigned value of the byte as a 32 bit integer
546      */

547     public static int getUnsignedByte(final byte[] data) {
548         return getUnsignedByte(data, 0);
549     }
550
551
552     /**
553      * Copy a portion of a byte array
554      *
555      *@param data the original byte array
556      *@param offset Where to start copying from.
557      *@param size Number of bytes to copy.
558      *@return The byteArray value
559      *@throws IndexOutOfBoundsException - if copying would cause access of
560      * data outside array bounds.
561      */

562     public static byte[] getByteArray(final byte[] data, int offset, int size) {
563         byte[] copy = new byte[size];
564         System.arraycopy(data, offset, copy, 0, size);
565
566         return copy;
567     }
568
569
570 }
571
Popular Tags