diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java index f1ab738..42541e6 100644 --- a/src/main/java/at/favre/lib/bytes/Bytes.java +++ b/src/main/java/at/favre/lib/bytes/Bytes.java @@ -2044,6 +2044,25 @@ public double[] toDoubleArray() { return Util.Converter.toDoubleArray(internalArray(), byteOrder); } + /** + * Converts the internal byte array to a short array, that is, every 2 bytes will be packed into a single short. + *

+ * E.g. 2 bytes will be packed to a length 1 short array: + *

+     *  [b1, b2] = [short1]
+     * 
+ *

+ * This conversion respects the internal byte order. Will only work if all bytes can be directly mapped to short, + * which means the byte array length must be dividable by 2 without rest. + * + * @return new short[] instance representing this byte array + * @throws IllegalArgumentException if internal byte length mod 2 != 0 + */ + public short[] toShortArray() { + Util.Validation.checkModLength(length(), 2, "creating a short array"); + return Util.Converter.toShortArray(internalArray(), byteOrder); + } + /** * Decodes the internal byte array to UTF-8 char array. * This implementation will not internally create a {@link String}. diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java index ee494fc..da50ff0 100644 --- a/src/main/java/at/favre/lib/bytes/Util.java +++ b/src/main/java/at/favre/lib/bytes/Util.java @@ -860,6 +860,34 @@ static double[] toDoubleArray(byte[] bytes, ByteOrder byteOrder) { return array; } + + /** + * Converts the byte array to a short array. This will spread 2 bytes into a single short: + * + *

+         *     [b1, b2] = [short1]
+         * 
+ * + *

+ * Analysis + *

+ *

+ * + * @param bytes to convert to short array, must be % 2 == 0 to work correctly + * @param byteOrder of the byte array + * @return short array + */ + static short[] toShortArray(byte[] bytes, ByteOrder byteOrder) { + ShortBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asShortBuffer(); + short[] array = new short[buffer.remaining()]; + buffer.get(array); + return array; + } + /** * Convert UUID to a newly generated 16 byte long array representation. Puts the 8 byte most significant bits and * 8 byte least significant bits into an byte array. diff --git a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java index 4c1ff0f..efa1559 100644 --- a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java +++ b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java @@ -406,4 +406,38 @@ public void testToDoubleArrayLittleEndian() { 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).toDoubleArray(), 0.01); } + + @Test + public void testToShortArrayEmpty() { + assertArrayEquals(new short[0], Bytes.empty().toShortArray()); + } + + + @Test(expected = IllegalArgumentException.class) + public void testToShortArrayNotMod2Was5Byte() { + Bytes.wrap(new byte[]{0, 0, 0, 0, 1}).toShortArray(); + } + + @Test + public void testToShortArray() { + assertArrayEquals(new short[]{1}, Bytes.wrap(new byte[]{0, 1}).toShortArray()); + assertArrayEquals(new short[]{257}, Bytes.wrap(new byte[]{1, 1}).toShortArray()); + assertArrayEquals(new short[]{32_767}, Bytes.wrap(new byte[]{127, -1}).toShortArray()); + + assertArrayEquals(new short[]{1, 1}, Bytes.wrap(new byte[]{0, 1, 0, 1}).toShortArray()); + assertArrayEquals(new short[]{257, 1}, Bytes.wrap(new byte[]{1, 1, 0, 1}).toShortArray()); + assertArrayEquals(new short[]{257, 32_767, 1}, Bytes.wrap(new byte[]{1, 1, 127, -1, 0, 1}).toShortArray()); + } + + @Test + public void testToShortArrayLittleEndian() { + assertArrayEquals(new short[]{1}, Bytes.wrap(new byte[]{1, 0}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + assertArrayEquals(new short[]{257}, Bytes.wrap(new byte[]{1, 1}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + assertArrayEquals(new short[]{32_767}, Bytes.wrap(new byte[]{-1, 127}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + + assertArrayEquals(new short[]{1, 1}, Bytes.wrap(new byte[]{1, 0, 1, 0}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + assertArrayEquals(new short[]{257, 1}, Bytes.wrap(new byte[]{1, 1, 1, 0}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + assertArrayEquals(new short[]{257, 32_767, 1}, Bytes.wrap(new byte[]{1, 1, -1, 127, 1, 0}, ByteOrder.LITTLE_ENDIAN).toShortArray()); + } + } diff --git a/src/test/java/at/favre/lib/bytes/UtilConverterTest.java b/src/test/java/at/favre/lib/bytes/UtilConverterTest.java index 8aa717f..3ac6f7b 100644 --- a/src/test/java/at/favre/lib/bytes/UtilConverterTest.java +++ b/src/test/java/at/favre/lib/bytes/UtilConverterTest.java @@ -193,4 +193,20 @@ public void testToDoubleArray() { assertArrayEquals(new double[0], Util.Converter.toDoubleArray(new byte[0], ByteOrder.LITTLE_ENDIAN), 0.01); assertArrayEquals(new double[0], Util.Converter.toDoubleArray(new byte[0], ByteOrder.BIG_ENDIAN), 0.01); } + + @Test + public void testToShortArray() { + assertArrayEquals(new short[]{1}, Util.Converter.toShortArray(new byte[]{0, 1}, ByteOrder.BIG_ENDIAN)); + assertArrayEquals(new short[]{257}, Util.Converter.toShortArray(new byte[]{1, 1}, ByteOrder.BIG_ENDIAN)); + assertArrayEquals(new short[]{32_767}, Util.Converter.toShortArray(new byte[]{127, -1}, ByteOrder.BIG_ENDIAN)); + assertArrayEquals(new short[]{257, 32_767, 1}, Util.Converter.toShortArray(new byte[]{1, 1, 127, -1, 0, 1}, ByteOrder.BIG_ENDIAN)); + + assertArrayEquals(new short[]{1}, Util.Converter.toShortArray(new byte[]{1, 0}, ByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new short[]{257}, Util.Converter.toShortArray(new byte[]{1, 1}, ByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new short[]{32_767}, Util.Converter.toShortArray(new byte[]{-1, 127}, ByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new short[]{257, 32_767, 1}, Util.Converter.toShortArray(new byte[]{1, 1, -1, 127, 1, 0}, ByteOrder.LITTLE_ENDIAN)); + + assertArrayEquals(new short[0], Util.Converter.toShortArray(new byte[0], ByteOrder.LITTLE_ENDIAN)); + assertArrayEquals(new short[0], Util.Converter.toShortArray(new byte[0], ByteOrder.BIG_ENDIAN)); + } }