From e8a53d6b24902858aebfdfe5f74699e1cea235bc Mon Sep 17 00:00:00 2001 From: redkale Date: Tue, 1 Oct 2024 08:56:17 +0800 Subject: [PATCH] pb --- .../java/org/redkale/convert/DeMember.java | 7 + .../java/org/redkale/convert/EnMember.java | 7 + .../org/redkale/convert/ObjectDecoder.java | 4 + .../org/redkale/convert/ObjectEncoder.java | 28 ++- .../convert/pb/ProtobufArrayEncoder.java | 19 +- .../redkale/convert/pb/ProtobufCoders.java | 169 +++++++++--------- .../convert/pb/ProtobufCollectionEncoder.java | 21 ++- .../convert/pb/ProtobufDynEncoder.java | 86 +++++---- .../convert/pb/ProtobufEncodeable.java | 9 +- .../convert/pb/ProtobufEnumSimpledCoder.java | 2 +- .../redkale/convert/pb/ProtobufFactory.java | 6 +- .../convert/pb/ProtobufMapEncoder.java | 6 +- .../convert/pb/ProtobufObjectDecoder.java | 1 + .../convert/pb/ProtobufObjectEncoder.java | 98 +++++++--- .../redkale/convert/pb/ProtobufReader.java | 12 +- .../convert/pb/ProtobufStreamEncoder.java | 7 +- .../redkale/convert/pb/ProtobufWriter.java | 49 +++-- .../test/convert/GenericEntityTest.java | 1 + .../test/convert/pb/RequiredBeanTest.java | 118 ++++++++++++ .../convert/pb/UserBeanProtoDynEncoder.java | 8 +- 20 files changed, 466 insertions(+), 192 deletions(-) create mode 100644 src/test/java/org/redkale/test/convert/pb/RequiredBeanTest.java diff --git a/src/main/java/org/redkale/convert/DeMember.java b/src/main/java/org/redkale/convert/DeMember.java index 62c2240e2..603b32162 100644 --- a/src/main/java/org/redkale/convert/DeMember.java +++ b/src/main/java/org/redkale/convert/DeMember.java @@ -39,6 +39,9 @@ public final class DeMember { // 主要给protobuf使用 从1开始 protected int tag; + // 主要给protobuf使用 tag的大小 + int tagSize; + protected final Attribute attribute; protected Decodeable decoder; @@ -143,6 +146,10 @@ public final class DeMember { return this.tag; } + public int getTagSize() { + return this.tagSize; + } + public int compareTo(boolean fieldSort, DeMember o) { if (o == null) { return -1; diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java index fcf9c7a0d..a0c50e269 100644 --- a/src/main/java/org/redkale/convert/EnMember.java +++ b/src/main/java/org/redkale/convert/EnMember.java @@ -59,6 +59,9 @@ public final class EnMember { // 主要给protobuf使用 从1开始 int tag; + // 主要给protobuf使用 tag的大小 + int tagSize; + public EnMember(Attribute attribute, int tag, Encodeable encoder) { this.attribute = attribute; this.encoder = encoder; @@ -189,6 +192,10 @@ public final class EnMember { return this.tag; } + public int getTagSize() { + return this.tagSize; + } + public int compareTo(boolean fieldSort, EnMember o) { if (o == null) { return -1; diff --git a/src/main/java/org/redkale/convert/ObjectDecoder.java b/src/main/java/org/redkale/convert/ObjectDecoder.java index e24c27c61..8577c4895 100644 --- a/src/main/java/org/redkale/convert/ObjectDecoder.java +++ b/src/main/java/org/redkale/convert/ObjectDecoder.java @@ -443,6 +443,10 @@ public class ObjectDecoder implements Decodeable { member.tag = tag; } + protected void setTagSize(DeMember member, int tagSize) { + member.tagSize = tagSize; + } + protected void setIndex(DeMember member, int index) { member.index = index; } diff --git a/src/main/java/org/redkale/convert/ObjectEncoder.java b/src/main/java/org/redkale/convert/ObjectEncoder.java index 532ec91f9..623fb1bf2 100644 --- a/src/main/java/org/redkale/convert/ObjectEncoder.java +++ b/src/main/java/org/redkale/convert/ObjectEncoder.java @@ -8,8 +8,8 @@ package org.redkale.convert; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.locks.*; -import org.redkale.annotation.ConstructorParameters; import org.redkale.annotation.*; +import org.redkale.annotation.ConstructorParameters; import org.redkale.convert.ext.StringSimpledCoder; import org.redkale.util.*; @@ -337,21 +337,20 @@ public class ObjectEncoder implements Encodeable { factory.loadEncoder(clz).convertTo(out, value); return; } - W objout = objectWriter(out, value); - objout.writeObjectB(value); + out.writeObjectB(value); int maxPosition = 0; for (EnMember member : members) { maxPosition = member.getPosition(); - objout.writeObjectField(member, value); + out.writeObjectField(member, value); } - if (objout.objExtFunc != null) { - ConvertField[] extFields = objout.objExtFunc.apply(value); + if (out.objExtFunc != null) { + ConvertField[] extFields = out.objExtFunc.apply(value); if (extFields != null) { Encodeable anyEncoder = factory.getAnyEncoder(); for (ConvertField en : extFields) { if (en != null) { maxPosition++; - objout.writeObjectField( + out.writeObjectField( en.getName(), en.getType(), Math.max(en.getPosition(), maxPosition), @@ -361,8 +360,7 @@ public class ObjectEncoder implements Encodeable { } } } - objout.writeObjectE(value); - offerWriter(out, objout); + out.writeObjectE(value); } // ---------------------------------- 可定制方法 ---------------------------------- @@ -374,19 +372,15 @@ public class ObjectEncoder implements Encodeable { // do nothing } - protected W objectWriter(W out, T value) { - return out; - } - - protected void offerWriter(W parent, W out) { - // do nothing - } - // --------------------------------------------------------------------------------- protected void setTag(EnMember member, int tag) { member.tag = tag; } + protected void setTagSize(EnMember member, int tagSize) { + member.tagSize = tagSize; + } + protected void setIndex(EnMember member, int index) { member.index = index; } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java index 686264c24..472d620c5 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java @@ -6,6 +6,7 @@ package org.redkale.convert.pb; import java.lang.reflect.Type; +import org.redkale.annotation.Nonnull; import org.redkale.convert.*; /** @@ -26,13 +27,17 @@ public class ProtobufArrayEncoder extends ArrayEncoder } @Override - public void convertTo(ProtobufWriter out, EnMember member, T[] value) { + public void convertTo(ProtobufWriter out, @Nonnull EnMember member, T[] value) { this.checkInited(); if (value == null || value.length < 1) { return; } Encodeable itemEncoder = this.componentEncoder; T[] array = value; + // if (componentSizeRequired) { + // int tagSize = ProtobufFactory.computeSInt32SizeNoTag(member.getTag()); + // out.writeLength(computeSize(tagSize, value)); + // } out.writeArrayB(array.length, itemEncoder, array); for (T item : array) { out.writeField(member); @@ -41,6 +46,7 @@ public class ProtobufArrayEncoder extends ArrayEncoder } else if (componentSimpled) { itemEncoder.convertTo(out, item); } else { + // itemEncoder.convertTo(out, item); ProtobufWriter tmp = out.pollChild(); itemEncoder.convertTo(tmp, item); out.writeTuple(tmp); @@ -51,16 +57,19 @@ public class ProtobufArrayEncoder extends ArrayEncoder } @Override - public int computeSize(T[] value) { + public int computeSize(ProtobufWriter out, int tagSize, T[] value) { if (value == null || value.length < 1) { return 0; } - int size = 0; + int dataSize = 0; ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder; for (T item : value) { - size += itemEncoder.computeSize(item); + dataSize += itemEncoder.computeSize(out, tagSize, item); } - return size; + if (componentSizeRequired) { + dataSize += tagSize * value.length; + } + return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize; } @Override diff --git a/src/main/java/org/redkale/convert/pb/ProtobufCoders.java b/src/main/java/org/redkale/convert/pb/ProtobufCoders.java index 7db7ca022..ceb08787e 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufCoders.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufCoders.java @@ -62,7 +62,7 @@ public abstract class ProtobufCoders { public static final ProtobufBoolSimpledCoder instance = new ProtobufBoolSimpledCoder(); @Override - public int computeSize(Boolean value) { + public int computeSize(ProtobufWriter out, int tagSize, Boolean value) { return value == null ? 0 : 1; } @@ -78,7 +78,7 @@ public abstract class ProtobufCoders { public static final ProtobufByteSimpledCoder instance = new ProtobufByteSimpledCoder(); @Override - public int computeSize(Byte value) { + public int computeSize(ProtobufWriter out, int tagSize, Byte value) { return value == null ? 0 : 1; } @@ -94,7 +94,7 @@ public abstract class ProtobufCoders { public static final ProtobufCharSimpledCoder instance = new ProtobufCharSimpledCoder(); @Override - public int computeSize(Character value) { + public int computeSize(ProtobufWriter out, int tagSize, Character value) { return value == null ? 0 : ProtobufFactory.computeSInt32SizeNoTag(value); } @@ -110,7 +110,7 @@ public abstract class ProtobufCoders { public static final ProtobufShortSimpledCoder instance = new ProtobufShortSimpledCoder(); @Override - public int computeSize(Short value) { + public int computeSize(ProtobufWriter out, int tagSize, Short value) { return value == null ? 0 : ProtobufFactory.computeSInt32SizeNoTag(value); } @@ -126,7 +126,7 @@ public abstract class ProtobufCoders { public static final ProtobufIntSimpledCoder instance = new ProtobufIntSimpledCoder(); @Override - public int computeSize(Integer value) { + public int computeSize(ProtobufWriter out, int tagSize, Integer value) { return value == null ? 0 : ProtobufFactory.computeSInt32SizeNoTag(value); } @@ -142,7 +142,7 @@ public abstract class ProtobufCoders { public static final ProtobufFloatSimpledCoder instance = new ProtobufFloatSimpledCoder(); @Override - public int computeSize(Float value) { + public int computeSize(ProtobufWriter out, int tagSize, Float value) { return value == null ? 0 : 4; } @@ -158,7 +158,7 @@ public abstract class ProtobufCoders { public static final ProtobufLongSimpledCoder instance = new ProtobufLongSimpledCoder(); @Override - public int computeSize(Long value) { + public int computeSize(ProtobufWriter out, int tagSize, Long value) { return value == null ? 0 : ProtobufFactory.computeSInt64SizeNoTag(value); } @@ -174,7 +174,7 @@ public abstract class ProtobufCoders { public static final ProtobufDoubleSimpledCoder instance = new ProtobufDoubleSimpledCoder(); @Override - public int computeSize(Double value) { + public int computeSize(ProtobufWriter out, int tagSize, Double value) { return value == null ? 0 : 8; } @@ -190,7 +190,7 @@ public abstract class ProtobufCoders { public static final ProtobufStringSimpledCoder instance = new ProtobufStringSimpledCoder(); @Override - public int computeSize(String value) { + public int computeSize(ProtobufWriter out, int tagSize, String value) { if (value == null || value.isEmpty()) { return 0; } @@ -211,8 +211,9 @@ public abstract class ProtobufCoders { public static final ProtobufNumberSimpledCoder instance = new ProtobufNumberSimpledCoder(); @Override - public int computeSize(Number value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.longValue()); + public int computeSize(ProtobufWriter out, int tagSize, Number value) { + return ProtobufLongSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.longValue()); } @Override @@ -228,8 +229,9 @@ public abstract class ProtobufCoders { public static final ProtobufStringWrapperSimpledCoder instance = new ProtobufStringWrapperSimpledCoder(); @Override - public int computeSize(StringWrapper value) { - return ProtobufStringSimpledCoder.instance.computeSize(value == null ? null : value.getValue()); + public int computeSize(ProtobufWriter out, int tagSize, StringWrapper value) { + return ProtobufStringSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.getValue()); } @Override @@ -245,8 +247,9 @@ public abstract class ProtobufCoders { public static final ProtobufCharSequenceSimpledCoder instance = new ProtobufCharSequenceSimpledCoder(); @Override - public int computeSize(CharSequence value) { - return ProtobufStringSimpledCoder.instance.computeSize(value == null ? null : value.toString()); + public int computeSize(ProtobufWriter out, int tagSize, CharSequence value) { + return ProtobufStringSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.toString()); } @Override @@ -262,8 +265,9 @@ public abstract class ProtobufCoders { public static final ProtobufStringBuilderSimpledCoder instance = new ProtobufStringBuilderSimpledCoder(); @Override - public int computeSize(StringBuilder value) { - return ProtobufStringSimpledCoder.instance.computeSize(value == null ? null : value.toString()); + public int computeSize(ProtobufWriter out, int tagSize, StringBuilder value) { + return ProtobufStringSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.toString()); } @Override @@ -278,8 +282,8 @@ public abstract class ProtobufCoders { public static final ProtobufDateSimpledCoder instance = new ProtobufDateSimpledCoder(); @Override - public int computeSize(java.util.Date value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.getTime()); + public int computeSize(ProtobufWriter out, int tagSize, java.util.Date value) { + return ProtobufLongSimpledCoder.instance.computeSize(out, tagSize, value == null ? null : value.getTime()); } @Override @@ -294,8 +298,9 @@ public abstract class ProtobufCoders { public static final ProtobufInstantSimpledCoder instance = new ProtobufInstantSimpledCoder(); @Override - public int computeSize(java.time.Instant value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.toEpochMilli()); + public int computeSize(ProtobufWriter out, int tagSize, java.time.Instant value) { + return ProtobufLongSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.toEpochMilli()); } @Override @@ -310,8 +315,10 @@ public abstract class ProtobufCoders { public static final ProtobufLocalDateSimpledCoder instance = new ProtobufLocalDateSimpledCoder(); @Override - public int computeSize(java.time.LocalDate value) { + public int computeSize(ProtobufWriter out, int tagSize, java.time.LocalDate value) { return ProtobufIntSimpledCoder.instance.computeSize( + out, + tagSize, value == null ? null : (value.getYear() * 100_00 + value.getMonthValue() * 100 + value.getDayOfMonth())); @@ -329,8 +336,9 @@ public abstract class ProtobufCoders { public static final ProtobufLocalTimeSimpledCoder instance = new ProtobufLocalTimeSimpledCoder(); @Override - public int computeSize(java.time.LocalTime value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.toNanoOfDay()); + public int computeSize(ProtobufWriter out, int tagSize, java.time.LocalTime value) { + return ProtobufLongSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.toNanoOfDay()); } @Override @@ -346,7 +354,7 @@ public abstract class ProtobufCoders { public static final ProtobufLocalDateTimeSimpledCoder instance = new ProtobufLocalDateTimeSimpledCoder(); @Override - public int computeSize(java.time.LocalDateTime value) { + public int computeSize(ProtobufWriter out, int tagSize, java.time.LocalDateTime value) { return value == null ? 0 : (ProtobufFactory.computeSInt64SizeNoTag(12) + 12); } @@ -362,8 +370,8 @@ public abstract class ProtobufCoders { public static final ProtobufDurationSimpledCoder instance = new ProtobufDurationSimpledCoder(); @Override - public int computeSize(java.time.Duration value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.toNanos()); + public int computeSize(ProtobufWriter out, int tagSize, java.time.Duration value) { + return ProtobufLongSimpledCoder.instance.computeSize(out, tagSize, value == null ? null : value.toNanos()); } @Override @@ -379,7 +387,7 @@ public abstract class ProtobufCoders { public static final ProtobufAtomicBooleanSimpledCoder instance = new ProtobufAtomicBooleanSimpledCoder(); @Override - public int computeSize(AtomicBoolean value) { + public int computeSize(ProtobufWriter out, int tagSize, AtomicBoolean value) { return value == null ? 0 : 1; } @@ -396,8 +404,8 @@ public abstract class ProtobufCoders { public static final ProtobufAtomicIntegerSimpledCoder instance = new ProtobufAtomicIntegerSimpledCoder(); @Override - public int computeSize(AtomicInteger value) { - return ProtobufIntSimpledCoder.instance.computeSize(value == null ? null : value.get()); + public int computeSize(ProtobufWriter out, int tagSize, AtomicInteger value) { + return ProtobufIntSimpledCoder.instance.computeSize(out, tagSize, value == null ? null : value.get()); } @Override @@ -412,8 +420,8 @@ public abstract class ProtobufCoders { public static final ProtobufAtomicLongSimpledCoder instance = new ProtobufAtomicLongSimpledCoder(); @Override - public int computeSize(AtomicLong value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.get()); + public int computeSize(ProtobufWriter out, int tagSize, AtomicLong value) { + return ProtobufLongSimpledCoder.instance.computeSize(out, tagSize, value == null ? null : value.get()); } @Override @@ -428,7 +436,7 @@ public abstract class ProtobufCoders { public static final ProtobufBigIntegerSimpledCoder instance = new ProtobufBigIntegerSimpledCoder(); @Override - public int computeSize(BigInteger value) { + public int computeSize(ProtobufWriter out, int tagSize, BigInteger value) { if (value == null) { return 0; } @@ -453,11 +461,11 @@ public abstract class ProtobufCoders { public static final ProtobufBigDecimalSimpledCoder instance = new ProtobufBigDecimalSimpledCoder(); @Override - public int computeSize(BigDecimal value) { + public int computeSize(ProtobufWriter out, int tagSize, BigDecimal value) { if (value == null) { return 0; } - return ProtobufStringSimpledCoder.instance.computeSize(value.toString()); + return ProtobufStringSimpledCoder.instance.computeSize(out, tagSize, value.toString()); } @Override @@ -472,7 +480,7 @@ public abstract class ProtobufCoders { public static final ProtobufInetAddressSimpledCoder instance = new ProtobufInetAddressSimpledCoder(); @Override - public int computeSize(InetAddress value) { + public int computeSize(ProtobufWriter out, int tagSize, InetAddress value) { if (value == null) { return 0; } @@ -499,7 +507,7 @@ public abstract class ProtobufCoders { new ProtobufInetSocketAddressSimpledCoder(); @Override - public int computeSize(InetSocketAddress value) { + public int computeSize(ProtobufWriter out, int tagSize, InetSocketAddress value) { if (value == null) { return 0; } @@ -524,8 +532,9 @@ public abstract class ProtobufCoders { public static final ProtobufLongAdderSimpledCoder instance = new ProtobufLongAdderSimpledCoder(); @Override - public int computeSize(LongAdder value) { - return ProtobufLongSimpledCoder.instance.computeSize(value == null ? null : value.longValue()); + public int computeSize(ProtobufWriter out, int tagSize, LongAdder value) { + return ProtobufLongSimpledCoder.instance.computeSize( + out, tagSize, value == null ? null : value.longValue()); } @Override @@ -540,7 +549,7 @@ public abstract class ProtobufCoders { public static final ProtobufUint128SimpledCoder instance = new ProtobufUint128SimpledCoder(); @Override - public int computeSize(Uint128 value) { + public int computeSize(ProtobufWriter out, int tagSize, Uint128 value) { if (value == null) { return 0; } @@ -576,7 +585,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(boolean[] value) { + public int computeSize(ProtobufWriter out, int tagSize, boolean[] value) { return value == null ? 0 : value.length; } } @@ -597,7 +606,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(byte[] value) { + public int computeSize(ProtobufWriter out, int tagSize, byte[] value) { return value == null ? 0 : value.length; } } @@ -618,7 +627,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(char[] value) { + public int computeSize(ProtobufWriter out, int tagSize, char[] value) { if (value == null || value.length == 0) { return 0; } @@ -646,7 +655,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(short[] value) { + public int computeSize(ProtobufWriter out, int tagSize, short[] value) { if (value == null || value.length == 0) { return 0; } @@ -674,7 +683,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(int[] value) { + public int computeSize(ProtobufWriter out, int tagSize, int[] value) { if (value == null || value.length == 0) { return 0; } @@ -702,7 +711,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(float[] value) { + public int computeSize(ProtobufWriter out, int tagSize, float[] value) { return value == null ? 0 : value.length * 4; } } @@ -723,7 +732,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(long[] value) { + public int computeSize(ProtobufWriter out, int tagSize, long[] value) { if (value == null || value.length == 0) { return 0; } @@ -751,7 +760,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(double[] value) { + public int computeSize(ProtobufWriter out, int tagSize, double[] value) { return value == null ? 0 : value.length * 8; } } @@ -773,7 +782,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Boolean[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Boolean[] value) { return value == null ? 0 : value.length; } } @@ -794,7 +803,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Byte[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Byte[] value) { return value == null ? 0 : value.length; } } @@ -815,7 +824,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Character[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Character[] value) { if (value == null || value.length == 0) { return 0; } @@ -843,7 +852,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Short[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Short[] value) { if (value == null || value.length == 0) { return 0; } @@ -871,7 +880,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Integer[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Integer[] value) { if (value == null || value.length == 0) { return 0; } @@ -899,7 +908,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Float[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Float[] value) { return value == null ? 0 : value.length * 4; } } @@ -920,7 +929,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Long[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Long[] value) { if (value == null || value.length == 0) { return 0; } @@ -948,7 +957,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Double[] value) { + public int computeSize(ProtobufWriter out, int tagSize, Double[] value) { return value == null ? 0 : value.length * 8; } } @@ -971,7 +980,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(AtomicInteger[] value) { + public int computeSize(ProtobufWriter out, int tagSize, AtomicInteger[] value) { if (value == null || value.length == 0) { return 0; } @@ -1000,7 +1009,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(AtomicLong[] value) { + public int computeSize(ProtobufWriter out, int tagSize, AtomicLong[] value) { if (value == null || value.length == 0) { return 0; } @@ -1034,7 +1043,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { return value == null ? 0 : value.size(); } } @@ -1060,7 +1069,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { return value == null ? 0 : value.size(); } } @@ -1086,7 +1095,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1119,7 +1128,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1152,7 +1161,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1185,7 +1194,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { return value == null ? 0 : value.size() * 4; } } @@ -1211,7 +1220,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1244,7 +1253,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { return value == null ? 0 : value.size() * 8; } } @@ -1270,7 +1279,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { return value == null ? 0 : value.size(); } } @@ -1296,7 +1305,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1329,7 +1338,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Collection value) { + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { if (value == null || value.isEmpty()) { return 0; } @@ -1359,7 +1368,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { return value == null ? 0 : (int) value.count(); } } @@ -1381,7 +1390,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { return value == null ? 0 : (int) value.count(); } } @@ -1403,7 +1412,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } @@ -1432,7 +1441,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } @@ -1461,7 +1470,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } @@ -1490,7 +1499,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { return value == null ? 0 : (int) value.count() * 4; } } @@ -1512,7 +1521,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } @@ -1541,7 +1550,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { return value == null ? 0 : (int) value.count() * 8; } } @@ -1564,7 +1573,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { return value == null ? 0 : (int) value.count(); } } @@ -1587,7 +1596,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } @@ -1616,7 +1625,7 @@ public abstract class ProtobufCoders { } @Override - public int computeSize(Stream value) { + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { if (value == null) { return 0; } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java index 364742a03..d4b384cae 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java @@ -31,7 +31,11 @@ public class ProtobufCollectionEncoder extends CollectionEncoder extends CollectionEncoder value) { - return 0; + public int computeSize(ProtobufWriter out, int tagSize, Collection value) { + if (value == null || value.isEmpty()) { + return 0; + } + int dataSize = 0; + ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder; + for (T item : value) { + dataSize += itemEncoder.computeSize(out, tagSize, item); + } + if (componentSizeRequired) { + dataSize += tagSize * value.size(); + } + return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize; } @Override diff --git a/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java index 05194e269..f277e6b35 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java @@ -33,23 +33,26 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { // 动态字段: protected EnMember xxxEnMember; - protected ProtobufDynEncoder(ProtobufFactory factory, Type type, ObjectEncoder objectEncoderSelf) { + protected ProtobufDynEncoder(ProtobufFactory factory, Type type, ProtobufObjectEncoder objectEncoderSelf) { super((Class) type); this.typeClass = (Class) type; this.factory = factory; this.objectEncoderSelf = objectEncoderSelf; + this.memberSizeRequired = objectEncoderSelf.memberSizeRequired; this.members = objectEncoderSelf.getMembers(); this.inited = true; factory.register(type, this); } @Override - public abstract void convertTo(ProtobufWriter out, T value); + public abstract void convertTo(ProtobufWriter out, EnMember member, T value); protected static ProtobufDynEncoder generateDyncEncoder(final ProtobufFactory factory, final Class clazz) { final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz); selfObjEncoder.init(factory); // 必须执行,初始化EnMember内部信息 - + // if (((ProtobufObjectEncoder) selfObjEncoder).requiredMemberSize()) { // 嵌套对象 + // return null; + // } final Map simpledCoders = new HashMap<>(); final Map otherMembers = new HashMap<>(); StringBuilder elementb = new StringBuilder(); @@ -76,8 +79,8 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz; - ProtobufDynEncoder resultEncoder = - (ProtobufDynEncoder) newClazz.getConstructor(ProtobufFactory.class, Type.class, ObjectEncoder.class) + ProtobufDynEncoder resultEncoder = (ProtobufDynEncoder) + newClazz.getConstructor(ProtobufFactory.class, Type.class, ProtobufObjectEncoder.class) .newInstance(factory, clazz, selfObjEncoder); if (!simpledCoders.isEmpty()) { for (Map.Entry en : simpledCoders.entrySet()) { @@ -106,7 +109,7 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { final String pbwriterDesc = org.redkale.asm.Type.getDescriptor(ProtobufWriter.class); final String simpledCoderDesc = org.redkale.asm.Type.getDescriptor(SimpledCoder.class); final String enMemberDesc = org.redkale.asm.Type.getDescriptor(EnMember.class); - final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class); + final String pbencoderDesc = org.redkale.asm.Type.getDescriptor(ProtobufObjectEncoder.class); final String objectDesc = org.redkale.asm.Type.getDescriptor(Object.class); final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz); // ------------------------------------------------------------------------------ @@ -134,41 +137,54 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { } { // 构造函数 mv = (cw.visitMethod( - ACC_PUBLIC, "", "(" + pbfactoryDesc + typeDesc + objEncoderDesc + ")V", null, null)); + ACC_PUBLIC, "", "(" + pbfactoryDesc + typeDesc + pbencoderDesc + ")V", null, null)); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn( - INVOKESPECIAL, supDynName, "", "(" + pbfactoryDesc + typeDesc + objEncoderDesc + ")V", false); + INVOKESPECIAL, supDynName, "", "(" + pbfactoryDesc + typeDesc + pbencoderDesc + ")V", false); mv.visitInsn(RETURN); mv.visitMaxs(4, 4); mv.visitEnd(); } { // convertTo 方法 - mv = (cw.visitMethod(ACC_PUBLIC, "convertTo", "(" + pbwriterDesc + valtypeDesc + ")V", null, null)); + mv = (cw.visitMethod( + ACC_PUBLIC, "convertTo", "(" + pbwriterDesc + enMemberDesc + valtypeDesc + ")V", null, null)); // if (value == null) return; - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value Label ifLabel = new Label(); mv.visitJumpInsn(IFNONNULL, ifLabel); mv.visitInsn(RETURN); mv.visitLabel(ifLabel); mv.visitLineNumber(33, ifLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - // ProtobufWriter out = objectWriter(out0, value); - mv.visitVarInsn(ALOAD, 0); + + // if (parentMember != null) out0.writeField(parentMember); + mv.visitVarInsn(ALOAD, 2); // parentMember + Label ifMemberLabel = new Label(); + mv.visitJumpInsn(IFNULL, ifMemberLabel); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeField", "(" + enMemberDesc + ")V", false); + mv.visitLabel(ifMemberLabel); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + + // ProtobufWriter out = objectWriter(out0, parentMember, value); + mv.visitVarInsn(ALOAD, 0); // this + mv.visitVarInsn(ALOAD, 1); // out0 + mv.visitVarInsn(ALOAD, 2); // member + mv.visitVarInsn(ALOAD, 3); // value mv.visitMethodInsn( INVOKEVIRTUAL, newDynName, "objectWriter", - "(" + pbwriterDesc + objectDesc + ")" + pbwriterDesc, + "(" + pbwriterDesc + enMemberDesc + objectDesc + ")" + pbwriterDesc, false); - mv.visitVarInsn(ASTORE, 3); + mv.visitVarInsn(ASTORE, 4); + mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 3); - mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeObjectB", "(Ljava/lang/Object;)V", false); for (EnMember member : selfObjEncoder.getMembers()) { @@ -176,9 +192,9 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { final Type fieldType = member.getAttribute().genericType(); final Class fieldClass = member.getAttribute().type(); if (ProtobufFactory.isSimpleType(fieldClass)) { - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out Asms.visitInsn(mv, member.getTag()); // tag - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value if (member.getMethod() != null) { String mname = member.getMethod().getName(); String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod()); @@ -192,9 +208,9 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { String fieldDesc = org.redkale.asm.Type.getDescriptor(fieldClass); mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeFieldValue", "(I" + fieldDesc + ")V", false); } else if (fieldClass.isEnum()) { - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out Asms.visitInsn(mv, member.getTag()); // tag - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value if (member.getMethod() != null) { String mname = member.getMethod().getName(); String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod()); @@ -207,9 +223,9 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { } mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeFieldValue", "(ILjava/lang/Enum;)V", false); } else if (factory.supportSimpleCollectionType(fieldType)) { - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out Asms.visitInsn(mv, member.getTag()); // tag - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value if (member.getMethod() != null) { String mname = member.getMethod().getName(); String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod()); @@ -249,11 +265,11 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { } mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, wmethodName, "(ILjava/util/Collection;)V", false); } else if (simpledCoders.containsKey(fieldName)) { - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out Asms.visitInsn(mv, member.getTag()); // tag mv.visitVarInsn(ALOAD, 0); // this mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "SimpledCoder", simpledCoderDesc); - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value if (member.getMethod() != null) { String mname = member.getMethod().getName(); String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod()); @@ -271,10 +287,10 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { "(I" + simpledCoderDesc + objectDesc + ")V", false); } else { - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out mv.visitVarInsn(ALOAD, 0); // this mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "EnMember", enMemberDesc); - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 3); // value mv.visitMethodInsn( INVOKEVIRTUAL, pbwriterName, @@ -284,13 +300,13 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { } } // out.writeObjectE(value); - mv.visitVarInsn(ALOAD, 3); // out - mv.visitVarInsn(ALOAD, 2); // value + mv.visitVarInsn(ALOAD, 4); // out + mv.visitVarInsn(ALOAD, 3); // value mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeObjectE", "(Ljava/lang/Object;)V", false); // offerWriter(out0, out); mv.visitVarInsn(ALOAD, 0); // this mv.visitVarInsn(ALOAD, 1); // out0 - mv.visitVarInsn(ALOAD, 3); // out + mv.visitVarInsn(ALOAD, 4); // out mv.visitMethodInsn( INVOKEVIRTUAL, newDynName, "offerWriter", "(" + pbwriterDesc + pbwriterDesc + ")V", false); @@ -302,15 +318,21 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { mv = (cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "convertTo", - "(" + pbwriterDesc + "Ljava/lang/Object;)V", + "(" + pbwriterDesc + enMemberDesc + "Ljava/lang/Object;)V", null, null)); // mv.setDebug(true); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); mv.visitTypeInsn(CHECKCAST, valtypeName); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "convertTo", "(" + pbwriterDesc + valtypeDesc + ")V", false); + mv.visitMethodInsn( + INVOKEVIRTUAL, + newDynName, + "convertTo", + "(" + pbwriterDesc + enMemberDesc + valtypeDesc + ")V", + false); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); @@ -327,8 +349,8 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); try { - ProtobufDynEncoder resultEncoder = - (ProtobufDynEncoder) newClazz.getConstructor(ProtobufFactory.class, Type.class, ObjectEncoder.class) + ProtobufDynEncoder resultEncoder = (ProtobufDynEncoder) + newClazz.getConstructor(ProtobufFactory.class, Type.class, ProtobufObjectEncoder.class) .newInstance(factory, clazz, selfObjEncoder); if (!simpledCoders.isEmpty()) { for (Map.Entry en : simpledCoders.entrySet()) { diff --git a/src/main/java/org/redkale/convert/pb/ProtobufEncodeable.java b/src/main/java/org/redkale/convert/pb/ProtobufEncodeable.java index 72adb98c3..d3d8fc47b 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufEncodeable.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufEncodeable.java @@ -4,6 +4,7 @@ */ package org.redkale.convert.pb; +import org.redkale.convert.EnMember; import org.redkale.convert.Encodeable; import org.redkale.convert.Writer; @@ -17,11 +18,17 @@ import org.redkale.convert.Writer; * @param 序列化的数据类型 */ public interface ProtobufEncodeable extends Encodeable { + // 计算内容长度 - public int computeSize(T value); + public int computeSize(ProtobufWriter out, int tagSize, T value); // 是否需要计算内容长度 default boolean requireSize() { return false; } + + // 序列化 + default void convertTo(W out, EnMember member, T value) { + convertTo(out, value); + } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufEnumSimpledCoder.java b/src/main/java/org/redkale/convert/pb/ProtobufEnumSimpledCoder.java index 7cefd6865..a8fe078ed 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufEnumSimpledCoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufEnumSimpledCoder.java @@ -70,7 +70,7 @@ public class ProtobufEnumSimpledCoder extends MapEncoder public ProtobufMapEncoder(ConvertFactory factory, Type type) { super(factory, type); this.enumtostring = ((ProtobufFactory) factory).enumtostring; - this.keyTag = 1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring); - this.valTag = 2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring); + this.keyTag = 1 << 3 | ProtobufFactory.wireTypeBit(keyEncoder.getType(), enumtostring); + this.valTag = 2 << 3 | ProtobufFactory.wireTypeBit(valueEncoder.getType(), enumtostring); } @Override @@ -63,7 +63,7 @@ public class ProtobufMapEncoder extends MapEncoder } @Override - public int computeSize(Map value) { + public int computeSize(ProtobufWriter out, int tagLen, Map value) { if (value == null || value.isEmpty()) { return 0; } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufObjectDecoder.java b/src/main/java/org/redkale/convert/pb/ProtobufObjectDecoder.java index e03ee5da1..3c9c60299 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufObjectDecoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufObjectDecoder.java @@ -43,6 +43,7 @@ public class ProtobufObjectDecoder extends ObjectDecoder Attribute attr = member.getAttribute(); boolean enumtostring = ((ProtobufFactory) factory).enumtostring; setTag(member, ProtobufFactory.getTag(attr.field(), attr.genericType(), member.getPosition(), enumtostring)); + setTagSize(member, ProtobufFactory.computeSInt32SizeNoTag(member.getTag())); } @Override diff --git a/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java index 282875795..17916e328 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java @@ -6,6 +6,7 @@ package org.redkale.convert.pb; import java.lang.reflect.Type; +import org.redkale.annotation.ClassDepends; import org.redkale.convert.*; import org.redkale.util.Attribute; import org.redkale.util.Utility; @@ -23,6 +24,67 @@ public class ProtobufObjectEncoder extends ObjectEncoder super(type); } + @Override + public final void convertTo(ProtobufWriter out, T value) { + convertTo(out, null, value); + } + + @Override + public void convertTo(ProtobufWriter out, EnMember parentMember, T value) { + this.checkInited(); + if (value == null) { + out.writeObjectNull(null); + return; + } + if (parentMember != null) { + out.writeField(parentMember); + } + ProtobufWriter objout = objectWriter(out, parentMember, value); + objout.writeObjectB(value); + int maxPosition = 0; + for (EnMember member : members) { + maxPosition = member.getPosition(); + objout.writeObjectField(member, value); + } + if (objout.objExtFunc() != null) { + ConvertField[] extFields = objout.objExtFunc().apply(value); + if (extFields != null) { + Encodeable anyEncoder = factory.getAnyEncoder(); + for (ConvertField en : extFields) { + if (en != null) { + maxPosition++; + objout.writeObjectField( + en.getName(), + en.getType(), + Math.max(en.getPosition(), maxPosition), + anyEncoder, + en.getValue()); + } + } + } + } + objout.writeObjectE(value); + offerWriter(out, objout); + } + + @ClassDepends + protected ProtobufWriter objectWriter(ProtobufWriter out, EnMember parentMember, T value) { + // if (parentMember != null) { + // out.writeLength(computeSize(out, parentMember.getTagSize(), value)); + // } + if (out.length() > out.initOffset) { + return out.pollChild().configParentFunc(out); + } + return out; + } + + @ClassDepends + protected void offerWriter(ProtobufWriter parent, ProtobufWriter out) { + if (parent != out) { + parent.offerChild(out); + } + } + @Override protected void initForEachEnMember(ConvertFactory factory, EnMember member) { if (member.getIndex() < 1) { @@ -33,36 +95,30 @@ public class ProtobufObjectEncoder extends ObjectEncoder boolean enumtostring = ((ProtobufFactory) factory).enumtostring; this.memberSizeRequired |= ((ProtobufEncodeable) member.getEncoder()).requireSize(); setTag(member, ProtobufFactory.getTag(attr.field(), attr.genericType(), member.getPosition(), enumtostring)); + setTagSize(member, ProtobufFactory.computeSInt32SizeNoTag(member.getTag())); } @Override - protected ProtobufWriter objectWriter(ProtobufWriter out, T value) { -// if (memberSizeRequired) { -// out.writeLength(computeSize(value)); -// } -// return out; - if (out.length() > out.initOffset) { - return out.pollChild().configParentFunc(out); - } - return out; - } - - @Override - protected void offerWriter(ProtobufWriter parent, ProtobufWriter out) { - if (parent != out) { - parent.offerChild(out); - } - } - - @Override - public int computeSize(T value) { + public int computeSize(ProtobufWriter out, int tagSize, T value) { int size = 0; for (EnMember member : members) { - size += ((ProtobufEncodeable) member.getEncoder()).computeSize(member.getFieldValue(value)); + ProtobufEncodeable encodeable = (ProtobufEncodeable) member.getEncoder(); + int itemTagSize = member.getTagSize(); + int itemDataSize = encodeable.computeSize(out, itemTagSize, member.getFieldValue(value)); + if (itemDataSize > 0) { + size += itemTagSize + itemDataSize; + System.out.println( + "member: " + member.getFieldName() + ", tag: " + itemTagSize + ", data: " + itemDataSize); + } } + System.out.println("对象: " + value + ", 大小: " + size); return size; } + public boolean requiredMemberSize() { + return memberSizeRequired; + } + @Override public final boolean requireSize() { return true; diff --git a/src/main/java/org/redkale/convert/pb/ProtobufReader.java b/src/main/java/org/redkale/convert/pb/ProtobufReader.java index 1d484d385..352b0b815 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufReader.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufReader.java @@ -91,16 +91,16 @@ public class ProtobufReader extends Reader { return; } switch (tag & 0x7) { - case 0: + case 0: // boolean/byte/char/short/int/long readRawVarint32(); break; - case 1: + case 1: // double readRawLittleEndian64(); break; - case 2: + case 2: // byte[] readByteArray(); break; - case 5: + case 5: // float readRawLittleEndian32(); break; default: @@ -626,14 +626,14 @@ public class ProtobufReader extends Reader { throw new ConvertException("readRawVarint64SlowPath error"); } - protected int readRawLittleEndian32() { + protected int readRawLittleEndian32() { //float return ((content[++this.position] & 0xff) | ((content[++this.position] & 0xff) << 8) | ((content[++this.position] & 0xff) << 16) | ((content[++this.position] & 0xff) << 24)); } - protected long readRawLittleEndian64() { + protected long readRawLittleEndian64() { //double return ((content[++this.position] & 0xffL) | ((content[++this.position] & 0xffL) << 8) | ((content[++this.position] & 0xffL) << 16) diff --git a/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java index a841e8f78..97ba81cd6 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java @@ -32,7 +32,7 @@ public class ProtobufStreamEncoder extends StreamEncoder if (array == null || array.length < 1) { return; } - Encodeable itemEncoder = this.componentEncoder; + ProtobufEncodeable itemEncoder = (ProtobufEncodeable)this.componentEncoder; out.writeArrayB(array.length, itemEncoder, array); for (Object item : array) { out.writeField(member); @@ -51,8 +51,9 @@ public class ProtobufStreamEncoder extends StreamEncoder } @Override - public int computeSize(Stream value) { - return 0; + public int computeSize(ProtobufWriter out, int tagSize, Stream value) { + // Stream被forEach之后就不可用了, 所以不能进行遍历 + throw new UnsupportedOperationException("Not supported yet."); } @Override diff --git a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java index 2e9abda76..eb2d1f493 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java @@ -13,6 +13,7 @@ import java.util.concurrent.atomic.*; import java.util.function.*; import java.util.stream.Stream; import org.redkale.annotation.ClassDepends; +import org.redkale.annotation.Nullable; import org.redkale.convert.*; import org.redkale.util.*; @@ -87,6 +88,20 @@ public class ProtobufWriter extends Writer implements ByteTuple { this.content = bs; } + public ProtobufWriter() { + this(DEFAULT_SIZE); + } + + public ProtobufWriter(int size) { + this.content = new byte[Math.max(size, DEFAULT_SIZE)]; + } + + public ProtobufWriter(ByteArray array) { + this.content = array.content(); + this.initOffset = array.offset(); + this.count = array.length(); + } + @Override public final ProtobufWriter withFeatures(int features) { super.withFeatures(features); @@ -123,18 +138,8 @@ public class ProtobufWriter extends Writer implements ByteTuple { return mapFieldFunc; } - public ProtobufWriter() { - this(DEFAULT_SIZE); - } - - public ProtobufWriter(int size) { - this.content = new byte[Math.max(size, DEFAULT_SIZE)]; - } - - public ProtobufWriter(ByteArray array) { - this.content = array.content(); - this.initOffset = array.offset(); - this.count = array.length(); + protected Function objExtFunc() { + return objExtFunc; } @Override @@ -1294,8 +1299,26 @@ public class ProtobufWriter extends Writer implements ByteTuple { } } + @ClassDepends // objExtFunc扩展字段时member=null + public final void writeObjectField2(@Nullable EnMember member, Object obj) { + Object value; + if (objFieldFunc == null) { + value = member.getFieldValue(obj); + } else { + value = objFieldFunc.apply(member.getAttribute(), obj); + } + if (value == null) { + return; + } + ProtobufEncodeable encoder = (ProtobufEncodeable) member.getEncoder(); + if (encoder.requireSize()) { + writeLength(encoder.computeSize(this, member.getTagSize(), value)); + } + encoder.convertTo(this, member, value); + } + @Override - @ClassDepends + @ClassDepends // objExtFunc扩展字段时member=null public final void writeObjectField(final EnMember member, Object obj) { Object value; if (objFieldFunc == null) { diff --git a/src/test/java/org/redkale/test/convert/GenericEntityTest.java b/src/test/java/org/redkale/test/convert/GenericEntityTest.java index fee64926f..f2520667e 100644 --- a/src/test/java/org/redkale/test/convert/GenericEntityTest.java +++ b/src/test/java/org/redkale/test/convert/GenericEntityTest.java @@ -85,6 +85,7 @@ public class GenericEntityTest { byte[] bs = convert.convertTo(ENTITY_TYPE, bean); Utility.println("proto0 ", bs); String rs = convert.convertFrom(ENTITY_TYPE, bs).toString(); + System.out.println("反解析: " + rs); Assertions.assertEquals(JSON, rs); } diff --git a/src/test/java/org/redkale/test/convert/pb/RequiredBeanTest.java b/src/test/java/org/redkale/test/convert/pb/RequiredBeanTest.java new file mode 100644 index 000000000..1250a8e8d --- /dev/null +++ b/src/test/java/org/redkale/test/convert/pb/RequiredBeanTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016-2116 Redkale + * All rights reserved. + */ +package org.redkale.test.convert.pb; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.redkale.convert.ConvertColumn; +import org.redkale.convert.json.JsonConvert; +import org.redkale.convert.pb.ProtobufConvert; +import org.redkale.util.Utility; + +/** + * + * @author zhangjx + */ +public class RequiredBeanTest { + + public static void main(String[] args) throws Throwable { + RequiredBeanTest test = new RequiredBeanTest(); + test.run(); + } + + @Test + public void run() throws Exception { + RequiredBean bean = RequiredBean.create(); + ProtobufConvert convert = ProtobufConvert.root(); + byte[] bytes = convert.convertTo(bean); + System.out.println("序列化0: 26.[0x08,0x0c,0x12,0x03,0x61,0x61,0x61,0x12,0x03,0x62,0x62,0x62," + + "0x1a,0x03,0x63,0x63,0x63,0x1a,0x03,0x64,0x64,0x64,0x22,0x02,0x02,0x04]"); + Utility.println("序列化0: ", bytes); + RequiredArray array = new RequiredArray(); + array.beans = new RequiredBean[] {bean}; + byte[] bytes2 = convert.convertTo(array); + System.out.println("序列化s: 29.[0x1f,0x0a,0x1a,0x08,0x0c,0x12,0x03,0x61,0x61,0x61,0x12,0x03,0x62,0x62,0x62," + + "0x1a,0x03,0x63,0x63,0x63,0x1a,0x03,0x64,0x64,0x64,0x22,0x02,0x02,0x04]"); + Utility.println("序列化s: ", bytes2); + System.out.println("-----------------------------------------------"); + String jsons1 = JsonConvert.root().convertTo(array); + RequiredArray array2 = convert.convertFrom(RequiredArray.class, bytes2); + String jsons2 = JsonConvert.root().convertTo(array2); + System.out.println(jsons1); + System.out.println(jsons2); + Assertions.assertEquals(jsons1, jsons2); + } + + public static class RequiredArray { + @ConvertColumn(index = 1) + private RequiredBean[] beans; + + public RequiredBean[] getBeans() { + return beans; + } + + public void setBeans(RequiredBean[] beans) { + this.beans = beans; + } + } + + public static class RequiredBean { + + public static RequiredBean create() { + RequiredBean bean = new RequiredBean(); + bean.id = 6; + bean.strs1 = new String[] {"aaa", "bbb"}; + bean.strs2 = List.of("ccc", "ddd"); + bean.zbig1 = List.of(new AtomicInteger(1), new AtomicInteger(2)); + return bean; + } + + @ConvertColumn(index = 1) + private int id; + + @ConvertColumn(index = 2) + private String[] strs1; + + @ConvertColumn(index = 3) + private List strs2; + + @ConvertColumn(index = 4) + private List zbig1; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String[] getStrs1() { + return strs1; + } + + public void setStrs1(String[] strs1) { + this.strs1 = strs1; + } + + public List getStrs2() { + return strs2; + } + + public void setStrs2(List strs2) { + this.strs2 = strs2; + } + + public List getZbig1() { + return zbig1; + } + + public void setZbig1(List zbig1) { + this.zbig1 = zbig1; + } + } +} diff --git a/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java b/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java index da7ad319b..f86e188d5 100644 --- a/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java +++ b/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java @@ -6,10 +6,10 @@ package org.redkale.test.convert.pb; import java.lang.reflect.Type; import org.redkale.convert.EnMember; -import org.redkale.convert.ObjectEncoder; import org.redkale.convert.SimpledCoder; import org.redkale.convert.pb.ProtobufDynEncoder; import org.redkale.convert.pb.ProtobufFactory; +import org.redkale.convert.pb.ProtobufObjectEncoder; import org.redkale.convert.pb.ProtobufWriter; /** @@ -21,16 +21,16 @@ public class UserBeanProtoDynEncoder extends ProtobufDynEncoder { protected SimpledCoder scaleSimpledCoder; protected EnMember mapEnMember; - public UserBeanProtoDynEncoder(ProtobufFactory factory, Type type, ObjectEncoder objectEncoder) { + public UserBeanProtoDynEncoder(ProtobufFactory factory, Type type, ProtobufObjectEncoder objectEncoder) { super(factory, type, objectEncoder); } @Override - public void convertTo(ProtobufWriter out0, UserBean value) { + public void convertTo(ProtobufWriter out0, EnMember parentMember, UserBean value) { if (value == null) { return; } - ProtobufWriter out = objectWriter(out0, value); + ProtobufWriter out = objectWriter(out0, parentMember, value); out.writeObjectB(value); out.writeFieldValue(1, value.getSeqid()); out.writeFieldValue(2, value.getName());