From 227f294ae05abc848a335c6ac7fbfb14c1748d73 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Tue, 8 Mar 2016 23:27:15 +0100 Subject: [PATCH] implemented variable length field --- src/zutil/ByteUtil.java | 40 ++++++++++-------- .../binary/BinaryStructOutputStream.java | 41 ++++++++++++++----- .../binary/BinaryStructOutputStreamTest.java | 21 ++++------ 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/zutil/ByteUtil.java b/src/zutil/ByteUtil.java index 281e605..2d106f4 100755 --- a/src/zutil/ByteUtil.java +++ b/src/zutil/ByteUtil.java @@ -43,36 +43,44 @@ public class ByteUtil { }; /** - * Creates a new subbyte from offset and with a length and shifts the data to the left + * Creates a new sub byte from index and with a length and shifts the data to the left * * @param data is the byte data - * @param offset is the bit index, valid values 0-7 + * @param index is the bit index, valid values 0-7 * @param length is the length of bits to return, valid values 1-8 - * @return a new byte containing a subbyte defined by the offset and length + * @return a new byte containing a sub byte defined by the index and length */ - public static byte getShiftedBits(byte data, int offset, int length){ - int ret = 0xFF & getBits(data, offset, length); - ret = ret >>> offset+1-length; + public static byte getShiftedBits(byte data, int index, int length){ + int ret = 0xFF & getBits(data, index, length); + ret = ret >>> index+1-length; return (byte) ret; } /** - * Creates a new subbyte from offset and with a length + * Creates a new sub byte from index and with a length * * @param data is the byte data - * @param offset is the bit index, valid values 0-7 + * @param index is the bit index, valid values 0-7 * @param length is the length of bits to return, valid values 1-8 - * @return a new byte containing a subbyte defined by the offset and length + * @return a new byte containing a sub byte defined by the index and length */ - public static byte getBits(byte data, int offset, int length){ + public static byte getBits(byte data, int index, int length){ length--; - if(0 > offset || offset > 7) - throw new IllegalArgumentException("Invalid index argument, allowed value is 0-7"); - if(length < 0 && offset-length < 0) - throw new IllegalArgumentException("Invalid length argument: "+length+", allowed values 1-8 depending on index"); - - byte ret = (byte) (data & BYTE_MASK[offset][length]); + byte ret = (byte) (data & getBitMask(index, length)); return ret; } + /** + * Returns a byte bitmask + * + * @param index start index of the mask, valid values 0-7 + * @param length length of mask from index, valid values 1-8 + */ + public static byte getBitMask(int index, int length) { + if(0 > index || index > 7) + throw new IllegalArgumentException("Invalid index argument, allowed value is 0-7"); + if(length < 0 && index-length < 0) + throw new IllegalArgumentException("Invalid length argument: "+length+", allowed values 1-8 depending on index"); + return (byte) BYTE_MASK[index][length]; + } } diff --git a/src/zutil/parser/binary/BinaryStructOutputStream.java b/src/zutil/parser/binary/BinaryStructOutputStream.java index 307addf..500cccc 100755 --- a/src/zutil/parser/binary/BinaryStructOutputStream.java +++ b/src/zutil/parser/binary/BinaryStructOutputStream.java @@ -24,6 +24,9 @@ package zutil.parser.binary; +import zutil.ByteUtil; + +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -39,14 +42,14 @@ public class BinaryStructOutputStream { private OutputStream out; private byte rest; - private int restLength; + private int restBitLength; // length from Most Significant Bit public BinaryStructOutputStream(OutputStream out){ this.out = out; rest = 0; - restLength = 0; + restBitLength = 0; } @@ -54,9 +57,13 @@ public class BinaryStructOutputStream { * Generate a binary byte array from the provided struct. * The byte array will be left */ -/* public byte[] serialize(BinaryStruct struct) { - - }*/ + public static byte[] serialize(BinaryStruct struct) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + BinaryStructOutputStream out = new BinaryStructOutputStream(buffer); + out.write(struct); + out.flush(); + return buffer.toByteArray(); + } /** * Generate a binary stream from the provided struct and @@ -68,8 +75,19 @@ public class BinaryStructOutputStream { for (BinaryFieldData field : structDataList){ byte[] data = field.getValue(struct); - for (int i=data.length-1; i>=0; --i) { - out.write(data[i]); + int fieldBitLength = field.getBitLength(); + for (int i=data.length-1; fieldBitLength>0; fieldBitLength-=8, --i) { + byte b = data[i]; + if (restBitLength == 0 && fieldBitLength >= 8) + out.write(0xFF & b); + else { + b <<= 8-restBitLength-fieldBitLength; + b &= ByteUtil.getBitMask(7-restBitLength, fieldBitLength); + rest |= b; + restBitLength += fieldBitLength; + if (restBitLength >= 8) + localFlush(); + } } } } @@ -79,12 +97,15 @@ public class BinaryStructOutputStream { * Writes any outstanding data to the stream */ public void flush() throws IOException { - if(restLength > 0){ + localFlush(); + out.flush(); + } + private void localFlush() throws IOException { + if(restBitLength > 0){ out.write(0xFF & rest); rest = 0; - restLength = 0; + restBitLength = 0; } - out.flush(); } /** diff --git a/test/zutil/parser/binary/BinaryStructOutputStreamTest.java b/test/zutil/parser/binary/BinaryStructOutputStreamTest.java index daa129a..df50012 100755 --- a/test/zutil/parser/binary/BinaryStructOutputStreamTest.java +++ b/test/zutil/parser/binary/BinaryStructOutputStreamTest.java @@ -47,23 +47,23 @@ public class BinaryStructOutputStreamTest { public int i2 = 2; }; - byte[] data = serialize(struct); + byte[] data = BinaryStructOutputStream.serialize(struct); assertArrayEquals(new byte[]{0,0,0,1, 0,0,0,2}, data); } -/* + @Test public void basicBooleanTest() throws IOException { BinaryStruct struct = new BinaryStruct() { @BinaryField(index=1, length=1) - public boolean b1 = true; + public boolean b1 = false; @BinaryField(index=2, length=1) - public boolean b2 = false; + public boolean b2 = true; }; - byte[] data = serialize(struct); - assertArrayEquals(new byte[]{(byte)0b1000_0000}, data); + byte[] data = BinaryStructOutputStream.serialize(struct); + assertArrayEquals(new byte[]{(byte)0b0100_0000}, data); } - +/* @Test public void basicStringTest(){ BinaryTestStruct struct = new BinaryTestStruct() { @@ -79,11 +79,4 @@ public class BinaryStructOutputStreamTest { struct.assertObj(); } */ - - private byte[] serialize(BinaryStruct struct) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - BinaryStructOutputStream out = new BinaryStructOutputStream(buffer); - out.write(struct); - return buffer.toByteArray(); - } }