import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class Data {
@StructField(n=0,type=FieldType.INT4)
private int iv;
@StructField(n=1,type=FieldType.FP8)
private double xv;
@StructField(n=2,type=FieldType.FIXSTR,length=8,encoding="ISO-8859-1")
private String sv;
public int getIv() {
return iv;
}
public void setIv(int iv) {
this.iv = iv;
}
public double getXv() {
return xv;
}
public void setXv(double xv) {
this.xv = xv;
}
public String getSv() {
return sv;
}
public void setSv(String sv) {
this.sv = sv;
}
}
The class got a @Struct annotation. Each field in the class got a @StructField annotation with an element n that determines the order of the fields and an element type that describes the datatype in the native struct plus some optional elements that are needed for some field types.
// read StructReader sr = new StructReader(somebytearray); Data obj = sr.read(Data.class); // write Data obj = new Data(); ... StructWriter sw = new StructWriter(); sw.write(obj); byte[] ba = sw.GetBytes();
To specify a field as an array put an @Array annotation on the field and make the Java type an array.
To specify a field as a sub struct just specify type=FieldType.STRUCT in the @StructField annotation.
The Record library supports polymorphism in records.
You must use the @Selector annotation on the last field in the super class.
import dk.vajhoej.record.Alignment;
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
import dk.vajhoej.record.Selector;
import dk.vajhoej.record.SubType;
@Struct
public class Data {
@StructField(n=0,type=FieldType.INT4)
protected int id;
@StructField(n=1,type=FieldType.INT4)
@Selector(subtypes={@SubType(value=1,type=DataX.class),
@SubType(value=3,type=DataY.class)})
protected int typ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTyp() {
return typ;
}
public void setTyp(int typ) {
this.typ = typ;
}
}
Usage is as simple as:
Data obj = sr.read(Data.class);
This will actually read DataX or DataY instances depending on the value of the typ field.
Note that the numbering of the struct fields continue in the sub class - it does not reset to zero.
The API described above read/write by runtime analyzing the class and interpreting the output from the analysis.
The fast API analyze the class once and generate Java code dynamically to read/write using the Javassist library.
The annotation son the POJO classes are the same.
Note that not all features are supported in fast API - anything dynamic with length providers etc. does not work.
// read FastStructReader<Data> fsr = CodeGen.genReader(Data.class); fsr.init(somebytearray); Data obj = fsr.read(Data.class); // write Data obj = new Data(); ... FastStructWriter fsw = CodGen.genWriter(Data.class); fsw.write(obj); byte[] ba = sw.GetBytes();
// read Map<Class<? extends Data>, FastStructReader<? extends Data>> map = new HashMap<Class<? extends Data>, FastStructReader<? extends Data>>(); map.put(DataX.class, CodeGen.genReader(DataX.class)); map.put(DataY.class, CodeGen.genReader(DataY.class)); FastStructReader<Data> fsr = new CompositFastStructReader<Data>(Data.class, map); fsr.init(somebytearray); Data obj = fsr.read(Data.class); // write Data obj = new Data(); ... Map<Class<? extends Data>, FastStructReader<? extends Data>> map = new HashMap<Class<? extends Data>, FastStructReader<? extends Data>>(); map.put(DataX.class, CodeGen.genReader(DataX.class)); map.put(DataY.class, CodeGen.genReader(DataY.class)); FastStructWriter<Object> fsw = new CompositFastStructWriter(map); fsw.write(obj); byte[] ba = sw.GetBytes();