package org.hipi.util;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.nio.DoubleBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Various static helper methods that come in handy when serializing and deserializing arrays of
* different Java types and performing certain operations with byte arrays like conversion to
* string and computing hashes.
*/
public class ByteUtils {
/**
* Reads the contents of an stream until exhausted and converts contents to an array of bytes.
*
* @param stream
*/
public static byte[] inputStreamToByteArray(InputStream stream) throws IOException {
if (stream == null) {
return new byte[] {};
}
byte[] buffer = new byte[1024];
ByteArrayOutputStream output = new ByteArrayOutputStream();
boolean error = false;
try {
int numRead = 0;
while ((numRead = stream.read(buffer)) > -1) {
output.write(buffer, 0, numRead);
}
} catch (IOException ioe) {
error = true; // this error should be thrown, even if there is an error closing stream
throw ioe;
} catch (RuntimeException re) {
error = true; // this error should be thrown, even if there is an error closing stream
throw re;
} finally {
try {
stream.close();
} catch (IOException ioe) {
if (!error) {
throw ioe;
}
}
}
output.flush();
return output.toByteArray();
}
/**
* Convert from a byte array to one int
*
* @param byteArray
*/
public static final int byteArrayToInt(byte[] byteArray) {
return byteArrayToInt(byteArray, 0);
}
/**
* Convert from a byte array at an offset to one int
*
* @param byteArray
* @param offset the offset in the byteArray that is the first byte of the int
*
* TODO: Test that this will work for leading-zero bytes
*/
public static final int byteArrayToInt(byte[] byteArray, int offset) {
return byteArray[0 + offset] << 24 | (byteArray[1 + offset] & 0xff) << 16 |
(byteArray[2 + offset] & 0xff) << 8 | (byteArray[3 + offset] & 0xff);
}
/**
* Convert from one int to a byte array
*
* @param i the integer
*/
public static final byte[] intToByteArray(int i) {
return new byte[] {(byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) i};
}
/**
* Computes SHA-1 hash of byte array.
*
* @param vals input byte array
* @return SHA-1 hash of the input byte array
*/
public static String asHex(byte[] vals) {
if (vals == null) {
return null;
}
try {
MessageDigest sha1;
sha1 = MessageDigest.getInstance("SHA-1");
byte[] bytes = sha1.digest(vals);
StringBuilder hex = new StringBuilder(bytes.length * 2);
for (int i = 0; i < bytes.length; i++)
hex.append(Integer.toHexString(0xFF & bytes[i]));
return hex.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public static String makeString(byte[] vals, int count) {
if (vals == null || Math.min(vals.length, count) <= 0) {
return "";
}
int n = Math.min(vals.length, count);
String result = "";
for (int i=0; i<n; i++) {
result += String.format("0x%02X", vals[i]);
if (i<(n-1)) {
result += " ";
}
}
return result;
}
/**
* Convert from an array of bytes to an array of shorts
* @param byteArray
*/
public static short[] byteArrayToShortArray(byte[] byteArray) {
if(byteArray.length % 2 != 0) {
throw new IllegalArgumentException("Length of byteArray is not evenly divisible by 2, "
+ "which is the number of bytes in one short.");
}
short shortArray[] = new short[byteArray.length / 2];
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
ShortBuffer shortBuff = byteBuf.asShortBuffer();
shortBuff.get(shortArray);
return shortArray;
}
/**
* Convert from an array of shorts to an array of bytes
*
* @param shortArray
*/
public static byte[] shortArrayToByteArray(short shortArray[]) {
byte byteArray[] = new byte[shortArray.length*2]; // 2 bytes per short
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
ShortBuffer shortBuf = byteBuf.asShortBuffer();
shortBuf.put(shortArray);
return byteArray;
}
/**
* Convert from an array of bytes to an array of ints
* @param byteArray
*/
public static int[] byteArrayToIntArray(byte[] byteArray) {
if(byteArray.length % 4 != 0) {
throw new IllegalArgumentException("Length of byteArray is not evenly divisible by 4, "
+ "which is the number of bytes in one int.");
}
int intArray[] = new int[byteArray.length / 4];
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
IntBuffer intBuff = byteBuf.asIntBuffer();
intBuff.get(intArray);
return intArray;
}
/**
* Convert from an array of ints to an array of bytes
* @param intArray
*/
public static byte[] intArrayToByteArray(int[] intArray) {
byte[] byteArray = new byte[intArray.length*4]; // 4 bytes per int
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
IntBuffer intBuff = byteBuf.asIntBuffer();
intBuff.put(intArray);
return byteArray;
}
/**
* Convert from an array of bytes to an array of floats
*
* @param byteArray
*/
public static float[] byteArrayToFloatArray(byte byteArray[]) throws IllegalArgumentException {
if (byteArray.length % 4 != 0) {
throw new IllegalArgumentException("Length of byteArray is not evenly divisible by 4, "
+ "which is the number of bytes in one float.");
}
float floatArray[] = new float[byteArray.length / 4];
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
floatBuf.get(floatArray);
return floatArray;
}
/**
* Convert from an array of floats to an array of bytes
*
* @param floatArray
*/
public static byte[] floatArrayToByteArray(float floatArray[]) {
byte byteArray[] = new byte[floatArray.length*4]; // 4 bytes per float
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
FloatBuffer floatBuf = byteBuf.asFloatBuffer();
floatBuf.put(floatArray);
return byteArray;
}
/**
* Convert from an array of bytes to an array of doubles
* @param byteArray
*/
public static double[] byteArrayToDoubleArray(byte[] byteArray) {
if (byteArray.length % 8 != 0) {
throw new IllegalArgumentException("Length of byteArray is not evenly divisible by 8, "
+ "which is the number of bytes in one double.");
}
double doubleArray[] = new double[byteArray.length / 8];
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
DoubleBuffer doubleBuff = byteBuf.asDoubleBuffer();
doubleBuff.get(doubleArray);
return doubleArray;
}
/**
* Convert from an array of doubles to an array of bytes
* @param doubleArray
*/
public static byte[] doubleArrayToByteArray(double[] doubleArray) {
byte[] byteArray = new byte[doubleArray.length*8]; // 8 bytes per double
ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
DoubleBuffer doubleBuff = byteBuf.asDoubleBuffer();
doubleBuff.put(doubleArray);
return byteArray;
}
}