Implementation of CustomBinaryStruct Serializer done
This commit is contained in:
parent
6071ad7c70
commit
e41fe70951
5 changed files with 111 additions and 52 deletions
|
|
@ -59,7 +59,7 @@ public class BinaryFieldData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setValue(Object obj, byte[] data){
|
protected void setByteValue(Object obj, byte[] data){
|
||||||
try {
|
try {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
if (field.getType() == Boolean.class || field.getType() == boolean.class)
|
if (field.getType() == Boolean.class || field.getType() == boolean.class)
|
||||||
|
|
@ -74,8 +74,16 @@ public class BinaryFieldData {
|
||||||
e.printStackTrace();
|
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 {
|
try {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
if (field.getType() == Boolean.class || field.getType() == boolean.class)
|
if (field.getType() == Boolean.class || field.getType() == boolean.class)
|
||||||
|
|
@ -91,10 +99,22 @@ public class BinaryFieldData {
|
||||||
}
|
}
|
||||||
return null;
|
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(){
|
public int getBitLength(){
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BinaryFieldSerializer getSerializer(){
|
||||||
|
return serializer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,17 +25,10 @@
|
||||||
package zutil.parser.binary;
|
package zutil.parser.binary;
|
||||||
|
|
||||||
import zutil.ByteUtil;
|
import zutil.ByteUtil;
|
||||||
import zutil.converter.Converter;
|
|
||||||
import zutil.parser.binary.BinaryStruct.BinaryField;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
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;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -78,23 +71,29 @@ public class BinaryStructInputStream {
|
||||||
|
|
||||||
int totalReadLength = 0;
|
int totalReadLength = 0;
|
||||||
for (BinaryFieldData field : structDataList){
|
for (BinaryFieldData field : structDataList){
|
||||||
byte[] valueData = new byte[(int) Math.ceil(field.getBitLength() / 8.0)];
|
if (field.getSerializer() != null){
|
||||||
int fieldReadLength = 0;
|
Object value = field.getSerializer().read(in, field);
|
||||||
|
field.setValue(struct, value);
|
||||||
// Parse value
|
}
|
||||||
for (int valueDataIndex = 0; valueDataIndex < valueData.length; ++valueDataIndex) {
|
else {
|
||||||
if(dataBitIndex < 0) { // Read new data?
|
byte[] valueData = new byte[(int) Math.ceil(field.getBitLength() / 8.0)];
|
||||||
data = (byte) in.read();
|
int fieldReadLength = 0;
|
||||||
dataBitIndex = 7;
|
|
||||||
}
|
// Parse value
|
||||||
int bitLength = Math.min(dataBitIndex+1, field.getBitLength() - fieldReadLength);
|
for (int valueDataIndex = 0; valueDataIndex < valueData.length; ++valueDataIndex) {
|
||||||
valueData[valueDataIndex] = ByteUtil.getShiftedBits(data, dataBitIndex, bitLength);
|
if (dataBitIndex < 0) { // Read new data?
|
||||||
fieldReadLength += bitLength;
|
data = (byte) in.read();
|
||||||
dataBitIndex -= bitLength;
|
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;
|
return totalReadLength;
|
||||||
|
|
|
||||||
|
|
@ -73,20 +73,26 @@ public class BinaryStructOutputStream {
|
||||||
List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass());
|
List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass());
|
||||||
|
|
||||||
for (BinaryFieldData field : structDataList){
|
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();
|
int fieldBitLength = field.getBitLength();
|
||||||
for (int i=(int)Math.ceil(fieldBitLength/8.0)-1; fieldBitLength>0; fieldBitLength-=8, --i) {
|
for (int i = (int) Math.ceil(fieldBitLength / 8.0) - 1; fieldBitLength > 0; fieldBitLength -= 8, --i) {
|
||||||
byte b = data[i];
|
byte b = data[i];
|
||||||
if (restBitLength == 0 && fieldBitLength >= 8)
|
if (restBitLength == 0 && fieldBitLength >= 8)
|
||||||
out.write(0xFF & b);
|
out.write(0xFF & b);
|
||||||
else {
|
else {
|
||||||
b <<= 8-restBitLength-fieldBitLength;
|
b <<= 8 - restBitLength - fieldBitLength;
|
||||||
b &= ByteUtil.getBitMask(7-restBitLength, fieldBitLength);
|
b &= ByteUtil.getBitMask(7 - restBitLength, fieldBitLength);
|
||||||
rest |= b;
|
rest |= b;
|
||||||
restBitLength += fieldBitLength;
|
restBitLength += fieldBitLength;
|
||||||
if (restBitLength >= 8)
|
if (restBitLength >= 8)
|
||||||
localFlush();
|
localFlush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ package zutil.parser.binary;
|
||||||
|
|
||||||
import org.junit.Test;
|
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.assertEquals;
|
||||||
import static junit.framework.TestCase.assertFalse;
|
import static junit.framework.TestCase.assertFalse;
|
||||||
|
|
||||||
|
|
@ -125,4 +129,29 @@ public class BinaryStructInputStreamTest {
|
||||||
BinaryStructInputStream.read(struct, new byte[]{0b0000_0001,0b0001_1000,0b0000_0000});
|
BinaryStructInputStream.read(struct, new byte[]{0b0000_0001,0b0001_1000,0b0000_0000});
|
||||||
struct.assertObj();
|
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<String>{
|
||||||
|
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 {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ package zutil.parser.binary;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -77,20 +77,25 @@ public class BinaryStructOutputStreamTest {
|
||||||
byte[] data = BinaryStructOutputStream.serialize(struct);
|
byte[] data = BinaryStructOutputStream.serialize(struct);
|
||||||
assertArrayEquals(new byte[]{(byte)0b0100_0000}, data);
|
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());
|
byte[] data = BinaryStructOutputStream.serialize(struct);
|
||||||
struct.assertObj();
|
assertArrayEquals(new byte[]{0b0000_0001,0b0000_0010,0b0000_0011,0b0000_0100}, data);
|
||||||
|
}
|
||||||
|
public static class ByteStringSerializer implements BinaryFieldSerializer<String>{
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue