/** * Copyright (c) 2013-2014 Robert Maupin * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. */ package org.csdgn.maru; import java.nio.ByteOrder; /** * I am tired of rewriting all these methods when I need them. * * Why use a complicated ByteBuffer when you can get exactly what you want with * this ByteConverter? * * All those who work with binary files may appreciate this class. * * @author Robert Maupin * */ public class ByteConverter { public static final ByteConverter LITTLE_ENDIAN = new ByteConverter(ByteOrder.LITTLE_ENDIAN); public static final ByteConverter BIG_ENDIAN = new ByteConverter(ByteOrder.BIG_ENDIAN); /** * For reference:<br/> * Big Endian = Most Significant Bit First<br /> * Little Endian = Least Significant Bit First */ private ByteOrder order; public ByteConverter() { order = ByteOrder.nativeOrder(); } public ByteConverter(ByteOrder order) { this.order = order; } public byte[] fromDouble(double value) { return fromLong(Double.doubleToRawLongBits(value)); } public byte[] fromDoubleArray(double[] value) { return fromDoubleArray(value, 0, value.length); } public byte[] fromDoubleArray(double[] value, int start) { return fromDoubleArray(value, start, value.length - start); } public byte[] fromDoubleArray(double[] value, int start, int length) { int end = length + start; byte[] output = new byte[length << 3]; for (int i = start; i < end; ++i) { int n = i - start << 3; byte[] buf = fromDouble(value[i]); output[n] = buf[0]; output[n + 1] = buf[1]; output[n + 2] = buf[2]; output[n + 3] = buf[3]; output[n + 4] = buf[4]; output[n + 5] = buf[5]; output[n + 6] = buf[6]; output[n + 7] = buf[7]; } return output; } public byte[] fromFloat(float value) { return fromInt(Float.floatToRawIntBits(value)); } public byte[] fromFloatArray(float[] value) { return fromFloatArray(value, 0, value.length); } public byte[] fromFloatArray(float[] value, int start) { return fromFloatArray(value, start, value.length - start); } public byte[] fromFloatArray(float[] value, int start, int length) { int end = length + start; byte[] output = new byte[length << 2]; for (int i = start; i < end; ++i) { int n = i - start << 2; byte[] buf = fromFloat(value[i]); output[n] = buf[0]; output[n + 1] = buf[1]; output[n + 2] = buf[2]; output[n + 3] = buf[3]; } return output; } public byte[] fromInt(int value) { if (order == ByteOrder.BIG_ENDIAN) { return new byte[] { ubyte(value, 24), ubyte(value, 16), ubyte(value, 8), ubyte(value, 0) }; } return new byte[] { ubyte(value, 0), ubyte(value, 8), ubyte(value, 16), ubyte(value, 24) }; } public byte[] fromIntArray(int[] value) { return fromIntArray(value, 0, value.length); } public byte[] fromIntArray(int[] value, int start) { return fromIntArray(value, start, value.length - start); } public byte[] fromIntArray(int[] value, int start, int length) { int end = length + start; byte[] output = new byte[length << 2]; for (int i = start; i < end; ++i) { int n = i - start << 2; byte[] buf = fromInt(value[i]); output[n] = buf[0]; output[n + 1] = buf[1]; output[n + 2] = buf[2]; output[n + 3] = buf[3]; } return output; } public byte[] fromLong(long value) { if (order == ByteOrder.BIG_ENDIAN) { return new byte[] { ubyte(value, 56), ubyte(value, 48), ubyte(value, 40), ubyte(value, 32), ubyte(value, 24), ubyte(value, 16), ubyte(value, 8), ubyte(value, 0) }; } return new byte[] { ubyte(value, 0), ubyte(value, 8), ubyte(value, 16), ubyte(value, 24), ubyte(value, 32), ubyte(value, 40), ubyte(value, 48), ubyte(value, 56) }; } public byte[] fromLongArray(long[] value) { return fromLongArray(value, 0, value.length); } public byte[] fromLongArray(long[] value, int start) { return fromLongArray(value, start, value.length - start); } public byte[] fromLongArray(long[] value, int start, int length) { int end = length + start; byte[] output = new byte[length << 3]; for (int i = start; i < end; ++i) { int n = i - start << 3; byte[] buf = fromLong(value[i]); output[n] = buf[0]; output[n + 1] = buf[1]; output[n + 2] = buf[2]; output[n + 3] = buf[3]; output[n + 4] = buf[4]; output[n + 5] = buf[5]; output[n + 6] = buf[6]; output[n + 7] = buf[7]; } return output; } public byte[] fromShort(short value) { if (order == ByteOrder.BIG_ENDIAN) { return new byte[] { ubyte(value, 8), ubyte(value, 0) }; } return new byte[] { ubyte(value, 0), ubyte(value, 8) }; } public byte[] fromShortArray(short[] value) { return fromShortArray(value, 0, value.length); } public byte[] fromShortArray(short[] value, int start) { return fromShortArray(value, start, value.length - start); } public byte[] fromShortArray(short[] value, int start, int length) { int end = length + start; byte[] output = new byte[length << 1]; for (int i = start; i < end; ++i) { int n = i - start << 1; byte[] buf = fromShort(value[i]); output[n] = buf[0]; output[n + 1] = buf[1]; } return output; } public void setByteOrder(ByteOrder order) { this.order = order; } public double toDouble(byte[] array) { return Double.longBitsToDouble(toLong(array)); } public double toDouble(byte[] array, int start) { return Double.longBitsToDouble(toLong(array, start)); } public double[] toDoubleArray(byte[] array) { return toDoubleArray(array, 0, array.length); } public double[] toDoubleArray(byte[] array, int start) { return toDoubleArray(array, start, array.length - start); } public double[] toDoubleArray(byte[] array, int start, int length) { double[] output = new double[length - start >> 3]; for (int i = 0; i < output.length; ++i) { output[i] = toDouble(array, start + (i << 3)); } return output; } public float toFloat(byte[] array) { return Float.intBitsToFloat(toInt(array)); } public float toFloat(byte[] array, int start) { return Float.intBitsToFloat(toInt(array, start)); } public float[] toFloatArray(byte[] array) { return toFloatArray(array, 0, array.length); } public float[] toFloatArray(byte[] array, int start) { return toFloatArray(array, start, array.length - start); } public float[] toFloatArray(byte[] array, int start, int length) { float[] output = new float[length - start >> 2]; for (int i = 0; i < output.length; ++i) { output[i] = toFloat(array, start + (i << 2)); } return output; } public int toInt(byte[] array) { if (order == ByteOrder.BIG_ENDIAN) { return uint(array[0], 24) | uint(array[1], 16) | uint(array[2], 8) | uint(array[3], 0); } return uint(array[3], 24) | uint(array[2], 16) | uint(array[1], 8) | uint(array[0], 0); } public int toInt(byte[] array, int start) { if (order == ByteOrder.BIG_ENDIAN) { return uint(array[start], 24) | uint(array[start + 1], 16) | uint(array[start + 2], 8) | uint(array[start + 3], 0); } return uint(array[start + 3], 24) | uint(array[start + 2], 16) | uint(array[start + 1], 8) | uint(array[start], 0); } public int[] toIntArray(byte[] array) { return toIntArray(array, 0, array.length); } public int[] toIntArray(byte[] array, int start) { return toIntArray(array, start, array.length - start); } public int[] toIntArray(byte[] array, int start, int length) { int[] output = new int[length - start >> 2]; for (int i = 0; i < output.length; ++i) { output[i] = toInt(array, start + (i << 2)); } return output; } public long toLong(byte[] array) { if (order == ByteOrder.BIG_ENDIAN) { return ulong(array[0], 56) | ulong(array[1], 48) | ulong(array[2], 40) | ulong(array[3], 32) | ulong(array[4], 24) | ulong(array[5], 16) | ulong(array[6], 8) | ulong(array[7], 0); } return ulong(array[7], 56) | ulong(array[6], 48) | ulong(array[5], 40) | ulong(array[4], 32) | ulong(array[3], 24) | ulong(array[2], 16) | ulong(array[1], 8) | ulong(array[0], 0); } public long toLong(byte[] array, int start) { if (order == ByteOrder.BIG_ENDIAN) { return ulong(array[start], 56) | ulong(array[start + 1], 48) | ulong(array[start + 2], 40) | ulong(array[start + 3], 32) | ulong(array[start + 4], 24) | ulong(array[start + 5], 16) | ulong(array[start + 6], 8) | ulong(array[start + 7], 0); } return ulong(array[start + 7], 56) | ulong(array[start + 6], 48) | ulong(array[start + 5], 40) | ulong(array[start + 4], 32) | ulong(array[start + 3], 24) | ulong(array[start + 2], 16) | ulong(array[start + 1], 8) | ulong(array[start], 0); } public long[] toLongArray(byte[] array) { return toLongArray(array, 0, array.length); } public long[] toLongArray(byte[] array, int start) { return toLongArray(array, start, array.length - start); } public long[] toLongArray(byte[] array, int start, int length) { long[] output = new long[length - start >> 3]; for (int i = 0; i < output.length; ++i) { output[i] = toLong(array, start + (i << 3)); } return output; } public short toShort(byte[] array) { if (order == ByteOrder.BIG_ENDIAN) { return (short) (uint(array[0], 8) | uint(array[1], 0)); } return (short) (uint(array[1], 8) | uint(array[0], 0)); } public short toShort(byte[] array, int start) { if (order == ByteOrder.BIG_ENDIAN) { return (short) (uint(array[start], 8) | uint(array[start + 1], 0)); } return (short) (uint(array[start + 1], 8) | uint(array[start], 0)); } public short[] toShortArray(byte[] array) { return toShortArray(array, 0, array.length); } public short[] toShortArray(byte[] array, int start) { return toShortArray(array, start, array.length - start); } public short[] toShortArray(byte[] array, int start, int length) { short[] output = new short[length - start >> 1]; for (int i = 0; i < output.length; ++i) { output[i] = toShort(array, start + (i << 1)); } return output; } private byte ubyte(long b, int rshf) { return (byte) (b >>> rshf); } private int uint(byte b, int lsft) { return (b & 0xFF) << lsft; } private long ulong(byte b, long lsft) { return (b & 0xFFL) << lsft; } }