This commit is contained in:
redkale
2024-09-25 18:55:18 +08:00
parent 23eaff080b
commit 1d4a1d4b66
5 changed files with 201 additions and 70 deletions

View File

@@ -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<T> extends ProtobufObjectEncoder<T> {
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<T> extends ProtobufObjectEncoder<T> {
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<T> extends ProtobufObjectEncoder<T> {
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<T> extends ProtobufObjectEncoder<T> {
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<T> extends ProtobufObjectEncoder<T> {
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";
}

View File

@@ -228,6 +228,76 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|| type == AtomicLong.class;
}
protected 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 == AtomicInteger.class
|| fieldClass == AtomicLong.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 == AtomicInteger[].class
|| fieldClass == AtomicLong[].class
|| fieldClass == String[].class;
}
protected 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 == AtomicInteger.class
|| componentType == AtomicLong.class
|| componentType == String.class;
}
public static Class getSimpleCollectionComponentType(Type type) {
return supportSimpleCollectionType(type)
? (Class) ((ParameterizedType) type).getActualTypeArguments()[0]
: null;
}
public static int getTag(String fieldName, Type fieldType, int fieldPos, boolean enumtostring) {
int wiretype = ProtobufFactory.wireType(fieldType, enumtostring);
return (fieldPos << 3 | wiretype);

View File

@@ -5,7 +5,6 @@
*/
package org.redkale.convert.pb;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -872,6 +871,62 @@ public class ProtobufWriter extends Writer implements ByteTuple {
}
}
public void writeAtomicIntegers(AtomicInteger[] value) {
AtomicInteger[] array = value;
if (array != null && array.length > 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<AtomicInteger> value) {
Collection<AtomicInteger> 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<AtomicLong> value) {
Collection<AtomicLong> 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<AtomicInteger> value) {
if (value != null && !value.isEmpty()) {
writeTag(tag);
writeAtomicIntegers(value);
this.comma = true;
}
}
@ClassDepends
public void writeFieldAtomicLongsValue(int tag, Collection<AtomicLong> value) {
if (value != null && !value.isEmpty()) {
writeTag(tag);
writeAtomicLongs(value);
this.comma = true;
}
}
@ClassDepends
public void writeFieldStringsValue(int tag, Collection<String> 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) {

View File

@@ -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<String, String> getMap() {
return map;
}

View File

@@ -78,6 +78,8 @@ public class UserBeanProtoDynEncoder extends ProtobufDynEncoder<UserBean> {
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);