/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import xxl.core.util.WrappingRuntimeException; /** * Conversion routines: byte array <--> short, int, long. * <br> * There are some catogories of methods: * <ul> * <li> * Methods with the suffix LE assume little endian byte ordering. Example for 4-Byte integers:<br> * <code>01 00 00 00 = 1, 00 00 00 01 = 65536, 00 00 00 80 = -2147483648</code> * </li> * <li> * Methods with the suffix BE assume big endian byte ordering (so far not supported!). Example for 4-Byte integers:<br> * <code>01 00 00 00 = 16777216, 00 00 00 01 = 1, 00 00 00 80 = 128</code> * </li> * <li> * Methods with the suffix Stream use streams to convert the types to byte arrays * and back. These methode are usually much slower. Java uses big endian byte ordering. * </li> * <li> * Other methods. * </li> * </ul> */ public class ByteArrayConversions { /** * Do not allow instances of this class */ private ByteArrayConversions() {} /** * Converts the given byte to a short. * @param b byte to convert. * @return short. */ public static short conv255(byte b) { return (b<0)?(short) (256+b):(short)b; } /** * Converts the given byte to a short. * @param b byte to convert. * @return short. */ public static short conv127(byte b) { return (short) (b&127); } /** * Converts the byte array to a short. It is assumed that the array has a length of 2. * @param b the byte array to convert. * @return short. */ public static short convShortLE(byte b[]) { // Variable kostet fast keine Zeit! int zw = (conv127(b[1])<<8) | conv255(b[0]); if (b[1]<0) // Vorzeichen return (short) (zw - (1<<15)); else return (short) zw; } /** * Converts the byte array to a short. It is assumed that the array has a length of 2. * @param b the byte array to convert. * @param offset start if the integer inside the array. * @return short. */ public static short convShortLE(byte b[], int offset) { // Variable kostet fast keine Zeit! int zw = (conv127(b[offset+1])<<8) | conv255(b[offset]); if (b[offset+1]<0) // Vorzeichen return (short) (zw - (1<<15)); else return (short) zw; } /** * Converts the two given byte values to a short. * @param b0 the 'left' byte value. * @param b1 the 'right' byte value. * @return short. */ public static short convShortLE(byte b0, byte b1) { // Variable kostet fast keine Zeit! int zw = (conv127(b1)<<8) | conv255(b0); if (b1 < 0) // Vorzeichen return (short) (zw - (1<<15)); else return (short) zw; } /** * Converts the given byte to a short value. * @param b the byte to convert. * @return short. */ public static short convShortLE(byte b) { return conv255(b); } /** * Converts the byte array to a short value. * @param b the byte array. * @return short. */ public static short convShortStream(byte b[]) { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); DataOutput out = new DataOutputStream(output); out.write(b,0,b.length); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); DataInput in = new DataInputStream(input); return in.readShort(); } catch (IOException e) { throw new WrappingRuntimeException(e); } } /** * Converts the given byte array to an int value. It is assumed that the byte * array has a length of 4. * @param b the byte array. * @return int. */ public static int convIntLE(byte b[]) { int zw = (((((conv127(b[3])<<8) | conv255(b[2]))<<8) | conv255(b[1]))<<8) | conv255(b[0]); if (b[3]<0) // Vorzeichen return zw - (1<<31); else return zw; } /** * Converts the given byte array to an int value. It is assumed that the byte * array has a length of 4. * @param b the byte array. * @param offset start offset inside the array. * @return int. */ public static int convIntLE(byte b[], int offset) { int zw = (((((conv127(b[offset+3])<<8) | conv255(b[offset+2]))<<8) | conv255(b[offset+1]))<<8) | conv255(b[offset]); if (b[offset+3]<0) // Vorzeichen return zw - (1<<31); else return zw; } /** * Convert the given bytes to an int value. * @param b0 the 'outer left' byte value. * @param b1 the byte value at the right of b0. * @param b2 the byte value at the right of b1. * @param b3 the byte value at the right of b2. * @return int. */ public static int convIntLE(byte b0, byte b1, byte b2, byte b3) { int zw = (((((conv127(b3)<<8) | conv255(b2))<<8) | conv255(b1))<<8) | conv255(b0); if (b3<0) // Vorzeichen return zw - (1<<31); else return zw; } /** * Convert the given bytes to an int value. * @param b0 the 'left' byte value. * @param b1 the 'right' byte value. * @return int. */ public static int convIntLE(byte b0, byte b1) { return ((conv255(b1))<<8) | conv255(b0); } /** * Convert the byte array to an int value. * @param b the byte array. * @return int. */ public static int convIntStream(byte b[]) { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); DataOutput out = new DataOutputStream(output); out.write(b,0,b.length); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); DataInput in = new DataInputStream(input); return in.readInt(); } catch (IOException e) { throw new xxl.core.util.WrappingRuntimeException(e); //return 0; } } /** * Convert the given byte array to a long value. It is assumed that the * byte array has a length of 8. * @param b the byte array. * @return long. */ public static long convLongLE(byte b[]) { long zw = ((long) conv127(b[7])<<56) | ((long) conv255(b[6])<<48) | ((long) conv255(b[5])<<40) | ((long) conv255(b[4])<<32) | ((long) conv255(b[3])<<24) | ((long) conv255(b[2])<<16) | ((long) conv255(b[1])<<8) | conv255(b[0]); if (b[7]<0) // Vorzeichen return zw - (((long) 1)<<63); else return zw; } /** * Convert the given byte array to a long value. It is assumed that the * byte array has a length of 8. * @param b the byte array. * @param offset start if the integer inside the array. * @return long. */ public static long convLongLE(byte b[], int offset) { long zw = ((long) conv127(b[offset+7])<<56) | ((long) conv255(b[offset+6])<<48) | ((long) conv255(b[offset+5])<<40) | ((long) conv255(b[offset+4])<<32) | ((long) conv255(b[offset+3])<<24) | ((long) conv255(b[offset+2])<<16) | ((long) conv255(b[offset+1])<<8) | conv255(b[offset]); if (b[offset+7]<0) // Vorzeichen return zw - (((long) 1)<<63); else return zw; } /** * Convert the given byte values to a long value. * @param b0 the 'outer left' byte value. * @param b1 the byte value at the right of b0. * @param b2 the byte value at the right of b1. * @param b3 the byte value at the right of b2. * @param b4 the byte value at the right of b3. * @param b5 the byte value at the right of b4. * @param b6 the byte value at the right of b5. * @param b7 the byte value at the right of b6. * @return long. */ public static long convLongLE(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) { long zw = ((long) conv127(b7)<<56) | ((long) conv255(b6)<<48) | ((long) conv255(b5)<<40) | ((long) conv255(b4)<<32) | ((long) conv255(b3)<<24) | ((long) conv255(b2)<<16) | ((long) conv255(b1)<<8) | conv255(b0); if (b7<0) // Vorzeichen return zw - (((long) 1)<<63); else return zw; } /** * Convert the given byte values to a long value. * @param b0 lowest byte (byte 0) * @param b1 byte 1 * @param b2 byte 2 * @param b3 hightest byte (byte 3) * @return long. */ public static long convLongLE(byte b0, byte b1, byte b2, byte b3) { return ((long) conv255(b3)<<24) | ((long) conv255(b2)<<16) | ((long) conv255(b1)<<8) | conv255(b0); } /** * Convert the byte array to an long value. * @param b the byte array. * @return long. */ public static long convLongStream(byte b[]) { try { ByteArrayOutputStream output = new ByteArrayOutputStream(); DataOutput out = new DataOutputStream(output); out.write(b,0,b.length); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); DataInput in = new DataInputStream(input); return in.readLong(); } catch (IOException e) { throw new xxl.core.util.WrappingRuntimeException(e); //return 0; } } /** * Convert the integer to a byte array. * @param i the integer value * @param b array for the output. */ public static void convIntToByteArrayLE(int i, byte b[]) { b[0] = (byte) (i&255); i>>=8; b[1] = (byte) (i&255); i>>=8; b[2] = (byte) (i&255); i>>=8; b[3] = (byte) (i&255); } /** * Convert the integer to a byte array. * @param i the integer value * @param b array for the output. * @param offset determines the location to which the values are written inside the byte array. */ public static void convIntToByteArrayLE(int i, byte b[], int offset) { b[offset++] = (byte) (i&255); i>>=8; b[offset++] = (byte) (i&255); i>>=8; b[offset++] = (byte) (i&255); i>>=8; b[offset] = (byte) (i&255); } /** * Convert the integer to a byte array. * @param i the integer value * @return byte array. */ public static byte[] convIntToByteArrayLE(int i) { byte b[] = new byte[4]; convIntToByteArrayLE(i,b); return b; } /** * Convert the integer to a byte array. * @param i the integer value * @return byte array. */ public static byte[] convIntToByteArrayStream(int i) { ByteArrayOutputStream bao = new ByteArrayOutputStream(4); DataOutputStream dos = new DataOutputStream(bao); try { dos.writeInt(i); dos.flush(); } catch (IOException e) { throw new WrappingRuntimeException(e); } return bao.toByteArray(); } /** * Convert the long to a byte array. * @param l the long value * @param b array for the output. */ public static void convLongToByteArrayLE(long l, byte b[]) { b[0] = (byte) (l&255); l>>=8; b[1] = (byte) (l&255); l>>=8; b[2] = (byte) (l&255); l>>=8; b[3] = (byte) (l&255); l>>=8; b[4] = (byte) (l&255); l>>=8; b[5] = (byte) (l&255); l>>=8; b[6] = (byte) (l&255); l>>=8; b[7] = (byte) (l&255); } /** * Convert the long to a byte array. * @param l the long value * @param b byte array for the output. * @param offset determines the location to which the values are written inside the byte array. */ public static void convLongToByteArrayLE(long l, byte b[], int offset) { b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset++] = (byte) (l&255); l>>=8; b[offset] = (byte) (l&255); } /** * Convert the long to a byte array. * @param l the long value * @return byte array. */ public static byte[] convLongToByteArrayLE(long l) { byte b[] = new byte[8]; convLongToByteArrayLE(l,b); return b; } /** * Retun the string representation of the byte array. Starting at offset from (inclusive) * until the index to (exclusive). * @param b the byte array. * @param from index (inclusive). * @param to index (exclusive). * @return a string representation of the byte array. */ public static String byteToString(byte[] b, int from, int to) { try { //return new String(bpb, from, to-from, "US-ASCII"); return new String(b, from, to-from, "ISO-8859-1"); //return new String(bpb, from, from+2, "UTF-8"); //return new String(bpb, from, to-from, "UTF-16BE"); } catch (UnsupportedEncodingException e) { throw new WrappingRuntimeException(e); } } /** * Retun the unicode string representation of the byte array. Starting at * offset from (inclusive) until the index to (exclusive). * @param b the byte array. * @param from index (inclusive). * @param to index (exclusive). * @return a unicode string representation of the byte array. */ public static String unicodeByteToString(byte[] b, int from, int to) { try { return new String(b, from, to-from, "UTF-16LE"); } catch (UnsupportedEncodingException e) { throw new WrappingRuntimeException(e); } } /** * Converts a litte endian representation into a big endian * representation and vice versa. * @param b input byte array. * @return converted byte array. */ public static byte[] endianConversion(byte b[]) { byte bconv[] = new byte[b.length]; for (int i=0 ; i<b.length ; i++) bconv[i] = b[b.length-1-i]; return bconv; } }