diff --git a/src/zutil/ByteUtil.java b/src/zutil/ByteUtil.java index 8c0908f..b5f4334 100755 --- a/src/zutil/ByteUtil.java +++ b/src/zutil/ByteUtil.java @@ -137,7 +137,7 @@ public class ByteUtil { */ public static byte[] shiftLeft(byte[] data, int shiftBy) { if(0 > shiftBy || shiftBy > 8) - throw new IllegalArgumentException("Invalid shiftBy argument, allowed values: 0-8"); + throw new IllegalArgumentException("Invalid shiftBy("+shiftBy+") argument, allowed values: 0-8"); if (shiftBy == 0) return data; diff --git a/src/zutil/parser/binary/BinaryStructInputStream.java b/src/zutil/parser/binary/BinaryStructInputStream.java index a90f86c..23b5b75 100755 --- a/src/zutil/parser/binary/BinaryStructInputStream.java +++ b/src/zutil/parser/binary/BinaryStructInputStream.java @@ -78,8 +78,7 @@ public class BinaryStructInputStream { else { byte[] valueData = new byte[(int) Math.ceil(field.getBitLength(struct) / 8.0)]; int fieldReadLength = 0; // How much we have read so far - int shiftBy = (dataBitIndex+1 + field.getBitLength(struct)) % 8; - + int shiftBy = shiftBy(dataBitIndex, field.getBitLength(struct)); // Parse value for (int valueDataIndex=valueData.length-1; valueDataIndex >= 0 ; --valueDataIndex) { @@ -102,5 +101,8 @@ public class BinaryStructInputStream { return totalReadLength; } - + protected static int shiftBy(int bitIndex, int bitLength){ + int shiftBy = (8 - ((7-bitIndex) + bitLength) % 8) % 8; + return shiftBy; + } } diff --git a/test/zutil/parser/binary/BinaryStructInputStreamTest.java b/test/zutil/parser/binary/BinaryStructInputStreamTest.java index 44a8f68..3d76372 100755 --- a/test/zutil/parser/binary/BinaryStructInputStreamTest.java +++ b/test/zutil/parser/binary/BinaryStructInputStreamTest.java @@ -111,7 +111,6 @@ public class BinaryStructInputStreamTest { struct.assertObj(); } - // TODO: add full non lined length support @Test public void nonLinedLength2(){ BinaryTestStruct struct = new BinaryTestStruct() { @@ -130,6 +129,33 @@ public class BinaryStructInputStreamTest { struct.assertObj(); } + @Test + public void mixedType(){ + BinaryTestStruct struct = new BinaryTestStruct() { + @BinaryField(index=1, length=4) + public int i1; + @BinaryField(index=2, length=1) + public boolean b2; + @BinaryField(index=3, length=1) + public boolean b3; + @BinaryField(index=4, length=1) + public boolean b4; + @BinaryField(index=5, length=1) + public boolean b5; + + public void assertObj(){ + assertEquals("i1", 6, i1); + assertEquals("b2", true, b2); + assertEquals("b3", true, b3); + assertEquals("b4", false, b4); + assertEquals("b5", true, b5); + } + }; + + BinaryStructInputStream.read(struct, new byte[]{0b0110_1101}); + struct.assertObj(); + } + @Test public void customBinaryField(){ @@ -175,4 +201,51 @@ public class BinaryStructInputStreamTest { BinaryStructInputStream.read(struct, data); struct.assertObj(); } + + + @Test + public void shiftBy(){ + assertEquals(0, BinaryStructInputStream.shiftBy(0, 1)); + assertEquals(1, BinaryStructInputStream.shiftBy(1, 1)); + assertEquals(3, BinaryStructInputStream.shiftBy(3, 1)); + assertEquals(4, BinaryStructInputStream.shiftBy(4, 1)); + assertEquals(5, BinaryStructInputStream.shiftBy(5, 1)); + assertEquals(6, BinaryStructInputStream.shiftBy(6, 1)); + assertEquals(7, BinaryStructInputStream.shiftBy(7, 1)); + + assertEquals(0, BinaryStructInputStream.shiftBy(1, 2)); + assertEquals(2, BinaryStructInputStream.shiftBy(3, 2)); + assertEquals(6, BinaryStructInputStream.shiftBy(7, 2)); + + assertEquals(0, BinaryStructInputStream.shiftBy(7, 8)); + assertEquals(2, BinaryStructInputStream.shiftBy(7, 6)); + assertEquals(3, BinaryStructInputStream.shiftBy(7, 5)); + assertEquals(6, BinaryStructInputStream.shiftBy(7, 2)); + + // Cross 1 byte border + assertEquals(7, BinaryStructInputStream.shiftBy(0, 2)); + assertEquals(6, BinaryStructInputStream.shiftBy(1, 4)); + assertEquals(4, BinaryStructInputStream.shiftBy(3, 8)); + assertEquals(0, BinaryStructInputStream.shiftBy(3, 12)); + assertEquals(0, BinaryStructInputStream.shiftBy(7, 16)); + + // Cross 2 byte borders + assertEquals(0, BinaryStructInputStream.shiftBy(7, 32)); + assertEquals(7, BinaryStructInputStream.shiftBy(7, 33)); + assertEquals(6, BinaryStructInputStream.shiftBy(7, 34)); + assertEquals(5, BinaryStructInputStream.shiftBy(7, 35)); + assertEquals(4, BinaryStructInputStream.shiftBy(7, 36)); + assertEquals(3, BinaryStructInputStream.shiftBy(7, 37)); + assertEquals(2, BinaryStructInputStream.shiftBy(7, 38)); + assertEquals(1, BinaryStructInputStream.shiftBy(7, 39)); + assertEquals(0, BinaryStructInputStream.shiftBy(7, 40)); + assertEquals(7, BinaryStructInputStream.shiftBy(7, 41)); + assertEquals(6, BinaryStructInputStream.shiftBy(6, 41)); + assertEquals(5, BinaryStructInputStream.shiftBy(5, 41)); + assertEquals(4, BinaryStructInputStream.shiftBy(4, 41)); + assertEquals(3, BinaryStructInputStream.shiftBy(3, 41)); + assertEquals(2, BinaryStructInputStream.shiftBy(2, 41)); + assertEquals(1, BinaryStructInputStream.shiftBy(1, 41)); + assertEquals(0, BinaryStructInputStream.shiftBy(7, 64)); + } }