From 1d4a1d4b664697b7c202a97382a14d43dbae8061 Mon Sep 17 00:00:00 2001 From: redkale Date: Wed, 25 Sep 2024 18:55:18 +0800 Subject: [PATCH] protobuf --- .../convert/pb/ProtobufDynEncoder.java | 16 +- .../redkale/convert/pb/ProtobufFactory.java | 70 +++++++ .../redkale/convert/pb/ProtobufWriter.java | 175 +++++++++++------- .../org/redkale/test/convert/pb/UserBean.java | 8 + .../convert/pb/UserBeanProtoDynEncoder.java | 2 + 5 files changed, 201 insertions(+), 70 deletions(-) diff --git a/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java index 6cf665e85..c0fecb4d9 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java @@ -8,6 +8,8 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import org.redkale.asm.Asms; import org.redkale.asm.ClassWriter; import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES; @@ -67,9 +69,9 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { final Class fieldClass = member.getAttribute().type(); final Type fieldType = member.getAttribute().genericType(); elementb.append(fieldName).append(','); - if (!ProtobufWriter.isSimpleType(fieldClass) + if (!ProtobufFactory.isSimpleType(fieldClass) && !fieldClass.isEnum() - && !ProtobufWriter.supportSimpleCollectionType(fieldType)) { + && !ProtobufFactory.supportSimpleCollectionType(fieldType)) { if ((member.getEncoder() instanceof SimpledCoder)) { simpledCoders.put(fieldName, (SimpledCoder) member.getEncoder()); } else { @@ -185,7 +187,7 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { final String fieldName = member.getAttribute().field(); final Type fieldType = member.getAttribute().genericType(); final Class fieldClass = member.getAttribute().type(); - if (ProtobufWriter.isSimpleType(fieldClass)) { + if (ProtobufFactory.isSimpleType(fieldClass)) { mv.visitVarInsn(ALOAD, 3); // out Asms.visitInsn(mv, member.getTag()); // tag mv.visitVarInsn(ALOAD, 2); // value @@ -216,7 +218,7 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc); } mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeFieldValue", "(ILjava/lang/Enum;)V", false); - } else if (ProtobufWriter.supportSimpleCollectionType(fieldType)) { + } else if (ProtobufFactory.supportSimpleCollectionType(fieldType)) { mv.visitVarInsn(ALOAD, 3); // out Asms.visitInsn(mv, member.getTag()); // tag mv.visitVarInsn(ALOAD, 2); // value @@ -230,7 +232,7 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { String fdesc = org.redkale.asm.Type.getDescriptor(field.getType()); mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc); } - Class componentType = ProtobufWriter.getSimpleCollectionComponentType(fieldType); + Class componentType = ProtobufFactory.getSimpleCollectionComponentType(fieldType); String wmethodName = null; if (componentType == Boolean.class) { wmethodName = "writeFieldBoolsValue"; @@ -248,6 +250,10 @@ public abstract class ProtobufDynEncoder extends ProtobufObjectEncoder { wmethodName = "writeFieldLongsValue"; } else if (componentType == Double.class) { wmethodName = "writeFieldDoublesValue"; + } else if (componentType == AtomicInteger.class) { + wmethodName = "writeFieldAtomicIntegersValue"; + } else if (componentType == AtomicLong.class) { + wmethodName = "writeFieldAtomicLongsValue"; } else if (componentType == String.class) { wmethodName = "writeFieldStringValue"; } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufFactory.java b/src/main/java/org/redkale/convert/pb/ProtobufFactory.java index 09ecbc64f..048d8c57c 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufFactory.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufFactory.java @@ -228,6 +228,76 @@ public class ProtobufFactory extends ConvertFactory 0) { + int len = 0; + for (AtomicInteger item : array) { + len += computeSInt32SizeNoTag(item == null ? 0 : item.get()); + } + writeLength(len); + for (AtomicInteger item : array) { + writeInt(item == null ? 0 : item.get()); + } + } + } + + public void writeAtomicIntegers(Collection value) { + Collection array = value; + if (array != null && !array.isEmpty()) { + int len = 0; + for (AtomicInteger item : array) { + len += computeSInt32SizeNoTag(item == null ? 0 : item.get()); + } + writeLength(len); + for (AtomicInteger item : array) { + writeInt(item == null ? 0 : item.get()); + } + } + } + + public void writeAtomicLongs(AtomicLong[] value) { + AtomicLong[] array = value; + if (array != null && array.length > 0) { + int len = 0; + for (AtomicLong item : array) { + len += computeSInt64SizeNoTag(item == null ? 0 : item.get()); + } + writeLength(len); + for (AtomicLong item : array) { + writeLong(item == null ? 0 : item.get()); + } + } + } + + public void writeAtomicLongs(Collection value) { + Collection array = value; + if (array != null && !array.isEmpty()) { + int len = 0; + for (AtomicLong item : array) { + len += computeSInt64SizeNoTag(item == null ? 0 : item.get()); + } + writeLength(len); + for (AtomicLong item : array) { + writeLong(item == null ? 0 : item.get()); + } + } + } + @Override public void writeWrapper(StringWrapper value) { if (value != null) { @@ -1023,6 +1078,24 @@ public class ProtobufWriter extends Writer implements ByteTuple { } } + @ClassDepends + public void writeFieldValue(int tag, AtomicInteger value) { + if (value != null && value.get() != 0) { + writeTag(tag); + writeInt(value.get()); + this.comma = true; + } + } + + @ClassDepends + public void writeFieldValue(int tag, AtomicLong value) { + if (value != null && value.get() != 0) { + writeTag(tag); + writeLong(value.get()); + this.comma = true; + } + } + @ClassDepends public void writeFieldValue(int tag, boolean[] value) { if (value != null && value.length > 0) { @@ -1167,6 +1240,24 @@ public class ProtobufWriter extends Writer implements ByteTuple { } } + @ClassDepends + public void writeFieldValue(int tag, AtomicInteger[] value) { + if (value != null && value.length > 0) { + writeTag(tag); + writeAtomicIntegers(value); + this.comma = true; + } + } + + @ClassDepends + public void writeFieldValue(int tag, AtomicLong[] value) { + if (value != null && value.length > 0) { + writeTag(tag); + writeAtomicLongs(value); + this.comma = true; + } + } + @ClassDepends public void writeFieldValue(int tag, String[] value) { if (value != null && value.length > 0) { @@ -1247,6 +1338,24 @@ public class ProtobufWriter extends Writer implements ByteTuple { } } + @ClassDepends + public void writeFieldAtomicIntegersValue(int tag, Collection value) { + if (value != null && !value.isEmpty()) { + writeTag(tag); + writeAtomicIntegers(value); + this.comma = true; + } + } + + @ClassDepends + public void writeFieldAtomicLongsValue(int tag, Collection value) { + if (value != null && !value.isEmpty()) { + writeTag(tag); + writeAtomicLongs(value); + this.comma = true; + } + } + @ClassDepends public void writeFieldStringsValue(int tag, Collection value) { if (value != null && !value.isEmpty()) { @@ -1535,70 +1644,6 @@ public class ProtobufWriter extends Writer implements ByteTuple { }; } - public static boolean isSimpleType(Class fieldClass) { - return fieldClass.isPrimitive() - || fieldClass == Boolean.class - || fieldClass == Byte.class - || fieldClass == Character.class - || fieldClass == Short.class - || fieldClass == Integer.class - || fieldClass == Float.class - || fieldClass == Long.class - || fieldClass == Double.class - || fieldClass == String.class - || fieldClass == boolean[].class - || fieldClass == byte[].class - || fieldClass == char[].class - || fieldClass == short[].class - || fieldClass == int[].class - || fieldClass == float[].class - || fieldClass == long[].class - || fieldClass == double[].class - || fieldClass == Boolean[].class - || fieldClass == Byte[].class - || fieldClass == Character[].class - || fieldClass == Short[].class - || fieldClass == Integer[].class - || fieldClass == Float[].class - || fieldClass == Long[].class - || fieldClass == Double[].class - || fieldClass == String[].class; - } - - public static boolean supportSimpleCollectionType(Type type) { - if (!(type instanceof ParameterizedType)) { - return false; - } - ParameterizedType ptype = (ParameterizedType) type; - if (!(ptype.getRawType() instanceof Class)) { - return false; - } - Type[] ptargs = ptype.getActualTypeArguments(); - if (ptargs == null || ptargs.length != 1) { - return false; - } - Class ownerType = (Class) ptype.getRawType(); - if (!Collection.class.isAssignableFrom(ownerType)) { - return false; - } - Type componentType = ptargs[0]; - return componentType == Boolean.class - || componentType == Byte.class - || componentType == Character.class - || componentType == Short.class - || componentType == Integer.class - || componentType == Float.class - || componentType == Long.class - || componentType == Double.class - || componentType == String.class; - } - - public static Class getSimpleCollectionComponentType(Type type) { - return supportSimpleCollectionType(type) - ? (Class) ((ParameterizedType) type).getActualTypeArguments()[0] - : null; - } - // see com.google.protobuf.CodedOutputStream protected static int computeInt32SizeNoTag(final int value) { if (value == 0) { diff --git a/src/test/java/org/redkale/test/convert/pb/UserBean.java b/src/test/java/org/redkale/test/convert/pb/UserBean.java index 04022e71a..6e53123f2 100644 --- a/src/test/java/org/redkale/test/convert/pb/UserBean.java +++ b/src/test/java/org/redkale/test/convert/pb/UserBean.java @@ -9,6 +9,8 @@ import java.math.BigInteger; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import org.redkale.convert.ConvertColumn; import org.redkale.convert.json.JsonConvert; import org.redkale.persistence.Id; @@ -145,6 +147,12 @@ public class UserBean { @ConvertColumn(index = 42) public UserKind kind; + @ConvertColumn(index = 43) + public AtomicInteger count; + + @ConvertColumn(index = 44) + public AtomicLong[] count2; + public Map getMap() { return map; } 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 ee96e0b66..4a6acdaf7 100644 --- a/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java +++ b/src/test/java/org/redkale/test/convert/pb/UserBeanProtoDynEncoder.java @@ -78,6 +78,8 @@ public class UserBeanProtoDynEncoder extends ProtobufDynEncoder { out.writeFieldBytesValue(23, value.getBit6()); out.writeFieldValue(100, value.kind); + out.writeFieldValue(101, value.count); + out.writeFieldValue(102, value.count2); out.writeObjectField(mapEnMember, value); out.writeObjectE(value);