blob: bb835d0ab11c3d9ec54c0429889e826fa2bedcb4 [file] [log] [blame]
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.export.binary;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* <code>ByteUtils</code> is a helper class for converting numeric primitives
* to and from byte representations.
*
* @author Joshua Slack
*/
public class ByteUtils {
/**
* Takes an InputStream and returns the complete byte content of it
*
* @param inputStream
* The input stream to read from
* @return The byte array containing the data from the input stream
* @throws java.io.IOException
* thrown if there is a problem reading from the input stream
* provided
*/
public static byte[] getByteContent(InputStream inputStream)
throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(
16 * 1024);
byte[] buffer = new byte[1024];
int byteCount = -1;
byte[] data = null;
// Read the byte content into the output stream first
while ((byteCount = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, byteCount);
}
// Set data with byte content from stream
data = outputStream.toByteArray();
// Release resources
outputStream.close();
return data;
}
// ********** byte <> short METHODS **********
/**
* Writes a short out to an OutputStream.
*
* @param outputStream
* The OutputStream the short will be written to
* @param value
* The short to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeShort(OutputStream outputStream, short value)
throws IOException {
byte[] byteArray = convertToBytes(value);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(short value) {
byte[] byteArray = new byte[2];
byteArray[0] = (byte) (value >> 8);
byteArray[1] = (byte) value;
return byteArray;
}
/**
* Read in a short from an InputStream
*
* @param inputStream
* The InputStream used to read the short
* @return A short, which is the next 2 bytes converted from the InputStream
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static short readShort(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[2];
// Read in the next 2 bytes
inputStream.read(byteArray);
short number = convertShortFromBytes(byteArray);
return number;
}
public static short convertShortFromBytes(byte[] byteArray) {
return convertShortFromBytes(byteArray, 0);
}
public static short convertShortFromBytes(byte[] byteArray, int offset) {
// Convert it to a short
short number = (short) ((byteArray[offset+1] & 0xFF) + ((byteArray[offset+0] & 0xFF) << 8));
return number;
}
// ********** byte <> int METHODS **********
/**
* Writes an integer out to an OutputStream.
*
* @param outputStream
* The OutputStream the integer will be written to
* @param integer
* The integer to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeInt(OutputStream outputStream, int integer)
throws IOException {
byte[] byteArray = convertToBytes(integer);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(int integer) {
byte[] byteArray = new byte[4];
byteArray[0] = (byte) (integer >> 24);
byteArray[1] = (byte) (integer >> 16);
byteArray[2] = (byte) (integer >> 8);
byteArray[3] = (byte) integer;
return byteArray;
}
/**
* Read in an integer from an InputStream
*
* @param inputStream
* The InputStream used to read the integer
* @return An int, which is the next 4 bytes converted from the InputStream
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static int readInt(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[4];
// Read in the next 4 bytes
inputStream.read(byteArray);
int number = convertIntFromBytes(byteArray);
return number;
}
public static int convertIntFromBytes(byte[] byteArray) {
return convertIntFromBytes(byteArray, 0);
}
public static int convertIntFromBytes(byte[] byteArray, int offset) {
// Convert it to an int
int number = ((byteArray[offset] & 0xFF) << 24)
+ ((byteArray[offset+1] & 0xFF) << 16) + ((byteArray[offset+2] & 0xFF) << 8)
+ (byteArray[offset+3] & 0xFF);
return number;
}
// ********** byte <> long METHODS **********
/**
* Writes a long out to an OutputStream.
*
* @param outputStream
* The OutputStream the long will be written to
* @param value
* The long to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeLong(OutputStream outputStream, long value)
throws IOException {
byte[] byteArray = convertToBytes(value);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(long n) {
byte[] bytes = new byte[8];
bytes[7] = (byte) (n);
n >>>= 8;
bytes[6] = (byte) (n);
n >>>= 8;
bytes[5] = (byte) (n);
n >>>= 8;
bytes[4] = (byte) (n);
n >>>= 8;
bytes[3] = (byte) (n);
n >>>= 8;
bytes[2] = (byte) (n);
n >>>= 8;
bytes[1] = (byte) (n);
n >>>= 8;
bytes[0] = (byte) (n);
return bytes;
}
/**
* Read in a long from an InputStream
*
* @param inputStream
* The InputStream used to read the long
* @return A long, which is the next 8 bytes converted from the InputStream
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static long readLong(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[8];
// Read in the next 8 bytes
inputStream.read(byteArray);
long number = convertLongFromBytes(byteArray);
return number;
}
public static long convertLongFromBytes(byte[] bytes) {
return convertLongFromBytes(bytes, 0);
}
public static long convertLongFromBytes(byte[] bytes, int offset) {
// Convert it to an long
return ((((long) bytes[offset+7]) & 0xFF)
+ ((((long) bytes[offset+6]) & 0xFF) << 8)
+ ((((long) bytes[offset+5]) & 0xFF) << 16)
+ ((((long) bytes[offset+4]) & 0xFF) << 24)
+ ((((long) bytes[offset+3]) & 0xFF) << 32)
+ ((((long) bytes[offset+2]) & 0xFF) << 40)
+ ((((long) bytes[offset+1]) & 0xFF) << 48)
+ ((((long) bytes[offset+0]) & 0xFF) << 56));
}
// ********** byte <> double METHODS **********
/**
* Writes a double out to an OutputStream.
*
* @param outputStream
* The OutputStream the double will be written to
* @param value
* The double to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeDouble(OutputStream outputStream, double value)
throws IOException {
byte[] byteArray = convertToBytes(value);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(double n) {
long bits = Double.doubleToLongBits(n);
return convertToBytes(bits);
}
/**
* Read in a double from an InputStream
*
* @param inputStream
* The InputStream used to read the double
* @return A double, which is the next 8 bytes converted from the InputStream
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static double readDouble(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[8];
// Read in the next 8 bytes
inputStream.read(byteArray);
double number = convertDoubleFromBytes(byteArray);
return number;
}
public static double convertDoubleFromBytes(byte[] bytes) {
return convertDoubleFromBytes(bytes, 0);
}
public static double convertDoubleFromBytes(byte[] bytes, int offset) {
// Convert it to a double
long bits = convertLongFromBytes(bytes, offset);
return Double.longBitsToDouble(bits);
}
// ********** byte <> float METHODS **********
/**
* Writes an float out to an OutputStream.
*
* @param outputStream
* The OutputStream the float will be written to
* @param fVal
* The float to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeFloat(OutputStream outputStream, float fVal)
throws IOException {
byte[] byteArray = convertToBytes(fVal);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(float f) {
int temp = Float.floatToIntBits(f);
return convertToBytes(temp);
}
/**
* Read in a float from an InputStream
*
* @param inputStream
* The InputStream used to read the float
* @return A float, which is the next 4 bytes converted from the InputStream
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static float readFloat(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[4];
// Read in the next 4 bytes
inputStream.read(byteArray);
float number = convertFloatFromBytes(byteArray);
return number;
}
public static float convertFloatFromBytes(byte[] byteArray) {
return convertFloatFromBytes(byteArray, 0);
}
public static float convertFloatFromBytes(byte[] byteArray, int offset) {
// Convert it to an int
int number = convertIntFromBytes(byteArray, offset);
return Float.intBitsToFloat(number);
}
// ********** byte <> boolean METHODS **********
/**
* Writes a boolean out to an OutputStream.
*
* @param outputStream
* The OutputStream the boolean will be written to
* @param bVal
* The boolean to write
* @throws IOException
* Thrown if there is a problem writing to the OutputStream
*/
public static void writeBoolean(OutputStream outputStream, boolean bVal)
throws IOException {
byte[] byteArray = convertToBytes(bVal);
outputStream.write(byteArray);
return;
}
public static byte[] convertToBytes(boolean b) {
byte[] rVal = new byte[1];
rVal[0] = b ? (byte)1 : (byte)0;
return rVal;
}
/**
* Read in a boolean from an InputStream
*
* @param inputStream
* The InputStream used to read the boolean
* @return A boolean, which is the next byte converted from the InputStream (iow, byte != 0)
* @throws IOException
* Thrown if there is a problem reading from the InputStream
*/
public static boolean readBoolean(InputStream inputStream) throws IOException {
byte[] byteArray = new byte[1];
// Read in the next byte
inputStream.read(byteArray);
return convertBooleanFromBytes(byteArray);
}
public static boolean convertBooleanFromBytes(byte[] byteArray) {
return convertBooleanFromBytes(byteArray, 0);
}
public static boolean convertBooleanFromBytes(byte[] byteArray, int offset) {
return byteArray[offset] != 0;
}
/**
* Properly reads in data from the given stream until the specified number
* of bytes have been read.
*
* @param store
* the byte array to store in. Should have a length > bytes
* @param bytes
* the number of bytes to read.
* @param is
* the stream to read from
* @return the store array for chaining purposes
* @throws IOException
* if an error occurs while reading from the stream
* @throws ArrayIndexOutOfBoundsException
* if bytes greater than the length of the store.
*/
public static byte[] readData(byte[] store, int bytes, InputStream is) throws IOException {
for (int i = 0; i < bytes; i++) {
store[i] = (byte)is.read();
}
return store;
}
public static byte[] rightAlignBytes(byte[] bytes, int width) {
if (bytes.length != width) {
byte[] rVal = new byte[width];
for (int x = width - bytes.length; x < width; x++) {
rVal[x] = bytes[x - (width - bytes.length)];
}
return rVal;
}
return bytes;
}
}