Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main/java/at/favre/lib/bytes/Bytes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* E.g. 2 bytes will be packed to a length 1 short array:
* <pre>
* [b1, b2] = [short1]
* </pre>
* <p>
* 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}.
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/at/favre/lib/bytes/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*
* <pre>
* [b1, b2] = [short1]
* </pre>
*
* <p>
* <strong>Analysis</strong>
* <ul>
* <li>Time Complexity: <code>O(n)</code></li>
* <li>Space Complexity: <code>O(n)</code></li>
* <li>Alters Parameters: <code>false</code></li>
* </ul>
* </p>
*
* @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.
Expand Down
34 changes: 34 additions & 0 deletions src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

}
16 changes: 16 additions & 0 deletions src/test/java/at/favre/lib/bytes/UtilConverterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}