Skip to content

Commit

Permalink
Add implicit conversion from integral types to byte array
Browse files Browse the repository at this point in the history
Integral types are converted to a byte array with a Big Endian byte
order and size as the number of bytes used to represent the integral
value in two's complement binary form.

Issue: junit-team#2702
  • Loading branch information
scordio committed Sep 7, 2021
1 parent d25b650 commit c244810
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -64,6 +66,12 @@
* {@link File}, {@link BigDecimal}, {@link BigInteger}, {@link Currency},
* {@link Locale}, {@link URI}, {@link URL}, {@link UUID}, etc.
*
* <p>The {@code DefaultArgumentConverter} can also convert from primitive
* integral types (byte, short, int and long) and their corresponding wrapper
* types to a byte array, having {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN} byte
* order and size equals to the number of bytes used to represent the integral
* value in two's complement binary form.
*
* <p>If the source and target types are identical the source object will not
* be modified.
*
Expand All @@ -84,6 +92,8 @@ public class DefaultArgumentConverter extends SimpleArgumentConverter {
new FallbackStringToObjectConverter() //
));

private static final IntegralTypesToByteArrayConverter integralTypesToByteArrayConverter = new IntegralTypesToByteArrayConverter();

private DefaultArgumentConverter() {
// nothing to initialize
}
Expand Down Expand Up @@ -124,6 +134,9 @@ private Object convertToTargetType(Object source, Class<?> targetType) {
}
}
}
if (targetType == byte[].class && integralTypesToByteArrayConverter.canConvert(source.getClass())) {
return integralTypesToByteArrayConverter.convert(source);
}
throw new ArgumentConversionException("No implicit conversion to convert object of type "
+ source.getClass().getName() + " to type " + targetType.getName());
}
Expand Down Expand Up @@ -299,4 +312,29 @@ private static URL toURL(String url) {

}

private static class IntegralTypesToByteArrayConverter {

private boolean canConvert(Class<?> sourceType) {
return sourceType == Byte.class || sourceType == Short.class || sourceType == Integer.class
|| sourceType == Long.class;
}

private byte[] convert(Object source) {
if (source instanceof Byte) {
return ByteBuffer.allocate(Byte.BYTES).put((Byte) source).array();
}
if (source instanceof Short) {
return ByteBuffer.allocate(Short.BYTES).putShort((Short) source).array();
}
if (source instanceof Integer) {
return ByteBuffer.allocate(Integer.BYTES).putInt((Integer) source).array();
}
if (source instanceof Long) {
return ByteBuffer.allocate(Long.BYTES).putLong((Long) source).array();
}
throw new ArgumentConversionException("Cannot convert object of type " + source.getClass().getName());
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,17 @@ void convertsStringToUUID() {

// -------------------------------------------------------------------------

/**
* @since FIXME
*/
@Test
void convertsIntegralTypesToByteArray() {
assertConverts((byte) 0x7F, byte[].class, new byte[] { 127 });
assertConverts((short) 0x7E7F, byte[].class, new byte[] { 126, 127 });
assertConverts(0x7C7D7E7F, byte[].class, new byte[] { 124, 125, 126, 127 });
assertConverts(0x78797A7B7C7D7E7FL, byte[].class, new byte[] { 120, 121, 122, 123, 124, 125, 126, 127 });
}

private void assertConverts(Object input, Class<?> targetClass, Object expectedOutput) {
var result = DefaultArgumentConverter.INSTANCE.convert(input, targetClass);

Expand Down

0 comments on commit c244810

Please sign in to comment.