ByteArrayUtilTest.java
package tools.jackson.core.unittest.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Random;
import org.junit.jupiter.api.Test;
import tools.jackson.core.unittest.*;
import tools.jackson.core.util.ByteArrayUtil;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests for {@link ByteArrayUtil} accessors, checked against {@link ByteBuffer}
* as an independent oracle.
*/
public class ByteArrayUtilTest extends JacksonCoreTestBase
{
private final static int OFFSET = 3; // deliberately unaligned
/*
/**********************************************************************
/* Test methods, reading
/**********************************************************************
*/
@Test
void getIntLE()
{
for (byte[] input : _inputs(4)) {
final int exp = ByteBuffer.wrap(input, OFFSET, 4)
.order(ByteOrder.LITTLE_ENDIAN).getInt();
assertEquals(exp, ByteArrayUtil.getIntLE(input, OFFSET),
"for input "+Arrays.toString(input));
}
}
@Test
void getIntBE()
{
for (byte[] input : _inputs(4)) {
final int exp = ByteBuffer.wrap(input, OFFSET, 4)
.order(ByteOrder.BIG_ENDIAN).getInt();
assertEquals(exp, ByteArrayUtil.getIntBE(input, OFFSET),
"for input "+Arrays.toString(input));
}
}
@Test
void getLongLE()
{
for (byte[] input : _inputs(8)) {
final long exp = ByteBuffer.wrap(input, OFFSET, 8)
.order(ByteOrder.LITTLE_ENDIAN).getLong();
assertEquals(exp, ByteArrayUtil.getLongLE(input, OFFSET),
"for input "+Arrays.toString(input));
}
}
@Test
void getLongBE()
{
for (byte[] input : _inputs(8)) {
final long exp = ByteBuffer.wrap(input, OFFSET, 8)
.order(ByteOrder.BIG_ENDIAN).getLong();
assertEquals(exp, ByteArrayUtil.getLongBE(input, OFFSET),
"for input "+Arrays.toString(input));
}
}
/*
/**********************************************************************
/* Test methods, writing
/**********************************************************************
*/
@Test
void setIntLE()
{
for (int value : _intValues()) {
byte[] exp = new byte[OFFSET+4];
ByteBuffer.wrap(exp, OFFSET, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(value);
byte[] act = new byte[OFFSET+4];
ByteArrayUtil.setIntLE(act, OFFSET, value);
assertArrayEquals(exp, act, "for value "+value);
assertEquals(value, ByteArrayUtil.getIntLE(act, OFFSET));
}
}
@Test
void setIntBE()
{
for (int value : _intValues()) {
byte[] exp = new byte[OFFSET+4];
ByteBuffer.wrap(exp, OFFSET, 4).order(ByteOrder.BIG_ENDIAN).putInt(value);
byte[] act = new byte[OFFSET+4];
ByteArrayUtil.setIntBE(act, OFFSET, value);
assertArrayEquals(exp, act, "for value "+value);
assertEquals(value, ByteArrayUtil.getIntBE(act, OFFSET));
}
}
@Test
void setLongLE()
{
for (long value : _longValues()) {
byte[] exp = new byte[OFFSET+8];
ByteBuffer.wrap(exp, OFFSET, 8).order(ByteOrder.LITTLE_ENDIAN).putLong(value);
byte[] act = new byte[OFFSET+8];
ByteArrayUtil.setLongLE(act, OFFSET, value);
assertArrayEquals(exp, act, "for value "+value);
assertEquals(value, ByteArrayUtil.getLongLE(act, OFFSET));
}
}
@Test
void setLongBE()
{
for (long value : _longValues()) {
byte[] exp = new byte[OFFSET+8];
ByteBuffer.wrap(exp, OFFSET, 8).order(ByteOrder.BIG_ENDIAN).putLong(value);
byte[] act = new byte[OFFSET+8];
ByteArrayUtil.setLongBE(act, OFFSET, value);
assertArrayEquals(exp, act, "for value "+value);
assertEquals(value, ByteArrayUtil.getLongBE(act, OFFSET));
}
}
/*
/**********************************************************************
/* Test methods, endianness relations
/**********************************************************************
*/
@Test
void endiannessIsReversed()
{
for (byte[] input : _inputs(8)) {
assertEquals(ByteArrayUtil.getIntBE(input, OFFSET),
Integer.reverseBytes(ByteArrayUtil.getIntLE(input, OFFSET)));
assertEquals(ByteArrayUtil.getLongBE(input, OFFSET),
Long.reverseBytes(ByteArrayUtil.getLongLE(input, OFFSET)));
}
}
@Test
void writesTouchNoOtherBytes()
{
// Writes must stay strictly within [offset, offset+size)
byte[] b = new byte[OFFSET+8+OFFSET];
Arrays.fill(b, (byte) 0x5A);
ByteArrayUtil.setLongBE(b, OFFSET, -1L);
for (int i = 0; i < OFFSET; ++i) {
assertEquals((byte) 0x5A, b[i], "at index "+i);
assertEquals((byte) 0x5A, b[OFFSET+8+i], "at index "+(OFFSET+8+i));
}
Arrays.fill(b, (byte) 0x5A);
ByteArrayUtil.setIntLE(b, OFFSET, -1);
for (int i = 0; i < OFFSET; ++i) {
assertEquals((byte) 0x5A, b[i], "at index "+i);
}
for (int i = OFFSET+4; i < b.length; ++i) {
assertEquals((byte) 0x5A, b[i], "at index "+i);
}
}
/*
/**********************************************************************
/* Helper methods for building inputs: sign-bit and all-bits-set cases
/* first, then pseudo-random ones (fixed seed, for reproducibility)
/**********************************************************************
*/
private byte[][] _inputs(int length) {
final int size = OFFSET + length;
byte[][] result = new byte[3+100][];
result[0] = new byte[size];
result[1] = new byte[size];
Arrays.fill(result[1], (byte) 0xFF);
result[2] = new byte[size];
result[2][OFFSET] = (byte) 0x80; // high bit of first byte only
Random rnd = new Random(1234);
for (int i = 3; i < result.length; ++i) {
byte[] b = new byte[size];
rnd.nextBytes(b);
result[i] = b;
}
return result;
}
private int[] _intValues() {
int[] result = new int[4+100];
result[0] = 0;
result[1] = -1;
result[2] = Integer.MIN_VALUE;
result[3] = Integer.MAX_VALUE;
Random rnd = new Random(5678);
for (int i = 4; i < result.length; ++i) {
result[i] = rnd.nextInt();
}
return result;
}
private long[] _longValues() {
long[] result = new long[4+100];
result[0] = 0L;
result[1] = -1L;
result[2] = Long.MIN_VALUE;
result[3] = Long.MAX_VALUE;
Random rnd = new Random(9012);
for (int i = 4; i < result.length; ++i) {
result[i] = rnd.nextLong();
}
return result;
}
}