• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.jme3.export.binary;
34 
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39 
40 /**
41  * <code>ByteUtils</code> is a helper class for converting numeric primitives
42  * to and from byte representations.
43  *
44  * @author Joshua Slack
45  */
46 public class ByteUtils {
47 
48     /**
49      * Takes an InputStream and returns the complete byte content of it
50      *
51      * @param inputStream
52      *            The input stream to read from
53      * @return The byte array containing the data from the input stream
54      * @throws java.io.IOException
55      *             thrown if there is a problem reading from the input stream
56      *             provided
57      */
getByteContent(InputStream inputStream)58     public static byte[] getByteContent(InputStream inputStream)
59             throws IOException {
60         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(
61                 16 * 1024);
62         byte[] buffer = new byte[1024];
63         int byteCount = -1;
64         byte[] data = null;
65 
66         // Read the byte content into the output stream first
67         while ((byteCount = inputStream.read(buffer)) > 0) {
68             outputStream.write(buffer, 0, byteCount);
69         }
70 
71         // Set data with byte content from stream
72         data = outputStream.toByteArray();
73 
74         // Release resources
75         outputStream.close();
76 
77         return data;
78     }
79 
80 
81     // **********  byte <> short  METHODS  **********
82 
83     /**
84      * Writes a short out to an OutputStream.
85      *
86      * @param outputStream
87      *            The OutputStream the short will be written to
88      * @param value
89      *            The short to write
90      * @throws IOException
91      *             Thrown if there is a problem writing to the OutputStream
92      */
writeShort(OutputStream outputStream, short value)93     public static void writeShort(OutputStream outputStream, short value)
94             throws IOException {
95         byte[] byteArray = convertToBytes(value);
96 
97         outputStream.write(byteArray);
98 
99         return;
100     }
101 
convertToBytes(short value)102     public static byte[] convertToBytes(short value) {
103         byte[] byteArray = new byte[2];
104 
105         byteArray[0] = (byte) (value >> 8);
106         byteArray[1] = (byte) value;
107         return byteArray;
108     }
109 
110     /**
111      * Read in a short from an InputStream
112      *
113      * @param inputStream
114      *            The InputStream used to read the short
115      * @return A short, which is the next 2 bytes converted from the InputStream
116      * @throws IOException
117      *             Thrown if there is a problem reading from the InputStream
118      */
readShort(InputStream inputStream)119     public static short readShort(InputStream inputStream) throws IOException {
120         byte[] byteArray = new byte[2];
121 
122         // Read in the next 2 bytes
123         inputStream.read(byteArray);
124 
125         short number = convertShortFromBytes(byteArray);
126 
127         return number;
128     }
129 
convertShortFromBytes(byte[] byteArray)130     public static short convertShortFromBytes(byte[] byteArray) {
131         return convertShortFromBytes(byteArray, 0);
132     }
133 
convertShortFromBytes(byte[] byteArray, int offset)134     public static short convertShortFromBytes(byte[] byteArray, int offset) {
135         // Convert it to a short
136         short number = (short) ((byteArray[offset+1] & 0xFF) + ((byteArray[offset+0] & 0xFF) << 8));
137         return number;
138     }
139 
140 
141     // **********  byte <> int  METHODS  **********
142 
143     /**
144      * Writes an integer out to an OutputStream.
145      *
146      * @param outputStream
147      *            The OutputStream the integer will be written to
148      * @param integer
149      *            The integer to write
150      * @throws IOException
151      *             Thrown if there is a problem writing to the OutputStream
152      */
writeInt(OutputStream outputStream, int integer)153     public static void writeInt(OutputStream outputStream, int integer)
154             throws IOException {
155         byte[] byteArray = convertToBytes(integer);
156 
157         outputStream.write(byteArray);
158 
159         return;
160     }
161 
convertToBytes(int integer)162     public static byte[] convertToBytes(int integer) {
163         byte[] byteArray = new byte[4];
164 
165         byteArray[0] = (byte) (integer >> 24);
166         byteArray[1] = (byte) (integer >> 16);
167         byteArray[2] = (byte) (integer >> 8);
168         byteArray[3] = (byte) integer;
169         return byteArray;
170     }
171 
172     /**
173      * Read in an integer from an InputStream
174      *
175      * @param inputStream
176      *            The InputStream used to read the integer
177      * @return An int, which is the next 4 bytes converted from the InputStream
178      * @throws IOException
179      *             Thrown if there is a problem reading from the InputStream
180      */
readInt(InputStream inputStream)181     public static int readInt(InputStream inputStream) throws IOException {
182         byte[] byteArray = new byte[4];
183 
184         // Read in the next 4 bytes
185         inputStream.read(byteArray);
186 
187         int number = convertIntFromBytes(byteArray);
188 
189         return number;
190     }
191 
convertIntFromBytes(byte[] byteArray)192     public static int convertIntFromBytes(byte[] byteArray) {
193         return convertIntFromBytes(byteArray, 0);
194     }
195 
convertIntFromBytes(byte[] byteArray, int offset)196     public static int convertIntFromBytes(byte[] byteArray, int offset) {
197         // Convert it to an int
198         int number = ((byteArray[offset] & 0xFF) << 24)
199                 + ((byteArray[offset+1] & 0xFF) << 16) + ((byteArray[offset+2] & 0xFF) << 8)
200                 + (byteArray[offset+3] & 0xFF);
201         return number;
202     }
203 
204 
205     // **********  byte <> long  METHODS  **********
206 
207     /**
208      * Writes a long out to an OutputStream.
209      *
210      * @param outputStream
211      *            The OutputStream the long will be written to
212      * @param value
213      *            The long to write
214      * @throws IOException
215      *             Thrown if there is a problem writing to the OutputStream
216      */
writeLong(OutputStream outputStream, long value)217     public static void writeLong(OutputStream outputStream, long value)
218             throws IOException {
219         byte[] byteArray = convertToBytes(value);
220 
221         outputStream.write(byteArray);
222 
223         return;
224     }
225 
convertToBytes(long n)226     public static byte[] convertToBytes(long n) {
227         byte[] bytes = new byte[8];
228 
229         bytes[7] = (byte) (n);
230         n >>>= 8;
231         bytes[6] = (byte) (n);
232         n >>>= 8;
233         bytes[5] = (byte) (n);
234         n >>>= 8;
235         bytes[4] = (byte) (n);
236         n >>>= 8;
237         bytes[3] = (byte) (n);
238         n >>>= 8;
239         bytes[2] = (byte) (n);
240         n >>>= 8;
241         bytes[1] = (byte) (n);
242         n >>>= 8;
243         bytes[0] = (byte) (n);
244 
245         return bytes;
246     }
247 
248     /**
249      * Read in a long from an InputStream
250      *
251      * @param inputStream
252      *            The InputStream used to read the long
253      * @return A long, which is the next 8 bytes converted from the InputStream
254      * @throws IOException
255      *             Thrown if there is a problem reading from the InputStream
256      */
readLong(InputStream inputStream)257     public static long readLong(InputStream inputStream) throws IOException {
258         byte[] byteArray = new byte[8];
259 
260         // Read in the next 8 bytes
261         inputStream.read(byteArray);
262 
263         long number = convertLongFromBytes(byteArray);
264 
265         return number;
266     }
267 
convertLongFromBytes(byte[] bytes)268     public static long convertLongFromBytes(byte[] bytes) {
269         return convertLongFromBytes(bytes, 0);
270     }
271 
convertLongFromBytes(byte[] bytes, int offset)272     public static long convertLongFromBytes(byte[] bytes, int offset) {
273         // Convert it to an long
274         return    ((((long) bytes[offset+7]) & 0xFF)
275                 + ((((long) bytes[offset+6]) & 0xFF) << 8)
276                 + ((((long) bytes[offset+5]) & 0xFF) << 16)
277                 + ((((long) bytes[offset+4]) & 0xFF) << 24)
278                 + ((((long) bytes[offset+3]) & 0xFF) << 32)
279                 + ((((long) bytes[offset+2]) & 0xFF) << 40)
280                 + ((((long) bytes[offset+1]) & 0xFF) << 48)
281                 + ((((long) bytes[offset+0]) & 0xFF) << 56));
282     }
283 
284 
285     // **********  byte <> double  METHODS  **********
286 
287     /**
288      * Writes a double out to an OutputStream.
289      *
290      * @param outputStream
291      *            The OutputStream the double will be written to
292      * @param value
293      *            The double to write
294      * @throws IOException
295      *             Thrown if there is a problem writing to the OutputStream
296      */
writeDouble(OutputStream outputStream, double value)297     public static void writeDouble(OutputStream outputStream, double value)
298             throws IOException {
299         byte[] byteArray = convertToBytes(value);
300 
301         outputStream.write(byteArray);
302 
303         return;
304     }
305 
convertToBytes(double n)306     public static byte[] convertToBytes(double n) {
307         long bits = Double.doubleToLongBits(n);
308         return convertToBytes(bits);
309     }
310 
311     /**
312      * Read in a double from an InputStream
313      *
314      * @param inputStream
315      *            The InputStream used to read the double
316      * @return A double, which is the next 8 bytes converted from the InputStream
317      * @throws IOException
318      *             Thrown if there is a problem reading from the InputStream
319      */
readDouble(InputStream inputStream)320     public static double readDouble(InputStream inputStream) throws IOException {
321         byte[] byteArray = new byte[8];
322 
323         // Read in the next 8 bytes
324         inputStream.read(byteArray);
325 
326         double number = convertDoubleFromBytes(byteArray);
327 
328         return number;
329     }
330 
convertDoubleFromBytes(byte[] bytes)331     public static double convertDoubleFromBytes(byte[] bytes) {
332         return convertDoubleFromBytes(bytes, 0);
333     }
334 
convertDoubleFromBytes(byte[] bytes, int offset)335     public static double convertDoubleFromBytes(byte[] bytes, int offset) {
336         // Convert it to a double
337         long bits = convertLongFromBytes(bytes, offset);
338         return Double.longBitsToDouble(bits);
339     }
340 
341     //  **********  byte <> float  METHODS  **********
342 
343     /**
344      * Writes an float out to an OutputStream.
345      *
346      * @param outputStream
347      *            The OutputStream the float will be written to
348      * @param fVal
349      *            The float to write
350      * @throws IOException
351      *             Thrown if there is a problem writing to the OutputStream
352      */
writeFloat(OutputStream outputStream, float fVal)353     public static void writeFloat(OutputStream outputStream, float fVal)
354             throws IOException {
355         byte[] byteArray = convertToBytes(fVal);
356 
357         outputStream.write(byteArray);
358 
359         return;
360     }
361 
convertToBytes(float f)362     public static byte[] convertToBytes(float f) {
363         int temp = Float.floatToIntBits(f);
364         return convertToBytes(temp);
365     }
366 
367     /**
368      * Read in a float from an InputStream
369      *
370      * @param inputStream
371      *            The InputStream used to read the float
372      * @return A float, which is the next 4 bytes converted from the InputStream
373      * @throws IOException
374      *             Thrown if there is a problem reading from the InputStream
375      */
readFloat(InputStream inputStream)376     public static float readFloat(InputStream inputStream) throws IOException {
377         byte[] byteArray = new byte[4];
378 
379         // Read in the next 4 bytes
380         inputStream.read(byteArray);
381 
382         float number = convertFloatFromBytes(byteArray);
383 
384         return number;
385     }
386 
convertFloatFromBytes(byte[] byteArray)387     public static float convertFloatFromBytes(byte[] byteArray) {
388         return convertFloatFromBytes(byteArray, 0);
389     }
convertFloatFromBytes(byte[] byteArray, int offset)390     public static float convertFloatFromBytes(byte[] byteArray, int offset) {
391         // Convert it to an int
392         int number = convertIntFromBytes(byteArray, offset);
393         return Float.intBitsToFloat(number);
394     }
395 
396 
397 
398     //  **********  byte <> boolean  METHODS  **********
399 
400     /**
401      * Writes a boolean out to an OutputStream.
402      *
403      * @param outputStream
404      *            The OutputStream the boolean will be written to
405      * @param bVal
406      *            The boolean to write
407      * @throws IOException
408      *             Thrown if there is a problem writing to the OutputStream
409      */
writeBoolean(OutputStream outputStream, boolean bVal)410     public static void writeBoolean(OutputStream outputStream, boolean bVal)
411             throws IOException {
412         byte[] byteArray = convertToBytes(bVal);
413 
414         outputStream.write(byteArray);
415 
416         return;
417     }
418 
convertToBytes(boolean b)419     public static byte[] convertToBytes(boolean b) {
420         byte[] rVal = new byte[1];
421         rVal[0] = b ? (byte)1 : (byte)0;
422         return rVal;
423     }
424 
425     /**
426      * Read in a boolean from an InputStream
427      *
428      * @param inputStream
429      *            The InputStream used to read the boolean
430      * @return A boolean, which is the next byte converted from the InputStream (iow, byte != 0)
431      * @throws IOException
432      *             Thrown if there is a problem reading from the InputStream
433      */
readBoolean(InputStream inputStream)434     public static boolean readBoolean(InputStream inputStream) throws IOException {
435         byte[] byteArray = new byte[1];
436 
437         // Read in the next byte
438         inputStream.read(byteArray);
439 
440         return convertBooleanFromBytes(byteArray);
441     }
442 
convertBooleanFromBytes(byte[] byteArray)443     public static boolean convertBooleanFromBytes(byte[] byteArray) {
444         return convertBooleanFromBytes(byteArray, 0);
445     }
convertBooleanFromBytes(byte[] byteArray, int offset)446     public static boolean convertBooleanFromBytes(byte[] byteArray, int offset) {
447         return byteArray[offset] != 0;
448     }
449 
450 
451     /**
452      * Properly reads in data from the given stream until the specified number
453      * of bytes have been read.
454      *
455      * @param store
456      *            the byte array to store in. Should have a length > bytes
457      * @param bytes
458      *            the number of bytes to read.
459      * @param is
460      *            the stream to read from
461      * @return the store array for chaining purposes
462      * @throws IOException
463      *             if an error occurs while reading from the stream
464      * @throws ArrayIndexOutOfBoundsException
465      *             if bytes greater than the length of the store.
466      */
readData(byte[] store, int bytes, InputStream is)467     public static byte[] readData(byte[] store, int bytes, InputStream is) throws IOException {
468         for (int i = 0; i < bytes; i++) {
469             store[i] = (byte)is.read();
470         }
471         return store;
472     }
473 
rightAlignBytes(byte[] bytes, int width)474     public static byte[] rightAlignBytes(byte[] bytes, int width) {
475         if (bytes.length != width) {
476             byte[] rVal = new byte[width];
477             for (int x = width - bytes.length; x < width; x++) {
478                 rVal[x] = bytes[x - (width - bytes.length)];
479             }
480             return rVal;
481         }
482 
483         return bytes;
484     }
485 
486 }
487