package org.opendaylight.protocol.util;
import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedInteger;
import io.netty.buffer.ByteBuf;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.BitSet;
-import org.apache.commons.codec.binary.Hex;
/**
* Util class for methods working with byte array.
return buff.getLong();
}
- /**
- * Converts byte array to float IEEE 754 format. If there are less bytes in the array as required (Float.Size), the
- * method will push adequate number of zero bytes prepending given byte array.
- *
- * @param bytes array to be converted to float
- * @return float
- */
- public static float bytesToFloat(final byte[] bytes) {
- if (bytes.length > Float.SIZE / Byte.SIZE) {
- throw new IllegalArgumentException("Cannot convert bytes to float.Byte array too big.");
- }
- byte[] res = new byte[Float.SIZE / Byte.SIZE];
- if (bytes.length != Float.SIZE / Byte.SIZE) {
- System.arraycopy(bytes, 0, res, Float.SIZE / Byte.SIZE - bytes.length, bytes.length);
- } else {
- res = bytes;
- }
- final ByteBuffer buff = ByteBuffer.wrap(res);
- return buff.getFloat();
- }
-
/**
* Cuts 'count' number of bytes from the beginning of given byte array.
*
}
final byte[] byteArray = new byte[(int) file.length()];
try (final FileInputStream fin = new FileInputStream(file)) {
- while (offset < byteArray.length && (numRead = fin.read(byteArray, offset, byteArray.length - offset)) >= 0) {
- offset += numRead;
+ while (offset < byteArray.length) {
+ numRead = fin.read(byteArray, offset, byteArray.length - offset);
+ if (numRead >= 0) {
+ offset += numRead;
+ }
}
fin.close();
}
return byteArray;
}
- /**
- * Parses integer to array of bytes
- *
- * @param num integer to be parsed
- * @return parsed array of bytes with length of Integer.SIZE/Byte.SIZE
- */
- public static byte[] intToBytes(final int num) {
- return intToBytes(num, Integer.SIZE / Byte.SIZE);
- }
-
- /**
- * Parses integer to array of bytes
- *
- * @param num integer to be parsed
- * @param size desired byte array length
- * @return parsed array of bytes with length of size
- */
- public static byte[] intToBytes(final int num, final int size) {
- final int finalSize = Integer.SIZE / Byte.SIZE;
- final ByteBuffer bytesBuffer = ByteBuffer.allocate(finalSize);
- bytesBuffer.putInt(num);
- return ByteArray.subByte(bytesBuffer.array(), finalSize - size, size);
- }
-
- /**
- * Parses long to array of bytes
- *
- * @param num long to be parsed
- * @return parsed array of bytes with length of Long.SIZE/Byte.SIZE
- */
- public static byte[] longToBytes(final int num) {
- return longToBytes(num, Long.SIZE / Byte.SIZE);
- }
-
- /**
- * Parses long to array of bytes
- *
- * @param num long to be parsed
- * @param size desired byte array length
- * @return parsed array of bytes with length of size
- */
- public static byte[] longToBytes(final long num, final int size) {
- final int finalSize = Long.SIZE / Byte.SIZE;
- final ByteBuffer bytesBuffer = ByteBuffer.allocate(finalSize);
- bytesBuffer.putLong(num);
- return ByteArray.subByte(bytesBuffer.array(), finalSize - size, size);
- }
-
/**
* Copies range of bits from passed byte and align to right.<br/>
*
return retByte;
}
- /**
- * Copies whole source byte array to destination from offset.<br/>
- * Length of src can't be bigger than dest length minus offset
- *
- * @param src byte[]
- * @param dest byte[]
- * @param offset int
- */
- public static void copyWhole(final byte[] src, final byte[] dest, final int offset) {
- if (dest.length - offset < src.length) {
- throw new ArrayIndexOutOfBoundsException("Can't copy whole array.");
- }
-
- System.arraycopy(src, 0, dest, offset, src.length);
- }
-
- /**
- * Convert array of bytes to java short.<br/>
- * Size can't be bigger than size of short in bytes.
- *
- * @param bytes byte[]
- * @return array of bytes
- */
- public static short bytesToShort(final byte[] bytes) {
- if (bytes.length > Short.SIZE / Byte.SIZE) {
- throw new IllegalArgumentException("Cannot convert bytes to short. Byte array too big.");
- }
- byte[] res = new byte[Short.SIZE / Byte.SIZE];
- if (bytes.length != Short.SIZE / Byte.SIZE) {
- System.arraycopy(bytes, 0, res, Integer.SIZE / Byte.SIZE - bytes.length, bytes.length);
- } else {
- res = bytes;
- }
- final ByteBuffer buff = ByteBuffer.wrap(res);
- return buff.getShort();
- }
-
- /**
- * Convert short java representation to array of bytes.
- *
- * @param num short
- * @return short represented as array of bytes
- */
- public static byte[] shortToBytes(final short num) {
- final ByteBuffer bytesBuffer = ByteBuffer.allocate(Short.SIZE / Byte.SIZE);
- bytesBuffer.putShort(num);
-
- return bytesBuffer.array();
- }
-
- /**
- * Convert float java representation to array of bytes.
- *
- * @param num float
- * @return float represented as array of bytes
- */
- public static byte[] floatToBytes(final float num) {
- final ByteBuffer bytesBuffer = ByteBuffer.allocate(Float.SIZE / Byte.SIZE);
- bytesBuffer.putFloat(num);
-
- return bytesBuffer.array();
- }
-
- /**
- * Pretty print array of bytes as hex encoded string with 16 bytes per line. Each byte is separated by space, after
- * first 8 bytes there are 2 spaces instead of one.
- */
- public static String bytesToHexString(final byte[] array) {
- return bytesToHexString(array, 16, " ", 8, " ");
- }
-
- /**
- * Pretty-print an array of bytes as hex-encoded string. Separate them with specified separator.
- */
- public static String toHexString(final byte[] array, final String separator) {
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < array.length; i++) {
- sb.append(Hex.encodeHexString(new byte[] { array[i] }));
- if (i + 1 != array.length) {
- sb.append(separator);
- }
- }
- return sb.toString();
- }
-
- /**
- * Convert array of bytes to hexadecimal String.
- *
- * @param array
- * @param bytesOnLine number of bytes that should by displayed in one line
- * @param byteSeparator string that will be placed after each byte
- * @param wordCount number of bytes that make a 'word' (group of bytes)
- * @param wordSeparator string that will be placed after each word
- * @return Hexadecimal string representation of given byte array
- */
- public static String bytesToHexString(final byte[] array, final int bytesOnLine, final String byteSeparator, final int wordCount,
- final String wordSeparator) {
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < array.length; i++) {
- sb.append(Hex.encodeHexString(new byte[] { array[i] }));
- if ((i + 1) % bytesOnLine == 0) {
- sb.append("\n");
- } else {
- sb.append(byteSeparator);
- if ((i + 1) % wordCount == 0) {
- sb.append(wordSeparator);
- }
- }
-
- }
- return sb.toString();
- }
-
/**
* Decodes bytes to human readable UTF-8 string. If bytes are not valid UTF-8, they are represented as raw binary.
*
return Arrays.toString(bytes);
}
}
-
- /**
- * Searches for byte sequence in given array. Returns the index of first occurrence of this sequence (where it
- * starts).
- *
- * @param bytes byte array where to search for sequence
- * @param sequence to be searched in given byte array
- * @return -1 if the sequence could not be found in given byte array int index of first occurrence of the sequence
- * in bytes
- */
- public static int findByteSequence(final byte[] bytes, final byte[] sequence) {
- if (bytes.length < sequence.length) {
- throw new IllegalArgumentException("Sequence to be found is longer than the given byte array.");
- }
- if (bytes.length == sequence.length) {
- if (Arrays.equals(bytes, sequence)) {
- return 0;
- } else {
- return -1;
- }
- }
- int j = 0;
- for (int i = 0; i < bytes.length; i++) {
- if (bytes[i] == sequence[j]) {
- j++;
- if (j == sequence.length) {
- return i - j + 1;
- }
- } else {
- j = 0;
- }
- }
- return -1;
- }
-
- private static final byte MASK_BITS[] = new byte[] { 0, -128, -64, -32, -16, -8, -4, -2 };
-
- public static byte[] maskBytes(final byte[] original, final int bits) {
- if (original.length * Byte.SIZE < bits) {
- throw new IllegalArgumentException("Attempted to apply invalid mask (too long)");
- }
-
- final int needbytes = (bits + 7) / Byte.SIZE;
- // We need to have a new copy of the underlying byte array, so that
- // the original bytes stay untouched
- final byte[] bytes = Arrays.copyOf(original, original.length);
-
- final int needmask = bits % Byte.SIZE;
- if (needmask != 0) {
- bytes[needbytes - 1] &= MASK_BITS[needmask];
- }
-
- // zero-out the rest of the bytes
- for (int i = needbytes; i < bytes.length; i++) {
- bytes[i] = 0;
- }
- return bytes;
- }
-
- /**
- * Trims zeros from the beginning of the byte array.
- *
- * @param bytes
- * @return byte array without leading zeros.
- */
- public static byte[] trim(final byte[] bytes) {
- int i = bytes.length - 1;
- while (i >= 0 && bytes[i] == 0) {
- --i;
- }
- return Arrays.copyOf(bytes, i + 1);
- }
-
- /**
- * Converts given byte array to unsigned Integer.
- *
- * @param bytes byte array to be converted to unsigned Integer.
- * @return uint
- */
- public static UnsignedInteger bytesToUint32(final byte[] bytes) {
- Preconditions.checkArgument(bytes.length == Integer.SIZE / Byte.SIZE);
- return UnsignedInteger.fromIntBits(bytesToInt(bytes));
- }
-
- /**
- * Converts uint to byte array.
- *
- * @param uint to be converted to byte array
- * @return byte array
- */
- public static byte[] uint32ToBytes(final UnsignedInteger uint) {
- return intToBytes(uint.intValue());
- }
-
- /**
- * Converts uint as long to byte array.
- *
- * @param uint to be converted to byte array
- * @return byte array
- */
- public static byte[] uint32ToBytes(final long uint) {
- return uint32ToBytes(UnsignedInteger.valueOf(uint));
- }
}
@Test
public void testReadBytes() {
- ByteBuf buffer = Unpooled.copiedBuffer(this.before);
+ final ByteBuf buffer = Unpooled.copiedBuffer(this.before);
buffer.readerIndex(1);
assertArrayEquals(new byte[] { 28, 4, 6 }, ByteArray.readBytes(buffer, 3));
assertEquals(4, buffer.readerIndex());
@Test
public void testGetBytes() {
- ByteBuf buffer = Unpooled.copiedBuffer(this.before);
+ final ByteBuf buffer = Unpooled.copiedBuffer(this.before);
buffer.readerIndex(1);
assertArrayEquals(new byte[] { 28, 4, 6 }, ByteArray.getBytes(buffer, 3));
assertEquals(1, buffer.readerIndex());
assertNotSame(buffer.readerIndex(), buffer.writerIndex());
}
- @Test
- public void testBytesToFloat() {
- final float expected = 8581;
- final byte[] b = ByteArray.floatToBytes(expected);
- assertEquals(expected, ByteArray.bytesToFloat(b), 50);
- }
-
@Test
public void testSubByte() {
byte[] after = ByteArray.subByte(this.before, 0, 3);
}
}
- @Test
- public void testIntToBytes() {
- assertEquals(Integer.MAX_VALUE, ByteArray.bytesToInt(ByteArray.intToBytes(Integer.MAX_VALUE, Integer.SIZE / Byte.SIZE)));
- assertEquals(Integer.MIN_VALUE, ByteArray.bytesToInt(ByteArray.intToBytes(Integer.MIN_VALUE, Integer.SIZE / Byte.SIZE)));
- assertEquals(2, ByteArray.intToBytes(12, 2).length);
- assertArrayEquals(new byte[] { 0, 12 }, ByteArray.intToBytes(12, 2));
- assertEquals(5, ByteArray.bytesToInt(ByteArray.intToBytes(5, 2)));
- }
-
- @Test
- public void testLongToBytes_bytesToLong() {
- assertEquals(Long.MAX_VALUE, ByteArray.bytesToLong(ByteArray.longToBytes(Long.MAX_VALUE, Long.SIZE / Byte.SIZE)));
- assertEquals(Long.MIN_VALUE, ByteArray.bytesToLong(ByteArray.longToBytes(Long.MIN_VALUE, Long.SIZE / Byte.SIZE)));
- assertArrayEquals(new byte[] { 0, 0, 5 }, ByteArray.longToBytes(5L, 3));
- assertEquals(5, ByteArray.bytesToLong(ByteArray.longToBytes(5, 2)));
- }
-
/**
- * if less than 4 bytes are converted, zero bytes should be appendet at the buffer's start
+ * if less than 4 bytes are converted, zero bytes should be appended at the buffer's start
*/
@Test
public void testBytesToLong_prependingZeros() {
ByteArray.bytesToInt(b);
}
- @Test
- public void testBytes() {
- assertTrue(ByteArray.bytesToInt(new byte[] { 0, 0, 0, 15 }) == 15);
- assertEquals(Float.valueOf((float) 1.4E-45), Float.valueOf(ByteArray.bytesToFloat(new byte[] { 0, 0, 0, 1 })));
- assertEquals(Long.valueOf(16613001005322L), Long.valueOf(ByteArray.bytesToLong(this.before)));
- assertEquals(Short.valueOf((short) 1), Short.valueOf(ByteArray.bytesToShort(new byte[] { 0, 1 })));
- }
-
@Test
public void testCopyBitRange() {
assertEquals((byte) 10, ByteArray.copyBitsRange((byte) 0x28, 2, 4));
ByteArray.copyBitsRange((byte) 0x28, 2, -2);
}
- @Test
- public void testCopyWhole() {
- final byte[] expecteds = { (byte) 0x04, (byte) 0x02, (byte) 0xD4, (byte) 0xf5, (byte) 0x32 };
-
- final byte[] actuals = new byte[5];
- actuals[0] = (byte) 0x04;
- actuals[1] = (byte) 0x02;
- actuals[2] = (byte) 0xD4;
-
- final byte[] src = { (byte) 0xf5, (byte) 0x32 };
-
- ByteArray.copyWhole(src, actuals, 3);
-
- assertArrayEquals(expecteds, actuals);
- }
-
- @Test(expected = ArrayIndexOutOfBoundsException.class)
- public void testCopyWhole2() {
- ByteArray.copyWhole(new byte[0], new byte[1], 2);
- }
-
- @Test
- public void testBytesToShort() {
- final byte[] bytes1 = { (byte) 0x00, (byte) 0x01 };
- final short expectedShort1 = 1;
- assertEquals(expectedShort1, ByteArray.bytesToShort(bytes1));
-
- final byte[] bytes2 = { (byte) 0xFF, (byte) 0xFF };
- final short expectedShort2 = (short) 0xFFFF;
- assertEquals(expectedShort2, ByteArray.bytesToShort(bytes2));
-
- final byte[] bytes3 = { (byte) 0x25, (byte) 0x34 };
- final short expectedShort3 = (short) 0x2534;
- assertEquals(expectedShort3, ByteArray.bytesToShort(bytes3));
- }
-
- @Test
- public void testShortToBytes() {
- final byte[] expectedBytes1 = { (byte) 0x00, (byte) 0x01 };
- assertArrayEquals(expectedBytes1, ByteArray.shortToBytes((short) 1));
-
- final byte[] expectedBytes2 = { (byte) 0xFF, (byte) 0xFF };
- assertArrayEquals(expectedBytes2, ByteArray.shortToBytes((short) 0xFFFF));
-
- final byte[] expectedBytes3 = { (byte) 0x25, (byte) 0x34 };
- assertArrayEquals(expectedBytes3, ByteArray.shortToBytes((short) 0x2534));
- }
-
- @Test
- public void testFloatToBytes() {
- final byte[] expectedBytes1 = { (byte) 0x35, (byte) 0x86, (byte) 0x37, (byte) 0xbd };
- assertArrayEquals(expectedBytes1, ByteArray.floatToBytes((float) 0.000001));
-
- final byte[] expectedBytes2 = { (byte) 0xEF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
- assertArrayEquals(expectedBytes2, ByteArray.floatToBytes((float) -158456315583795709447797473280.0));
-
- final byte[] expectedBytes3 = { (byte) 0x49, (byte) 0xbf, (byte) 0x1c, (byte) 0x92 };
- assertArrayEquals(expectedBytes3, ByteArray.floatToBytes((float) 1565586.253637));
- }
-
- @Test
- public void testBytesToHexString() {
- final byte[] b = new byte[] { 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01, 0x16, 0x01,
- 0x16, };
- final String expected = "01 16 01 16 01 16 01 16 01 16 01 16 01 16 01 16\n01 16 ";
- assertEquals(expected, ByteArray.bytesToHexString(b));
- }
-
@Test
public void testBytesToHRString() {
byte[] b;
assertEquals(Arrays.toString(b), ByteArray.bytesToHRString(b));
}
- @Test
- public void testFindByteSequence() {
- final byte[] bytes = new byte[] { (byte) 36, (byte) 41, (byte) 55, (byte) 101, (byte) 38 };
- final byte[] sequence1 = new byte[] { (byte) 36, (byte) 41 };
-
- assertEquals(0, ByteArray.findByteSequence(bytes, sequence1));
-
- final byte[] sequence2 = new byte[] { (byte) 55, (byte) 38 };
-
- assertEquals(-1, ByteArray.findByteSequence(bytes, sequence2));
-
- final byte[] sequence3 = new byte[] { (byte) 101, (byte) 38 };
-
- assertEquals(3, ByteArray.findByteSequence(bytes, sequence3));
-
- try {
- ByteArray.findByteSequence(bytes, new byte[] { (byte) 36, (byte) 41, (byte) 55, (byte) 101, (byte) 38, (byte) 66 });
- } catch (final IllegalArgumentException e) {
- assertEquals("Sequence to be found is longer than the given byte array.", e.getMessage());
- }
- }
-
- @Test
- public void testMaskBytes() {
- final byte[] bytes = new byte[] { (byte) 0xAC, (byte) 0xA8, (byte) 0x1F, (byte) 0x08 };
- try {
- ByteArray.maskBytes(bytes, 48);
- } catch (final IllegalArgumentException e) {
- assertEquals("Attempted to apply invalid mask (too long)", e.getMessage());
- }
-
- assertArrayEquals(bytes, ByteArray.maskBytes(bytes, 32));
-
- assertArrayEquals(new byte[] { (byte) 0xAC, (byte) 0x80, 0, 0 }, ByteArray.maskBytes(bytes, 10));
- }
-
@Test(expected=UnsupportedOperationException.class)
public void testPrivateConstructor() throws Throwable {
final Constructor<ByteArray> c = ByteArray.class.getDeclaredConstructor();
c.setAccessible(true);
try {
c.newInstance();
- } catch (InvocationTargetException e) {
+ } catch (final InvocationTargetException e) {
throw e.getCause();
}
}