diff --git a/pom.xml b/pom.xml
index a1c153c..e8803f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,12 +48,11 @@
test
- com.google.code.gson
- gson
- 2.8.6
+ org.slf4j
+ slf4j-simple
+ 1.7.30
test
-
org.slf4j
slf4j-api
diff --git a/src/test/java/io/github/yezhihao/protostar/Test.java b/src/test/java/io/github/yezhihao/protostar/Test.java
deleted file mode 100644
index 21c66e2..0000000
--- a/src/test/java/io/github/yezhihao/protostar/Test.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.yezhihao.protostar;
-
-public class Test {
-
- public static void main(String[] args) {
- System.out.println();
- }
-}
diff --git a/src/test/java/io/github/yezhihao/protostar/convert/Attr1.java b/src/test/java/io/github/yezhihao/protostar/convert/Attr1.java
new file mode 100644
index 0000000..c719a1a
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/convert/Attr1.java
@@ -0,0 +1,46 @@
+package io.github.yezhihao.protostar.convert;
+
+import io.github.yezhihao.protostar.DataType;
+import io.github.yezhihao.protostar.annotation.Field;
+
+public class Attr1 {
+
+ private String name;
+ private int id;
+
+ public Attr1() {
+ }
+
+ public Attr1(String name, int id) {
+ this.name = name;
+ this.id = id;
+ }
+
+ @Field(index = 0, type = DataType.STRING, lengthSize = 1, desc = "名称")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Field(index = 1, type = DataType.WORD, desc = "ID")
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Attr1{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", id=").append(id);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/src/test/java/io/github/yezhihao/protostar/convert/Attr2.java b/src/test/java/io/github/yezhihao/protostar/convert/Attr2.java
new file mode 100644
index 0000000..88cb819
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/convert/Attr2.java
@@ -0,0 +1,66 @@
+package io.github.yezhihao.protostar.convert;
+
+import io.netty.buffer.ByteBuf;
+
+import java.nio.charset.StandardCharsets;
+
+public class Attr2 {
+
+ private int type;
+ private String content;
+
+ public Attr2() {
+ }
+
+ public Attr2(int type, String content) {
+ this.type = type;
+ this.content = content;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Attr2{");
+ sb.append("type=").append(type);
+ sb.append(", content='").append(content).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public static class Schema implements io.github.yezhihao.protostar.Schema {
+
+ public static final Schema INSTANCE = new Schema();
+
+ private Schema() {
+ }
+
+ @Override
+ public Attr2 readFrom(ByteBuf input) {
+ Attr2 message = new Attr2();
+ message.type = input.readInt();
+ message.content = input.readCharSequence(input.readableBytes(), StandardCharsets.UTF_8).toString();
+ return message;
+ }
+
+ @Override
+ public void writeTo(ByteBuf output, Attr2 message) {
+ output.writeInt(message.type);
+ output.writeCharSequence(message.content, StandardCharsets.UTF_8);
+ }
+ }
+}
diff --git a/src/test/java/io/github/yezhihao/protostar/convert/AttributeConverter.java b/src/test/java/io/github/yezhihao/protostar/convert/AttributeConverter.java
new file mode 100644
index 0000000..5b0ee47
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/convert/AttributeConverter.java
@@ -0,0 +1,54 @@
+package io.github.yezhihao.protostar.convert;
+
+import io.github.yezhihao.protostar.IdStrategy;
+import io.github.yezhihao.protostar.Schema;
+import io.github.yezhihao.protostar.converter.MapConverter;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AttributeConverter extends MapConverter {
+
+ private static final Logger log = LoggerFactory.getLogger(AttributeConverter.class);
+
+ private static final IdStrategy INSTANCE = AttributeType.INSTANCE;
+
+ @Override
+ public Object convert(Integer key, ByteBuf input) {
+ if (!input.isReadable())
+ return null;
+ Schema schema = INSTANCE.getSchema(key);
+ if (schema != null)
+ return INSTANCE.readFrom(key, input);
+ byte[] bytes = new byte[input.readableBytes()];
+ input.readBytes(bytes);
+ log.warn("未识别的附加信息:ID[{}], HEX[{}]", key, ByteBufUtil.hexDump(bytes));
+ return bytes;
+ }
+
+ @Override
+ public void convert(Integer key, ByteBuf output, Object value) {
+ Schema schema = INSTANCE.getSchema(key);
+ if (schema != null) {
+ schema.writeTo(output, value);
+ } else {
+ log.warn("未注册的附加信息:ID[{}], Value[{}]", key, value);
+ }
+ }
+
+ @Override
+ protected Integer readKey(ByteBuf input) {
+ return (int) input.readUnsignedByte();
+ }
+
+ @Override
+ protected void writeKey(ByteBuf output, Integer key) {
+ output.writeByte(key);
+ }
+
+ @Override
+ protected int valueSize() {
+ return 1;
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/io/github/yezhihao/protostar/convert/AttributeType.java b/src/test/java/io/github/yezhihao/protostar/convert/AttributeType.java
new file mode 100644
index 0000000..fe4a664
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/convert/AttributeType.java
@@ -0,0 +1,21 @@
+package io.github.yezhihao.protostar.convert;
+
+import io.github.yezhihao.protostar.IdStrategy;
+import io.github.yezhihao.protostar.PrepareLoadStrategy;
+import io.github.yezhihao.protostar.schema.IntSchema;
+import io.github.yezhihao.protostar.schema.StringSchema;
+
+public class AttributeType extends PrepareLoadStrategy {
+
+ public static final IdStrategy INSTANCE = new AttributeType();
+
+ @Override
+ protected void addSchemas(PrepareLoadStrategy schemaRegistry) {
+ schemaRegistry
+ .addSchema(1, IntSchema.Int32.INSTANCE)
+ .addSchema(2, StringSchema.Chars.getInstance((byte) 0, "GBK"))
+
+ .addSchema(3, Attr1.class)
+ .addSchema(4, Attr2.Schema.INSTANCE);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/io/github/yezhihao/protostar/convert/Test.java b/src/test/java/io/github/yezhihao/protostar/convert/Test.java
new file mode 100644
index 0000000..d68e1ad
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/convert/Test.java
@@ -0,0 +1,114 @@
+package io.github.yezhihao.protostar.convert;
+
+import io.github.yezhihao.protostar.DataType;
+import io.github.yezhihao.protostar.ProtostarUtil;
+import io.github.yezhihao.protostar.Schema;
+import io.github.yezhihao.protostar.annotation.Convert;
+import io.github.yezhihao.protostar.annotation.Field;
+import io.github.yezhihao.protostar.annotation.Fs;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class Test {
+
+ public static void main(String[] args) {
+ Map> multiVersionSchema = ProtostarUtil.getSchema(Foo.class);
+ Schema schema_v0 = multiVersionSchema.get(0);
+ Schema schema_v1 = multiVersionSchema.get(1);
+
+ ByteBuf buffer = Unpooled.buffer(32);
+ schema_v0.writeTo(buffer, foo());
+ String hex = ByteBufUtil.hexDump(buffer);
+ System.out.println(hex);
+
+ Foo foo = schema_v0.readFrom(buffer);
+ System.out.println(foo);
+ System.out.println("=========================version: 0");
+
+ buffer = Unpooled.buffer(32);
+ schema_v1.writeTo(buffer, foo());
+ hex = ByteBufUtil.hexDump(buffer);
+ System.out.println(hex);
+
+ foo = schema_v1.readFrom(buffer);
+ System.out.println(foo);
+ System.out.println("=========================version: 1");
+ }
+
+ public static Foo foo() {
+ Foo foo = new Foo();
+ foo.setName("张三");
+ foo.setId(128);
+ foo.setDateTime(LocalDateTime.of(2020, 7, 7, 19, 23, 59));
+ Map attrs = new TreeMap<>();
+ attrs.put(1, 123);
+ attrs.put(2, "李四");
+ attrs.put(3, new Attr1("test", 1));
+ attrs.put(4, new Attr2(2, "test2"));
+ foo.setAttributes(attrs);
+ return foo;
+ }
+
+ public static class Foo {
+
+ private String name;
+ private int id;
+ private LocalDateTime dateTime;
+ private Map attributes;
+
+ @Fs({@Field(index = 0, type = DataType.STRING, lengthSize = 1, desc = "名称", version = 0),
+ @Field(index = 0, type = DataType.STRING, length = 10, desc = "名称", version = 1)})
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Fs({@Field(index = 1, type = DataType.WORD, desc = "ID", version = 0),
+ @Field(index = 1, type = DataType.DWORD, desc = "ID", version = 1)})
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Field(index = 3, type = DataType.BCD8421, desc = "日期", version = {0, 1})
+ public LocalDateTime getDateTime() {
+ return dateTime;
+ }
+
+ public void setDateTime(LocalDateTime dateTime) {
+ this.dateTime = dateTime;
+ }
+
+ @Convert(converter = AttributeConverter.class)
+ @Field(index = 4, type = DataType.MAP, desc = "属性", version = {0, 1})
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map attributes) {
+ this.attributes = attributes;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Foo{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", id=").append(id);
+ sb.append(", dateTime=").append(dateTime);
+ sb.append(", attributes=").append(attributes);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
diff --git a/src/test/java/io/github/yezhihao/protostar/multiversion/Test.java b/src/test/java/io/github/yezhihao/protostar/multiversion/Test.java
new file mode 100644
index 0000000..a59b9be
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/multiversion/Test.java
@@ -0,0 +1,94 @@
+package io.github.yezhihao.protostar.multiversion;
+
+import io.github.yezhihao.protostar.DataType;
+import io.github.yezhihao.protostar.ProtostarUtil;
+import io.github.yezhihao.protostar.Schema;
+import io.github.yezhihao.protostar.annotation.Field;
+import io.github.yezhihao.protostar.annotation.Fs;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+public class Test {
+
+ public static void main(String[] args) {
+ Map> multiVersionSchema = ProtostarUtil.getSchema(Foo.class);
+ Schema schema_v0 = multiVersionSchema.get(0);
+ Schema schema_v1 = multiVersionSchema.get(1);
+
+ ByteBuf buffer = Unpooled.buffer(32);
+ schema_v0.writeTo(buffer, foo());
+ String hex = ByteBufUtil.hexDump(buffer);
+ System.out.println(hex);
+
+ Foo foo = schema_v0.readFrom(buffer);
+ System.out.println(foo);
+ System.out.println("=========================version: 0");
+
+ buffer = Unpooled.buffer(32);
+ schema_v1.writeTo(buffer, foo());
+ hex = ByteBufUtil.hexDump(buffer);
+ System.out.println(hex);
+
+ foo = schema_v1.readFrom(buffer);
+ System.out.println(foo);
+ System.out.println("=========================version: 1");
+ }
+
+ public static Foo foo() {
+ Foo foo = new Foo();
+ foo.setName("张三");
+ foo.setId(128);
+ foo.setDateTime(LocalDateTime.of(2020, 7, 7, 19, 23, 59));
+ return foo;
+ }
+
+ public static class Foo {
+
+ private String name;
+ private int id;
+ private LocalDateTime dateTime;
+
+ @Fs({@Field(index = 0, type = DataType.STRING, lengthSize = 1, desc = "名称", version = 0),
+ @Field(index = 0, type = DataType.STRING, length = 10, desc = "名称", version = 1)})
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Fs({@Field(index = 1, type = DataType.WORD, desc = "ID", version = 0),
+ @Field(index = 1, type = DataType.DWORD, desc = "ID", version = 1)})
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Field(index = 3, type = DataType.BCD8421, desc = "日期", version = {0, 1})
+ public LocalDateTime getDateTime() {
+ return dateTime;
+ }
+
+ public void setDateTime(LocalDateTime dateTime) {
+ this.dateTime = dateTime;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Foo{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", id=").append(id);
+ sb.append(", dateTime=").append(dateTime);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}
diff --git a/src/test/java/io/github/yezhihao/protostar/simple/Test.java b/src/test/java/io/github/yezhihao/protostar/simple/Test.java
new file mode 100644
index 0000000..49671f4
--- /dev/null
+++ b/src/test/java/io/github/yezhihao/protostar/simple/Test.java
@@ -0,0 +1,83 @@
+package io.github.yezhihao.protostar.simple;
+
+import io.github.yezhihao.protostar.DataType;
+import io.github.yezhihao.protostar.FieldFactory;
+import io.github.yezhihao.protostar.ProtostarUtil;
+import io.github.yezhihao.protostar.Schema;
+import io.github.yezhihao.protostar.annotation.Field;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+public class Test {
+
+ public static void main(String[] args) {
+ FieldFactory.EXPLAIN = true;
+
+ Map> multiVersionSchema = ProtostarUtil.getSchema(Foo.class);
+ Schema schema = multiVersionSchema.get(0);
+
+ ByteBuf buffer = Unpooled.buffer(32);
+ schema.writeTo(buffer, foo());
+ String hex = ByteBufUtil.hexDump(buffer);
+ System.out.println(hex);
+
+ Foo foo = schema.readFrom(buffer);
+ System.out.println(foo);
+ }
+
+ public static Foo foo() {
+ Foo foo = new Foo();
+ foo.setName("张三");
+ foo.setId(128);
+ foo.setDateTime(LocalDateTime.of(2020, 7, 7, 19, 23, 59));
+ return foo;
+ }
+
+ public static class Foo {
+
+ private String name;
+ private int id;
+ private LocalDateTime dateTime;
+
+ @Field(index = 0, type = DataType.STRING, lengthSize = 1, desc = "名称")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Field(index = 1, type = DataType.WORD, desc = "ID")
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Field(index = 3, type = DataType.BCD8421, desc = "日期")
+ public LocalDateTime getDateTime() {
+ return dateTime;
+ }
+
+ public void setDateTime(LocalDateTime dateTime) {
+ this.dateTime = dateTime;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Foo{");
+ sb.append("name='").append(name).append('\'');
+ sb.append(", id=").append(id);
+ sb.append(", dateTime=").append(dateTime);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+}