/* * Copyright (c) 2005 (Mike) Maurice Kienenberger (mkienenb@gmail.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.gamenet.util; import java.util.Arrays; /** * @author mlk */ public class ByteConversions { /** * @param byteArray * @param offset * @param maxLength * @return */ public static String getZeroTerminatedStringInByteArrayAtPositionMaxLength(byte[] byteArray, int offset, int maxLength) { int length = 0; while ( (0 != byteArray[offset + length]) && (length < maxLength) ) length++; return new String(byteArray, offset, length); } /** * @param value * @param byteArray * @param offset * @param maxLength */ public static void setZeroTerminatedStringInByteArrayAtPositionMaxLength(String value, byte[] byteArray, int offset, int maxLength) { if (null != value) { // update value Arrays.fill(byteArray, offset, offset + maxLength, (byte)0); byte[] valueBytes = value.getBytes(); System.arraycopy(valueBytes, 0, byteArray, offset, Math.min(maxLength, valueBytes.length)); if (valueBytes.length < maxLength) byteArray[offset + valueBytes.length] = 0; } } /** * @param byteArray * @param offset * @return */ public static long getLongInByteArrayAtPosition(byte[] byteArray, int offset) { long longValue = 0; for (int i = 0; i < 8; i++) { longValue += ((long)convertByteToInt(byteArray[offset + i])) << (8 * i); } return longValue; } /** * @param value * @param byteArray * @param offset */ static public void setLongInByteArrayAtPosition( long value, byte[] byteArray, int offset) { for (int i = 0; i < 8; i++) { long shiftedValue = value >> (long)(8 * i); int intValue = (int)(shiftedValue & 0xFF); byte byteValue = convertIntToByte(intValue); byteArray[offset + i] = byteValue; } } /** * @param value * @param byteArray * @param offset */ static public void setIntegerInByteArrayAtPosition( long value, byte[] byteArray, int offset) { for (int i = 0; i < 4; i++) { int intValue = (int)((value >> (8 * i)) & 0xFF); byte byteValue = convertIntToByte(intValue); byteArray[offset + i] = byteValue; } } /** * @param byteArray * @param offset * @return */ public static int getIntegerInByteArrayAtPosition(byte[] byteArray, int offset) { int intValue = 0; for (int i = 0; i < 4; i++) { intValue += convertByteToInt(byteArray[offset + i]) << (8 * i); } return intValue; } /** * @param value */ static public byte convertIntToByte(int value) { return value < 128 ? (byte)value : (byte)(value - 256); } /** * @param value */ static public int convertByteToInt(byte value) { return value >= 0 ? value : (256 + ((int)value)); } /** * @param byteArray * @param offset * @return */ public static short getShortInByteArrayAtPosition(byte[] byteArray, int offset) { short shortValue = 0; for (int i = 0; i < 2; i++) { shortValue += convertByteToInt(byteArray[offset + i]) << (8 * i); } return shortValue; } public static int getUnsignedShortInByteArrayAtPosition(byte[] byteArray, int offset) { int shortValue = 0; for (int i = 0; i < 2; i++) { shortValue += convertByteToInt(byteArray[offset + i]) << (8 * i); } return shortValue; } /** * @param value * @param byteArray * @param offset */ static public void setShortInByteArrayAtPosition( short value, byte[] byteArray, int offset) { for (int i = 0; i < 2; i++) { int intValue = (int)((value >> (8 * i)) & 0xFF); byte byteValue = convertIntToByte(intValue); byteArray[offset + i] = byteValue; } } static public boolean getValueForByteAtBit(byte data, int bitIndex) { if (bitIndex > 7) throw new RuntimeException("bitIndex <" + bitIndex + "> out of range."); int mask = 1 << bitIndex; return (data & mask) == mask; } static public byte setValueForByteAtBit(boolean value, byte data, int bitIndex) { if (bitIndex > 7) throw new RuntimeException("bitIndex <" + bitIndex + "> out of range."); if (value) { return (byte) (data | (1 << bitIndex)); } else { return (byte) (data & (~(1 << bitIndex))); } } public static void main(String args[]) { byte test[] = new byte[8]; long interval = Long.MAX_VALUE / 1600000L; for (long expected = Long.MAX_VALUE; expected > 0 ; expected -= interval) { setLongInByteArrayAtPosition(expected, test, 0); long actual = getLongInByteArrayAtPosition(test, 0); if (expected != actual) { throw new AssertionError("expected<" + String.valueOf(expected) + ">, actual<" + String.valueOf(actual) + ">"); } } for (long expected = Long.MIN_VALUE; expected < 0 ; expected += interval) { setLongInByteArrayAtPosition(expected, test, 0); long actual = getLongInByteArrayAtPosition(test, 0); if (expected != actual) { throw new AssertionError("expected<" + String.valueOf(expected) + ">, actual<" + String.valueOf(actual) + ">"); } } } /** * @param i * @param newData * @param offset */ public static void setUnsignedShortInByteArrayAtPosition(int i, byte[] newData, int offset) { // TODO: write this method ByteConversions.setShortInByteArrayAtPosition((short)i, newData, offset); } /** * @param data * @param offset * @return */ public static float getFloatInByteArrayAtPosition(byte[] data, int offset) { int value = getIntegerInByteArrayAtPosition(data, offset); return Float.intBitsToFloat(value); } /** * @param f * @param newData * @param offset */ public static void setFloatInByteArrayAtPosition(float f, byte[] newData, int offset) { int value = Float.floatToIntBits(f); setIntegerInByteArrayAtPosition(value, newData, offset); } public static int getIntegerFromDataInByteArrayAtPositionForLength(byte[] byteArray, int offset, int length) { switch (length) { case 1: return ByteConversions.convertByteToInt(byteArray[offset]); case 2: return ByteConversions.getUnsignedShortInByteArrayAtPosition(byteArray, offset); case 4: return ByteConversions.getIntegerInByteArrayAtPosition(byteArray, offset); default: throw new RuntimeException("Unsupported length of '" + length + "' for getIntegerFromDataInByteArrayAtPositionForLength."); } } }