/** * Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.ctdp.rfdynhud.gamedata; /** * Static methods to read primitive types from a byte array. * * @author Marvin Froehlich (CTDP) */ public class ByteUtil { public static final int SIZE_BOOL = 1; public static final int SIZE_CHAR = 1; public static final int SIZE_SHORT = 2; public static final int SIZE_INT = 4; public static final int SIZE_LONG = 4; public static final int SIZE_FLOAT = 4; public static final int SIZE_DOUBLE = 8; public static final int SIZE_POINTER = 4; // 4 or 8 ??? public static final int SIZE_VECTOR3F = 3 * SIZE_FLOAT; public static final int SIZE_VECTOR3D = 3 * SIZE_DOUBLE; public static final int SHIFT4_HH = 0; public static final int SHIFT4_HL = 8; public static final int SHIFT4_LH = 16; public static final int SHIFT4_LL = 24; public static final int SHIFT2_H = 0; public static final int SHIFT2_L = 8; public static final int SHIFT_HHH = 24 + 32; public static final int SHIFT_HHL = 16 + 32; public static final int SHIFT_HLH = 8 + 32; public static final int SHIFT_HLL = 0 + 32; public static final void writeByte( final byte value, byte[] buffer, final int offset ) { buffer[ offset ] = value; } public static final byte readByte( final byte[] buffer, final int offset ) { return ( buffer[ offset ] ); } public static final void writeUnsignedByte( final short value, byte[] buffer, final int offset ) { buffer[ offset ] = (byte)value; } public static final short readUnsignedByte( final byte[] buffer, final int offset ) { return ( (short)( buffer[ offset ] & 0xFF ) ); } public static final void writeBoolean( final boolean value, byte[] buffer, final int offset ) { buffer[ offset ] = value ? (byte)1 : (byte)0; } public static final boolean readBoolean( final byte[] buffer, final int offset ) { return ( ( buffer[ offset ] & 0xFF ) != 0 ); } public static final void writeShort( final int value, byte[] buffer, final int offset ) { buffer[ offset + 0 ] = (byte)( ( value >> ByteUtil.SHIFT2_H ) & 0xFF ); buffer[ offset + 1 ] = (byte)( ( value >> ByteUtil.SHIFT2_L ) & 0xFF ); } public static final short readShort( final byte[] buffer, final int offset ) { return ( (short)( ( ( buffer[ offset + 0 ] & 0xFF ) << ByteUtil.SHIFT2_H ) | ( ( buffer[ offset + 1 ] & 0xFF ) << ByteUtil.SHIFT2_L ) ) ); } public static final int readUnsignedShort( final byte[] buffer, final int offset ) { return ( ( ( buffer[ offset + 0 ] & 0xFF ) << ByteUtil.SHIFT2_H ) | ( ( buffer[ offset + 1 ] & 0xFF ) << ByteUtil.SHIFT2_L ) ); } public static final void writeInt( final int value, byte[] buffer, final int offset ) { buffer[ offset + 0 ] = (byte)( ( value >> ByteUtil.SHIFT4_HH ) & 0xFF ); buffer[ offset + 1 ] = (byte)( ( value >> ByteUtil.SHIFT4_HL ) & 0xFF ); buffer[ offset + 2 ] = (byte)( ( value >> ByteUtil.SHIFT4_LH ) & 0xFF ); buffer[ offset + 3 ] = (byte)( ( value >> ByteUtil.SHIFT4_LL ) & 0xFF ); } public static final int readInt( final byte[] buffer, final int offset ) { return ( ( ( buffer[ offset + 0 ] & 0xFF ) << ByteUtil.SHIFT4_HH ) | ( ( buffer[ offset + 1 ] & 0xFF ) << ByteUtil.SHIFT4_HL ) | ( ( buffer[ offset + 2 ] & 0xFF ) << ByteUtil.SHIFT4_LH ) | ( ( buffer[ offset + 3 ] & 0xFF ) << ByteUtil.SHIFT4_LL ) ); } public static final void writeUnsignedInt( final long value, byte[] buffer, final int offset ) { writeInt( (int)value, buffer, offset ); } public static final long readUnsignedInt( final byte[] buffer, final int offset ) { return ( readInt( buffer, offset ) ); } public static final void writeLong( final long value, byte[] buffer, final int offset ) { writeInt( (int)value, buffer, offset ); } public static final long readLong( final byte[] buffer, final int offset ) { /* int high = readInt( buffer, offset ); int low = readInt( buffer, offset + 4 ); return ( ( (long)high << 32 ) | low ); */ return ( readInt( buffer, offset ) ); } public static final void writeFloat( final float value, byte[] buffer, final int offset ) { int i = Float.floatToIntBits( value ); writeInt( i, buffer, offset ); } public static final float readFloat( final byte[] buffer, final int offset ) { int i = readInt( buffer, offset ); return ( Float.intBitsToFloat( i ) ); } public static final void writeDouble( final double value, byte[] buffer, final int offset ) { long l = Double.doubleToLongBits( value ); buffer[offset + 7] = (byte)( ( l >> 56 ) & 0xFF ); buffer[offset + 6] = (byte)( ( l >> 48 ) & 0xFF ); buffer[offset + 5] = (byte)( ( l >> 40 ) & 0xFF ); buffer[offset + 4] = (byte)( ( l >> 32 ) & 0xFF ); buffer[offset + 3] = (byte)( ( l >> 24 ) & 0xFF ); buffer[offset + 2] = (byte)( ( l >> 16 ) & 0xFF ); buffer[offset + 1] = (byte)( ( l >> 8 ) & 0xFF ); buffer[offset + 0] = (byte)( ( l >> 0 ) & 0xFF ); } public static final double readDouble( final byte[] buffer, final int offset ) { //long l = readLong( buffer, offset ); /* int low = readInt( buffer, offset ); int high = readInt( buffer, offset + 4 ); long l = ( (long)high << 32 ) | low; */ /* long l = ( ( (long)buffer[offset + 0] << 56 ) + ( (long)( buffer[offset + 1] & 255 ) << 48 ) + ( (long)( buffer[offset + 2] & 255 ) << 40 ) + ( (long)( buffer[offset + 3] & 255 ) << 32 ) + ( (long)( buffer[offset + 4] & 255 ) << 24 ) + ( ( buffer[offset + 5] & 255 ) << 16 ) + ( ( buffer[offset + 6] & 255 ) << 8 ) + ( ( buffer[offset + 7] & 255 ) << 0 ) ); */ long l = ( ( (long)( buffer[offset + 7] & 0xFF ) << 56 ) | ( (long)( buffer[offset + 6] & 0xFF ) << 48 ) | ( (long)( buffer[offset + 5] & 0xFF ) << 40 ) | ( (long)( buffer[offset + 4] & 0xFF ) << 32 ) | ( (long)( buffer[offset + 3] & 0xFF ) << 24 ) | ( (long)( buffer[offset + 2] & 0xFF ) << 16 ) | ( (long)( buffer[offset + 1] & 0xFF ) << 8 ) | ( ( buffer[offset + 0] & 0xFF ) ) ); return ( Double.longBitsToDouble( l ) ); } public static final void readVectorF( final byte[] buffer, final int offset, TelemVect3 vector ) { vector.x = ByteUtil.readFloat( buffer, offset + 0 * ByteUtil.SIZE_FLOAT ); vector.y = ByteUtil.readFloat( buffer, offset + 1 * ByteUtil.SIZE_FLOAT ); vector.z = ByteUtil.readFloat( buffer, offset + 2 * ByteUtil.SIZE_FLOAT ); } public static final void readVectorD( final byte[] buffer, final int offset, TelemVect3 vector ) { vector.x = (float)ByteUtil.readDouble( buffer, offset + 0 * ByteUtil.SIZE_DOUBLE ); vector.y = (float)ByteUtil.readDouble( buffer, offset + 1 * ByteUtil.SIZE_DOUBLE ); vector.z = (float)ByteUtil.readDouble( buffer, offset + 2 * ByteUtil.SIZE_DOUBLE ); } public static final String readString( final byte[] buffer, final int offset, final int maxLength ) { int length = maxLength; for ( int i = 0; i < maxLength; i++ ) { if ( buffer[offset + i] == (byte)0 ) { length = i; break; } } return ( new String( buffer, offset, length ) ); } }