diff --git a/pom.xml b/pom.xml
index 8cba8cd..330f944 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.github.yezhihao
protostar
- 2.0.4.RELEASE
+ 2.0.5.RELEASE
jar
Protostar
diff --git a/src/main/java/io/github/yezhihao/protostar/FieldFactory.java b/src/main/java/io/github/yezhihao/protostar/FieldFactory.java
index c9a8511..2e9647d 100644
--- a/src/main/java/io/github/yezhihao/protostar/FieldFactory.java
+++ b/src/main/java/io/github/yezhihao/protostar/FieldFactory.java
@@ -1,10 +1,7 @@
package io.github.yezhihao.protostar;
import io.github.yezhihao.protostar.annotation.Field;
-import io.github.yezhihao.protostar.field.BasicField;
-import io.github.yezhihao.protostar.field.DynamicLengthField;
-import io.github.yezhihao.protostar.field.FixedField;
-import io.github.yezhihao.protostar.field.FixedLengthField;
+import io.github.yezhihao.protostar.field.*;
import io.github.yezhihao.protostar.schema.*;
import java.nio.ByteBuffer;
@@ -65,7 +62,7 @@ public abstract class FieldFactory {
fieldSchema = ConvertSchema.getInstance(field.converter());
break;
case LIST:
- fieldSchema = CollectionSchema.getInstance(schema, field.lengthSize());
+ fieldSchema = CollectionSchema.getInstance(schema);
break;
case MAP:
fieldSchema = ConvertSchema.getInstance(field.converter());
@@ -78,15 +75,21 @@ public abstract class FieldFactory {
BasicField result;
if (EXPLAIN) {
if (field.lengthSize() > 0) {
- result = new DynamicLengthField.Logger(field, f, fieldSchema);
+ if (fieldSchema instanceof CollectionSchema)
+ result = new DynamicTotalField.Logger(field, f, fieldSchema);
+ else
+ result = new DynamicLengthField.Logger(field, f, fieldSchema);
} else if (field.length() > 0) {
result = new FixedLengthField.Logger(field, f, fieldSchema);
} else {
result = new FixedField.Logger(field, f, fieldSchema);
}
} else {
- if (field.lengthSize() > 0 && !(fieldSchema instanceof CollectionSchema)) {
- result = new DynamicLengthField(field, f, fieldSchema);
+ if (field.lengthSize() > 0) {
+ if (fieldSchema instanceof CollectionSchema)
+ result = new DynamicTotalField(field, f, fieldSchema);
+ else
+ result = new DynamicLengthField(field, f, fieldSchema);
} else if (field.length() > 0) {
result = new FixedLengthField(field, f, fieldSchema);
} else {
diff --git a/src/main/java/io/github/yezhihao/protostar/converter/MapConverter.java b/src/main/java/io/github/yezhihao/protostar/converter/MapConverter.java
index 73816a9..59bb9e4 100644
--- a/src/main/java/io/github/yezhihao/protostar/converter/MapConverter.java
+++ b/src/main/java/io/github/yezhihao/protostar/converter/MapConverter.java
@@ -70,10 +70,10 @@ public abstract class MapConverter extends PrepareLoadStrategy implements
if (schema != null) {
int lengthSize = valueSize();
int begin = output.writerIndex();
- output.writeBytes(ByteBufUtils.BLOCKS[lengthSize]);
+ ByteBufUtils.writeInt(output, lengthSize, 0);
schema.writeTo(output, value);
int length = output.writerIndex() - begin - lengthSize;
- ByteBufUtils.setInt(output, lengthSize, begin, length);
+ ByteBufUtils.setInt(output, begin, lengthSize, length);
} else {
log.warn("未注册的信息:ID[{}], VALUE[{}]", key, value);
}
diff --git a/src/main/java/io/github/yezhihao/protostar/field/BasicField.java b/src/main/java/io/github/yezhihao/protostar/field/BasicField.java
index 2de58e5..deb2886 100644
--- a/src/main/java/io/github/yezhihao/protostar/field/BasicField.java
+++ b/src/main/java/io/github/yezhihao/protostar/field/BasicField.java
@@ -30,9 +30,9 @@ public abstract class BasicField implements Comparable> {
}
}
- public abstract boolean readFrom(ByteBuf input, Object message) throws Exception;
+ public abstract boolean readFrom(ByteBuf input, T message) throws Exception;
- public abstract void writeTo(ByteBuf output, Object message) throws Exception;
+ public abstract void writeTo(ByteBuf output, T message) throws Exception;
public void println(int index, String desc, String hex, Object value) {
if (value != null)
diff --git a/src/main/java/io/github/yezhihao/protostar/field/DynamicLengthField.java b/src/main/java/io/github/yezhihao/protostar/field/DynamicLengthField.java
index 998b629..afc7473 100644
--- a/src/main/java/io/github/yezhihao/protostar/field/DynamicLengthField.java
+++ b/src/main/java/io/github/yezhihao/protostar/field/DynamicLengthField.java
@@ -13,11 +13,11 @@ import io.netty.buffer.ByteBufUtil;
*/
public class DynamicLengthField extends BasicField {
- protected final Schema schema;
+ protected final Schema schema;
protected final int lengthSize;
- public DynamicLengthField(Field field, java.lang.reflect.Field f, Schema schema) {
+ public DynamicLengthField(Field field, java.lang.reflect.Field f, Schema schema) {
super(field, f);
this.schema = schema;
this.lengthSize = field.lengthSize();
@@ -36,10 +36,10 @@ public class DynamicLengthField extends BasicField {
Object value = f.get(message);
if (value != null) {
int begin = output.writerIndex();
- output.writeBytes(ByteBufUtils.BLOCKS[lengthSize]);
- schema.writeTo(output, (T) value);
+ ByteBufUtils.writeInt(output, lengthSize, 0);
+ schema.writeTo(output, value);
int length = output.writerIndex() - begin - lengthSize;
- ByteBufUtils.setInt(output, lengthSize, begin, length);
+ ByteBufUtils.setInt(output, begin, lengthSize, length);
}
}
@@ -78,10 +78,10 @@ public class DynamicLengthField extends BasicField {
Object value = f.get(message);
if (value != null) {
int begin = output.writerIndex();
- output.writeBytes(ByteBufUtils.BLOCKS[lengthSize]);
- schema.writeTo(output, (T) value);
+ ByteBufUtils.writeInt(output, lengthSize, 0);
+ schema.writeTo(output, value);
int length = output.writerIndex() - begin - lengthSize;
- ByteBufUtils.setInt(output, lengthSize, begin, length);
+ ByteBufUtils.setInt(output, begin, lengthSize, length);
}
int after = output.writerIndex();
diff --git a/src/main/java/io/github/yezhihao/protostar/field/DynamicTotalField.java b/src/main/java/io/github/yezhihao/protostar/field/DynamicTotalField.java
new file mode 100644
index 0000000..2ebbdf2
--- /dev/null
+++ b/src/main/java/io/github/yezhihao/protostar/field/DynamicTotalField.java
@@ -0,0 +1,76 @@
+package io.github.yezhihao.protostar.field;
+
+import io.github.yezhihao.protostar.Schema;
+import io.github.yezhihao.protostar.annotation.Field;
+import io.github.yezhihao.protostar.util.ByteBufUtils;
+import io.github.yezhihao.protostar.util.StrUtils;
+import io.netty.buffer.ByteBuf;
+
+import java.util.Collection;
+
+/**
+ * 动态长度的字段
+ * @author yezhihao
+ * home https://gitee.com/yezhihao/jt808-server
+ */
+public class DynamicTotalField extends BasicField {
+
+ protected final Schema> schema;
+
+ protected final int totalSize;
+
+ public DynamicTotalField(Field field, java.lang.reflect.Field f, Schema schema) {
+ super(field, f);
+ this.schema = schema;
+ this.totalSize = field.lengthSize();
+ }
+
+ public boolean readFrom(ByteBuf input, Object message) throws Exception {
+ Object value = schema.readFrom(input, totalSize);
+ f.set(message, value);
+ return true;
+ }
+
+ public void writeTo(ByteBuf output, Object message) throws Exception {
+ Collection value = (Collection) f.get(message);
+ if (value != null)
+ schema.writeTo(output, totalSize, value);
+ }
+
+ @Override
+ public int compareTo(BasicField that) {
+ int r = Integer.compare(this.index, that.index);
+ if (r == 0)
+ r = (that instanceof DynamicTotalField) ? 1 : -1;
+ return r;
+ }
+
+ public static class Logger extends DynamicTotalField {
+
+ public Logger(Field field, java.lang.reflect.Field f, Schema schema) {
+ super(field, f, schema);
+ }
+
+ public boolean readFrom(ByteBuf input, Object message) throws Exception {
+ int total = ByteBufUtils.getInt(input, input.readerIndex(), totalSize);
+ String hex = StrUtils.leftPad(Integer.toHexString(total), totalSize << 1, '0');
+ println(this.index, this.field.desc() + "总数", hex, total);
+
+ Collection value = schema.readFrom(input, totalSize);
+ f.set(message, value);
+ return true;
+ }
+
+ public void writeTo(ByteBuf output, Object message) throws Exception {
+ Collection value = (Collection) f.get(message);
+ if (value != null) {
+
+ int total = value.size();
+ String hex = StrUtils.leftPad(Integer.toHexString(total), totalSize << 1, '0');
+ println(this.index, this.field.desc() + "总数", hex, total);
+
+ schema.writeTo(output, totalSize, value);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/github/yezhihao/protostar/field/FixedField.java b/src/main/java/io/github/yezhihao/protostar/field/FixedField.java
index cc21653..2010266 100644
--- a/src/main/java/io/github/yezhihao/protostar/field/FixedField.java
+++ b/src/main/java/io/github/yezhihao/protostar/field/FixedField.java
@@ -12,9 +12,9 @@ import io.netty.buffer.ByteBufUtil;
*/
public class FixedField extends BasicField {
- protected final Schema schema;
+ protected final Schema schema;
- public FixedField(Field field, java.lang.reflect.Field f, Schema schema) {
+ public FixedField(Field field, java.lang.reflect.Field f, Schema schema) {
super(field, f);
this.schema = schema;
}
@@ -28,7 +28,7 @@ public class FixedField extends BasicField {
public void writeTo(ByteBuf output, Object message) throws Exception {
Object value = f.get(message);
if (value != null)
- schema.writeTo(output, (T) value);
+ schema.writeTo(output, value);
}
public static class Logger extends FixedField {
@@ -54,7 +54,7 @@ public class FixedField extends BasicField {
Object value = f.get(message);
if (value != null)
- schema.writeTo(output, (T) value);
+ schema.writeTo(output, value);
int after = output.writerIndex();
String hex = ByteBufUtil.hexDump(output.slice(before, after - before));
diff --git a/src/main/java/io/github/yezhihao/protostar/field/FixedLengthField.java b/src/main/java/io/github/yezhihao/protostar/field/FixedLengthField.java
index 17fe6d5..e9ac309 100644
--- a/src/main/java/io/github/yezhihao/protostar/field/FixedLengthField.java
+++ b/src/main/java/io/github/yezhihao/protostar/field/FixedLengthField.java
@@ -12,7 +12,7 @@ import io.netty.buffer.ByteBufUtil;
*/
public class FixedLengthField extends BasicField {
- protected final Schema schema;
+ protected final Schema schema;
public FixedLengthField(Field field, java.lang.reflect.Field f, Schema schema) {
super(field, f);
@@ -28,7 +28,7 @@ public class FixedLengthField extends BasicField {
public void writeTo(ByteBuf output, Object message) throws Exception {
Object value = f.get(message);
if (value != null)
- schema.writeTo(output, length, (T) value);
+ schema.writeTo(output, length, value);
}
public static class Logger extends FixedLengthField {
@@ -54,7 +54,7 @@ public class FixedLengthField extends BasicField {
Object value = f.get(message);
if (value != null)
- schema.writeTo(output, length, (T) value);
+ schema.writeTo(output, length, value);
int after = output.writerIndex();
String hex = ByteBufUtil.hexDump(output.slice(before, after - before));
diff --git a/src/main/java/io/github/yezhihao/protostar/schema/CollectionSchema.java b/src/main/java/io/github/yezhihao/protostar/schema/CollectionSchema.java
index 69cc063..71771c2 100644
--- a/src/main/java/io/github/yezhihao/protostar/schema/CollectionSchema.java
+++ b/src/main/java/io/github/yezhihao/protostar/schema/CollectionSchema.java
@@ -6,77 +6,64 @@ import io.github.yezhihao.protostar.util.Cache;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
-import java.util.List;
+import java.util.Collection;
-public class CollectionSchema implements Schema> {
+public class CollectionSchema implements Schema> {
- private static final Cache CACHE = new Cache<>();
+ private static final Cache CACHE = new Cache<>();
- public static CollectionSchema getInstance(Schema schema, int lengthSize) {
- return CACHE.get(schema.hashCode() + "_" + lengthSize, key -> new CollectionSchema(schema, lengthSize));
+ public static CollectionSchema getInstance(Schema schema) {
+ return CACHE.get(schema, key -> new CollectionSchema(key));
}
private final Schema schema;
- private final int lengthSize;
-
- private CollectionSchema(Schema schema, int lengthSize) {
+ private CollectionSchema(Schema schema) {
this.schema = schema;
- this.lengthSize = lengthSize;
}
@Override
- public List readFrom(ByteBuf input) {
+ public Collection readFrom(ByteBuf input) {
if (!input.isReadable())
return null;
- List list;
- if (lengthSize > 0) {
- int length = ByteBufUtils.readInt(input, lengthSize);
- list = new ArrayList<>(length);
- for (int i = 0; i < length; i++) {
- T obj = schema.readFrom(input);
- if (obj == null) break;
- list.add(obj);
- }
- } else {
- list = new ArrayList<>(2);
- do {
- T obj = schema.readFrom(input);
- if (obj == null) break;
- list.add(obj);
- } while (input.isReadable());
+ Collection list = new ArrayList<>(2);
+ do {
+ T obj = schema.readFrom(input);
+ if (obj == null) break;
+ list.add(obj);
+ } while (input.isReadable());
+ return list;
+ }
+
+ @Override
+ public Collection readFrom(ByteBuf input, int totalSize) {
+ int total = ByteBufUtils.readInt(input, totalSize);
+ Collection list = new ArrayList<>(total);
+ for (int i = 0; i < total; i++) {
+ T obj = schema.readFrom(input);
+ list.add(obj);
}
return list;
}
-
@Override
- public List readFrom(ByteBuf input, int length) {
- int writerIndex = input.writerIndex();
- input.writerIndex(input.readerIndex() + length);
- List result = this.readFrom(input);
- input.writerIndex(writerIndex);
- return result;
- }
-
- @Override
- public void writeTo(ByteBuf output, List list) {
+ public void writeTo(ByteBuf output, Collection list) {
if (list == null || list.isEmpty())
return;
- if (lengthSize > 0)
- ByteBufUtils.writeInt(output, lengthSize, list.size());
+
for (T obj : list) {
schema.writeTo(output, obj);
}
}
@Override
- public void writeTo(ByteBuf output, int length, List list) {
+ public void writeTo(ByteBuf output, int totalSize, Collection list) {
if (list == null || list.isEmpty())
return;
+ ByteBufUtils.writeInt(output, totalSize, list.size());
for (T obj : list) {
- schema.writeTo(output, length, obj);
+ schema.writeTo(output, totalSize, obj);
}
}
}
\ No newline at end of file
diff --git a/src/main/java/io/github/yezhihao/protostar/util/ByteBufUtils.java b/src/main/java/io/github/yezhihao/protostar/util/ByteBufUtils.java
index 4080eae..92f9185 100644
--- a/src/main/java/io/github/yezhihao/protostar/util/ByteBufUtils.java
+++ b/src/main/java/io/github/yezhihao/protostar/util/ByteBufUtils.java
@@ -9,13 +9,6 @@ import io.netty.buffer.ByteBuf;
*/
public class ByteBufUtils {
- /** 长度域占位数据块 */
- public static final byte[][] BLOCKS = new byte[][]{
- new byte[0],
- new byte[1], new byte[2],
- new byte[3], new byte[4]};
-
-
public static int readInt(ByteBuf input, int length) {
int value;
switch (length) {
@@ -56,20 +49,20 @@ public class ByteBufUtils {
}
}
- public static int getInt(ByteBuf output, int length, int index) {
+ public static int getInt(ByteBuf input, int index, int length) {
int value;
switch (length) {
case 1:
- value = output.getUnsignedByte(index);
+ value = input.getUnsignedByte(index);
break;
case 2:
- value = output.getUnsignedShort(index);
+ value = input.getUnsignedShort(index);
break;
case 3:
- value = output.getUnsignedMedium(index);
+ value = input.getUnsignedMedium(index);
break;
case 4:
- value = output.getInt(index);
+ value = input.getInt(index);
break;
default:
throw new RuntimeException("unsupported length: " + length + " (expected: 1, 2, 3, 4)");
@@ -77,7 +70,7 @@ public class ByteBufUtils {
return value;
}
- public static void setInt(ByteBuf output, int length, int index, int value) {
+ public static void setInt(ByteBuf output, int index, int length, int value) {
switch (length) {
case 1:
output.setByte(index, value);
diff --git a/src/main/java/io/github/yezhihao/protostar/util/StrUtils.java b/src/main/java/io/github/yezhihao/protostar/util/StrUtils.java
index c8408e5..119ce26 100644
--- a/src/main/java/io/github/yezhihao/protostar/util/StrUtils.java
+++ b/src/main/java/io/github/yezhihao/protostar/util/StrUtils.java
@@ -90,4 +90,17 @@ public class StrUtils {
return false;
return componentType.isArray();
}
+
+ public static String leftPad(String str, int size, char ch) {
+ int length = str.length();
+ int pads = size - length;
+ if (pads > 0) {
+ char[] result = new char[size];
+ str.getChars(0, length, result, pads);
+ while (pads > 0)
+ result[--pads] = ch;
+ return new String(result);
+ }
+ return str;
+ }
}
\ No newline at end of file