From e41fe709513a989fb9d1ac8977d1b6585e0cf768 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Thu, 14 Apr 2016 13:15:49 +0200 Subject: [PATCH] Implementation of CustomBinaryStruct Serializer done --- src/zutil/parser/binary/BinaryFieldData.java | 24 +++++++++- .../binary/BinaryStructInputStream.java | 45 +++++++++---------- .../binary/BinaryStructOutputStream.java | 32 +++++++------ .../binary/BinaryStructInputStreamTest.java | 29 ++++++++++++ .../binary/BinaryStructOutputStreamTest.java | 33 ++++++++------ 5 files changed, 111 insertions(+), 52 deletions(-) diff --git a/src/zutil/parser/binary/BinaryFieldData.java b/src/zutil/parser/binary/BinaryFieldData.java index 28ead5b..164c3d0 100755 --- a/src/zutil/parser/binary/BinaryFieldData.java +++ b/src/zutil/parser/binary/BinaryFieldData.java @@ -59,7 +59,7 @@ public class BinaryFieldData { } } - protected void setValue(Object obj, byte[] data){ + protected void setByteValue(Object obj, byte[] data){ try { field.setAccessible(true); if (field.getType() == Boolean.class || field.getType() == boolean.class) @@ -74,8 +74,16 @@ public class BinaryFieldData { e.printStackTrace(); } } + protected void setValue(Object obj, Object value){ + try { + field.setAccessible(true); + field.set(obj, value); + } catch (IllegalAccessException e){ + e.printStackTrace(); + } + } - protected byte[] getValue(Object obj){ + protected byte[] getByteValue(Object obj){ try { field.setAccessible(true); if (field.getType() == Boolean.class || field.getType() == boolean.class) @@ -91,10 +99,22 @@ public class BinaryFieldData { } return null; } + protected Object getValue(Object obj){ + try { + field.setAccessible(true); + return field.get(obj); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return null; + } public int getBitLength(){ return length; } + public BinaryFieldSerializer getSerializer(){ + return serializer; + } } \ No newline at end of file diff --git a/src/zutil/parser/binary/BinaryStructInputStream.java b/src/zutil/parser/binary/BinaryStructInputStream.java index 7115f28..1234e90 100755 --- a/src/zutil/parser/binary/BinaryStructInputStream.java +++ b/src/zutil/parser/binary/BinaryStructInputStream.java @@ -25,17 +25,10 @@ package zutil.parser.binary; import zutil.ByteUtil; -import zutil.converter.Converter; -import zutil.parser.binary.BinaryStruct.BinaryField; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; /** @@ -78,23 +71,29 @@ public class BinaryStructInputStream { int totalReadLength = 0; for (BinaryFieldData field : structDataList){ - byte[] valueData = new byte[(int) Math.ceil(field.getBitLength() / 8.0)]; - int fieldReadLength = 0; - - // Parse value - for (int valueDataIndex = 0; valueDataIndex < valueData.length; ++valueDataIndex) { - if(dataBitIndex < 0) { // Read new data? - data = (byte) in.read(); - dataBitIndex = 7; - } - int bitLength = Math.min(dataBitIndex+1, field.getBitLength() - fieldReadLength); - valueData[valueDataIndex] = ByteUtil.getShiftedBits(data, dataBitIndex, bitLength); - fieldReadLength += bitLength; - dataBitIndex -= bitLength; + if (field.getSerializer() != null){ + Object value = field.getSerializer().read(in, field); + field.setValue(struct, value); + } + else { + byte[] valueData = new byte[(int) Math.ceil(field.getBitLength() / 8.0)]; + int fieldReadLength = 0; + + // Parse value + for (int valueDataIndex = 0; valueDataIndex < valueData.length; ++valueDataIndex) { + if (dataBitIndex < 0) { // Read new data? + data = (byte) in.read(); + dataBitIndex = 7; + } + int bitLength = Math.min(dataBitIndex + 1, field.getBitLength() - fieldReadLength); + valueData[valueDataIndex] = ByteUtil.getShiftedBits(data, dataBitIndex, bitLength); + fieldReadLength += bitLength; + dataBitIndex -= bitLength; + } + // Set value + field.setByteValue(struct, valueData); + totalReadLength += fieldReadLength; } - // Set value - field.setValue(struct, valueData); - totalReadLength += fieldReadLength; } return totalReadLength; diff --git a/src/zutil/parser/binary/BinaryStructOutputStream.java b/src/zutil/parser/binary/BinaryStructOutputStream.java index 9e6b1e0..a3b3cc6 100755 --- a/src/zutil/parser/binary/BinaryStructOutputStream.java +++ b/src/zutil/parser/binary/BinaryStructOutputStream.java @@ -73,20 +73,26 @@ public class BinaryStructOutputStream { List structDataList = BinaryFieldData.getStructFieldList(struct.getClass()); for (BinaryFieldData field : structDataList){ - byte[] data = field.getValue(struct); + if (field.getSerializer() != null){ + localFlush(); + field.getSerializer().write(out, field.getValue(struct), field); + } + else{ + byte[] data = field.getByteValue(struct); - int fieldBitLength = field.getBitLength(); - for (int i=(int)Math.ceil(fieldBitLength/8.0)-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(); + int fieldBitLength = field.getBitLength(); + for (int i = (int) Math.ceil(fieldBitLength / 8.0) - 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(); + } } } } diff --git a/test/zutil/parser/binary/BinaryStructInputStreamTest.java b/test/zutil/parser/binary/BinaryStructInputStreamTest.java index f1fd437..d4cc248 100755 --- a/test/zutil/parser/binary/BinaryStructInputStreamTest.java +++ b/test/zutil/parser/binary/BinaryStructInputStreamTest.java @@ -26,6 +26,10 @@ package zutil.parser.binary; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; @@ -125,4 +129,29 @@ public class BinaryStructInputStreamTest { BinaryStructInputStream.read(struct, new byte[]{0b0000_0001,0b0001_1000,0b0000_0000}); struct.assertObj(); } + + + @Test + public void customBinaryField(){ + BinaryTestStruct struct = new BinaryTestStruct() { + @CustomBinaryField(index=1, serializer=ByteStringSerializer.class) + public String s1; + + public void assertObj(){ + assertEquals("1234", s1); + } + }; + + BinaryStructInputStream.read(struct, new byte[]{0b0000_0001,0b0000_0010,0b0000_0011,0b0000_0100}); + struct.assertObj(); + } + public static class ByteStringSerializer implements BinaryFieldSerializer{ + public String read(InputStream in, BinaryFieldData field) throws IOException { + String ret = ""; + for (int c; (c=in.read()) > 0; ) + ret += c; + return ret; + } + public void write(OutputStream out, String obj, BinaryFieldData field) throws IOException {} + } } diff --git a/test/zutil/parser/binary/BinaryStructOutputStreamTest.java b/test/zutil/parser/binary/BinaryStructOutputStreamTest.java index 083cc60..8020b83 100755 --- a/test/zutil/parser/binary/BinaryStructOutputStreamTest.java +++ b/test/zutil/parser/binary/BinaryStructOutputStreamTest.java @@ -26,10 +26,10 @@ package zutil.parser.binary; import org.junit.Test; -import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; -import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertArrayEquals; @@ -77,20 +77,25 @@ public class BinaryStructOutputStreamTest { byte[] data = BinaryStructOutputStream.serialize(struct); assertArrayEquals(new byte[]{(byte)0b0100_0000}, data); } -/* - @Test - public void basicStringTest(){ - BinaryTestStruct struct = new BinaryTestStruct() { - @BinaryField(index=1, length=8*12) - public String s1; - public void assertObj(Object... expected){ - assertEquals(s1, "hello world!"); - } + + @Test + public void customBinaryField() throws IOException { + BinaryStruct struct = new BinaryStruct() { + @BinaryStruct.CustomBinaryField(index=1, serializer=ByteStringSerializer.class) + public String s1 = "1234"; }; - BinaryStructParser.parse(struct, "hello world!".getBytes()); - struct.assertObj(); + byte[] data = BinaryStructOutputStream.serialize(struct); + assertArrayEquals(new byte[]{0b0000_0001,0b0000_0010,0b0000_0011,0b0000_0100}, data); + } + public static class ByteStringSerializer implements BinaryFieldSerializer{ + public String read(InputStream in, BinaryFieldData field) throws IOException { + return null; + } + public void write(OutputStream out, String obj, BinaryFieldData field) throws IOException { + for (char c : obj.toCharArray()) + out.write(Integer.parseInt(""+c)); + } } - */ }