ValidationBitStreamReaderTest.java
package zserio.runtime.validation;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import zserio.runtime.array.Array;
import zserio.runtime.array.ArrayTraits;
import zserio.runtime.array.ArrayType;
import zserio.runtime.array.RawArray;
import zserio.runtime.io.ByteArrayBitStreamWriter;
public class ValidationBitStreamReaderTest
{
@Test
public void validationWithReadOnly() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeBits(2, 2);
writer.writeBits(7, 3);
writer.writeBits(9, 4);
writer.writeBits(10, 5);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// put rubbish at the end position which is not used
changedStream[changedStream.length - 1] |= 0x01;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertEquals(1, reader.readBits(1));
assertEquals(2, reader.readBits(2));
assertEquals(7, reader.readBits(3));
assertEquals(9, reader.readBits(4));
assertEquals(10, reader.readBits(5));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithAlignTo() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.alignTo(2);
writer.writeBits(2, 2);
writer.alignTo(4);
writer.writeBits(7, 3);
writer.alignTo(4);
writer.writeBits(9, 4);
writer.alignTo(8);
writer.writeBits(10, 5);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// put rubbish to the aligned dummy bits and at the end
changedStream[0] |= 0x40;
changedStream[0] |= 0x01;
changedStream[1] |= 0x0F;
changedStream[2] |= 0x03;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertEquals(1, reader.readBits(1));
reader.alignTo(2);
assertEquals(2, reader.readBits(2));
reader.alignTo(4);
assertEquals(7, reader.readBits(3));
reader.alignTo(4);
assertEquals(9, reader.readBits(4));
reader.alignTo(8);
assertEquals(10, reader.readBits(5));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithSkipBits() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeBits(0, 1); // skip
writer.writeBits(2, 2);
writer.writeBits(0, 2); // skip
writer.writeBits(7, 3);
writer.writeBits(0, 3); // skip
writer.writeBits(9, 4);
writer.writeBits(0, 4); // skip
writer.writeBits(10, 5);
writer.writeBits(0, 5); // skip
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// put rubbish to the skipped dummy bits and at the end
changedStream[0] |= 0x40;
changedStream[0] |= 0x0C;
changedStream[1] |= 0x70;
changedStream[2] |= 0xF0;
changedStream[3] |= 0x7C;
changedStream[3] |= 0x03;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertEquals(1, reader.readBits(1));
reader.setBitPosition(reader.getBitPosition() + 1);
assertEquals(2, reader.readBits(2));
reader.setBitPosition(reader.getBitPosition() + 2);
assertEquals(7, reader.readBits(3));
reader.setBitPosition(reader.getBitPosition() + 3);
assertEquals(9, reader.readBits(4));
reader.setBitPosition(reader.getBitPosition() + 4);
assertEquals(10, reader.readBits(5));
reader.setBitPosition(reader.getBitPosition() + 5);
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithSkipBytes() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeBits(0, 8); // skip
writer.writeBits(2, 2);
writer.writeBits(0, 8); // skip
writer.writeBits(7, 3);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// put rubbish to the skipped dummy bits and at the end
changedStream[0] |= 0x7F;
changedStream[1] |= 0x80;
changedStream[1] |= 0x1F;
changedStream[2] |= 0xE0;
changedStream[2] |= 0x03;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertEquals(1, reader.readBits(1));
reader.setBitPosition(reader.getBitPosition() + 8);
assertEquals(2, reader.readBits(2));
reader.setBitPosition(reader.getBitPosition() + 8);
assertEquals(7, reader.readBits(3));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithSetPosition() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeBits(2, 2);
writer.writeBits(7, 3);
writer.writeBits(9, 4);
writer.writeBits(10, 5);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// put rubbish at the end position which is not used
changedStream[changedStream.length - 1] |= 0x01;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
reader.readBits(16);
reader.setBitPosition(0);
assertEquals(1, reader.readBits(1));
assertEquals(2, reader.readBits(2));
assertEquals(7, reader.readBits(3));
assertEquals(9, reader.readBits(4));
assertEquals(10, reader.readBits(5));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithImplicitArray() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(0xAB, 8);
writer.writeBits(0xCD, 8);
final byte[] originalStream = writer.toByteArray();
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(originalStream))
{
final RawArray rawArray = new RawArray.ShortRawArray();
final ArrayTraits arrayTraits = new ArrayTraits.BitFieldShortArrayTraits(8);
final Array readArray = new Array(rawArray, arrayTraits, ArrayType.IMPLICIT);
readArray.read(reader);
final short[] readRawArray = readArray.getRawArray();
assertEquals(0xAB, readRawArray[0]);
assertEquals(0xCD, readRawArray[1]);
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithNan() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeFloat16(Float.NaN);
writer.writeBits(2, 2);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// change NaN to binary represantation which is not used by writer
changedStream[0] |= 0x40;
changedStream[1] |= 0xFF;
changedStream[2] |= 0x80;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertEquals(1, reader.readBits(1));
assertTrue(Float.isNaN(reader.readFloat16()));
assertEquals(2, reader.readBits(2));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
@Test
public void validationWithNanAndSetPosition() throws IOException
{
try (final ByteArrayBitStreamWriter writer = new ByteArrayBitStreamWriter())
{
writer.writeBits(1, 1);
writer.writeFloat16(Float.NaN);
writer.writeBits(2, 2);
final byte[] originalStream = writer.toByteArray();
final byte[] changedStream = new byte[originalStream.length];
System.arraycopy(originalStream, 0, changedStream, 0, changedStream.length);
// change NaN to binary representation which is not used by writer
changedStream[0] |= 0x40;
changedStream[1] |= 0xFF;
changedStream[2] |= 0x80;
try (final ValidationBitStreamReader reader = new ValidationBitStreamReader(changedStream))
{
assertTrue(Float.isNaN(reader.readFloat16()));
reader.setBitPosition(0);
assertEquals(1, reader.readBits(1));
assertTrue(Float.isNaN(reader.readFloat16()));
assertEquals(2, reader.readBits(2));
final byte[] maskedStream = reader.toMaskedByteArray();
assertTrue(Arrays.equals(originalStream, maskedStream));
}
}
}
}