This commit is contained in:
redkale
2024-10-03 01:05:12 +08:00
parent 67aa3c0609
commit 8e981e1b7e
14 changed files with 220 additions and 204 deletions

View File

@@ -6,10 +6,12 @@
package org.redkale.convert.ext;
import java.net.*;
import java.util.Arrays;
import java.util.Objects;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
import org.redkale.util.StringWrapper;
import org.redkale.util.Utility;
/**
* InetAddress 的SimpledCoder实现
@@ -35,7 +37,6 @@ public class InetAddressSimpledCoder<R extends Reader, W extends Writer> extends
this.bsSimpledCoder = Objects.requireNonNull(bSimpledCoder);
}
@Override
public void convertTo(W out, InetAddress value) {
if (value == null) {
@@ -70,25 +71,38 @@ public class InetAddressSimpledCoder<R extends Reader, W extends Writer> extends
public static final InetSocketAddressSimpledCoder instance = new InetSocketAddressSimpledCoder();
protected final SimpledCoder<R, W, byte[]> bsSimpledCoder;
protected InetSocketAddressSimpledCoder() {
this.bsSimpledCoder = ByteArraySimpledCoder.instance;
}
public InetSocketAddressSimpledCoder(SimpledCoder<R, W, byte[]> bSimpledCoder) {
this.bsSimpledCoder = Objects.requireNonNull(bSimpledCoder);
}
@Override
public void convertTo(W out, InetSocketAddress value) {
if (value == null) {
out.writeNull();
return;
}
ByteArraySimpledCoder.instance.convertTo(out, value.getAddress().getAddress());
out.writeInt(value.getPort());
int port = value.getPort();
byte[] bs = value.getAddress().getAddress();
bs = Utility.append(bs, (byte) ((port & 0xFF00) >> 8), (byte) (port & 0xFF));
bsSimpledCoder.convertTo(out, bs);
}
@Override
public InetSocketAddress convertFrom(R in) {
byte[] bytes = ByteArraySimpledCoder.instance.convertFrom(in);
byte[] bytes = bsSimpledCoder.convertFrom(in);
if (bytes == null) {
return null;
}
int port = in.readInt();
byte[] addr = Arrays.copyOf(bytes, bytes.length - 2);
int port = ((0xff00 & (bytes[bytes.length - 2] << 8)) | (0xff & bytes[bytes.length - 1]));
try {
return new InetSocketAddress(InetAddress.getByAddress(bytes), port);
return new InetSocketAddress(InetAddress.getByAddress(addr), port);
} catch (Exception ex) {
return null;
}

View File

@@ -27,24 +27,24 @@ public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T>
}
@Override
public void convertTo(ProtobufWriter out, @Nonnull EnMember member, T[] value) {
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, T[] value) {
this.checkInited();
if (value == null || value.length < 1) {
return;
}
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(value.length, itemEncoder, value);
boolean first = true;
for (T item : value) {
out.writeField(member);
if (!first) {
out.writeField(member);
}
if (item == null) {
out.writeLength(0);
} else if (componentSimpled) {
itemEncoder.convertTo(out, member, item);
} else {
ProtobufWriter tmp = out.pollChild();
itemEncoder.convertTo(tmp, member, item);
out.offerChild(tmp);
itemEncoder.convertTo(out, member, item);
}
first = false;
}
out.writeArrayE();
}

View File

@@ -45,6 +45,7 @@ import org.redkale.convert.ext.Uint128SimpledCoder;
import org.redkale.util.*;
/**
* SimpledCoder子类convertTo方法中都不会执行writeField/writeTag
*
* @author zhangjx
*/
@@ -798,13 +799,17 @@ public abstract class ProtobufCoders {
public static final ProtobufInetSocketAddressSimpledCoder instance =
new ProtobufInetSocketAddressSimpledCoder();
public ProtobufInetSocketAddressSimpledCoder() {
super(ProtobufByteArraySimpledCoder.instance);
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, InetSocketAddress value) {
if (value == null) {
return 0;
}
byte[] bs = value.getAddress().getAddress();
return ProtobufByteArraySimpledCoder.instance.computeSize(out, tagSize, bs);
return bs.length + 2; // port固定2字节
}
@Override

View File

@@ -27,24 +27,24 @@ public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWrit
}
@Override
public void convertTo(ProtobufWriter out, EnMember member, Collection<T> value) {
public void convertTo(final ProtobufWriter out, EnMember member, Collection<T> value) {
this.checkInited();
if (Utility.isEmpty(value)) {
return;
}
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(value.size(), itemEncoder, value);
boolean first = true;
for (T item : value) {
out.writeField(member);
if (!first) {
out.writeField(member);
}
if (item == null) {
out.writeLength(0);
} else if (componentSimpled) {
itemEncoder.convertTo(out, member, item);
} else {
ProtobufWriter tmp = out.pollChild();
itemEncoder.convertTo(tmp, member, item);
out.offerChild(tmp);
itemEncoder.convertTo(out, member, item);
}
first = false;
}
out.writeArrayE();
}

View File

@@ -49,9 +49,9 @@ public abstract class ProtobufDynEncoder<T> extends ProtobufObjectEncoder<T> {
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;
}
// if (((ProtobufObjectEncoder) selfObjEncoder).requiredMemberSize()) { // 嵌套对象
// return null;
// }
final Map<String, SimpledCoder> simpledCoders = new HashMap<>();
final Map<String, EnMember> otherMembers = new HashMap<>();
StringBuilder elementb = new StringBuilder();
@@ -159,26 +159,15 @@ public abstract class ProtobufDynEncoder<T> extends ProtobufObjectEncoder<T> {
mv.visitLineNumber(33, ifLabel);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
// 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);
// ProtobufWriter out = acceptWriter(out0, member);
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 + enMemberDesc + objectDesc + ")" + pbwriterDesc,
"acceptWriter",
"(" + pbwriterDesc + enMemberDesc + ")" + pbwriterDesc,
false);
mv.visitVarInsn(ASTORE, 4);

View File

@@ -19,6 +19,11 @@ import org.redkale.convert.Writer;
*/
public interface ProtobufEncodeable<W extends Writer, T> extends Encodeable<W, T> {
// 序列化
default void convertTo(W out, EnMember member, T value) {
convertTo(out, value);
}
// 计算内容长度
public int computeSize(ProtobufWriter out, int tagSize, T value);
@@ -27,11 +32,6 @@ public interface ProtobufEncodeable<W extends Writer, T> extends Encodeable<W, T
return false;
}
// 序列化
default void convertTo(W out, EnMember member, T value) {
convertTo(out, value);
}
// 获取数据类型枚举
public ProtobufTypeEnum typeEnum();

View File

@@ -7,7 +7,10 @@ package org.redkale.convert.pb;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import org.redkale.annotation.Nonnull;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.TypeToken;
@@ -24,6 +27,8 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
private final EnMember keyMember;
private final EnMember valueMember;
private final boolean keySimpled;
private final boolean valueSimpled;
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
super(factory, type);
@@ -33,10 +38,12 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
setTag(valueMember, ProtobufFactory.getTag(2, ((ProtobufEncodeable) valueEncoder).typeEnum()));
setTagSize(keyMember, ProtobufFactory.computeSInt32SizeNoTag(keyMember.getTag()));
setTagSize(valueMember, ProtobufFactory.computeSInt32SizeNoTag(valueMember.getTag()));
this.keySimpled = keyEncoder instanceof SimpledCoder;
this.valueSimpled = valueEncoder instanceof SimpledCoder;
}
@Override
public void convertTo(ProtobufWriter out, EnMember member, Map<K, V> value) {
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, Map<K, V> value) {
this.checkInited();
final Map<K, V> values = value;
if (Utility.isEmpty(value)) {
@@ -47,40 +54,71 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
BiFunction<K, V, V> mapFieldFunc = out.mapFieldFunc();
ProtobufEncodeable kencoder = (ProtobufEncodeable) this.keyEncoder;
ProtobufEncodeable vencoder = (ProtobufEncodeable) this.valueEncoder;
boolean keySimpled = kencoder instanceof SimpledCoder;
boolean valSimpled = vencoder instanceof SimpledCoder;
out.writeMapB(values.size(), kencoder, vencoder, value);
AtomicBoolean first = new AtomicBoolean(true);
values.forEach((key, val0) -> {
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0);
if (val != null) {
if (!first.get()) {
out.writeField(member);
ProtobufWriter tmp = out.pollChild();
if (keySimpled) {
tmp.writeField(keyMember);
kencoder.convertTo(tmp, key);
} else {
kencoder.convertTo(tmp, keyMember, key);
}
if (valSimpled) {
tmp.writeField(valueMember);
vencoder.convertTo(tmp, val);
} else {
vencoder.convertTo(tmp, valueMember, val);
}
out.offerChild(tmp);
}
ProtobufWriter subout = out.pollChild();
subout.writeTag(keyMember.getTag());
if (key == null) {
subout.writeLength(0);
} else {
kencoder.convertTo(subout, keyMember, key);
}
subout.writeTag(valueMember.getTag());
if (val == null) {
subout.writeLength(0);
} else {
vencoder.convertTo(subout, valueMember, val);
}
out.offerChild(subout);
first.set(false);
}
});
out.writeMapE();
}
protected ProtobufWriter acceptWriter(ProtobufWriter out, EnMember member) {
return member != null ? out.pollChild() : out;
}
protected void offerWriter(ProtobufWriter parent, ProtobufWriter out) {
if (parent != out) {
parent.offerChild(out);
}
}
public int computeSize(ProtobufWriter out, K key, V val) {
ProtobufEncodeable kencoder = (ProtobufEncodeable) this.keyEncoder;
ProtobufEncodeable vencoder = (ProtobufEncodeable) this.valueEncoder;
int keySize = kencoder.computeSize(out, keyMember.getTagSize(), key);
int valSize = vencoder.computeSize(out, valueMember.getTagSize(), val);
return (keySimpled ? (keyMember.getTagSize() + keySize) : keySize)
+ (valueSimpled ? (valueMember.getTagSize() + valSize) : valSize);
}
@Override
public int computeSize(ProtobufWriter out, int tagLen, Map<K, V> value) {
public int computeSize(ProtobufWriter out, int tagSize, Map<K, V> value) {
if (Utility.isEmpty(value)) {
return 0;
}
return 0;
Set<String> ignoreColumns = this.ignoreMapColumns;
BiFunction<K, V, V> mapFieldFunc = out.mapFieldFunc();
AtomicInteger size = new AtomicInteger();
value.forEach((key, val0) -> {
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0);
if (val != null) {
size.addAndGet(tagSize);
size.addAndGet(computeSize(out, key, val));
}
}
});
return size.get();
}
@Override

View File

@@ -7,6 +7,7 @@ package org.redkale.convert.pb;
import java.lang.reflect.Type;
import org.redkale.annotation.ClassDepends;
import org.redkale.annotation.Nullable;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.Utility;
@@ -30,30 +31,28 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T>
}
@Override
public void convertTo(ProtobufWriter out, EnMember parentMember, T value) {
public void convertTo(ProtobufWriter out, @Nullable EnMember member, 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);
ProtobufWriter subout = acceptWriter(out, member);
subout.writeObjectB(value);
int maxPosition = 0;
for (EnMember member : members) {
maxPosition = member.getPosition();
objout.writeObjectField(member, value);
for (EnMember fieldMember : members) {
maxPosition = fieldMember.getPosition();
subout.writeObjectField(fieldMember, value);
}
if (objout.objExtFunc() != null) {
ConvertField[] extFields = objout.objExtFunc().apply(value);
if (subout.objExtFunc() != null) {
ConvertField[] extFields = subout.objExtFunc().apply(value);
if (extFields != null) {
Encodeable<ProtobufWriter, ?> anyEncoder = factory.getAnyEncoder();
for (ConvertField en : extFields) {
if (en != null) {
maxPosition++;
objout.writeObjectField(
subout.writeObjectField(
en.getName(),
en.getType(),
Math.max(en.getPosition(), maxPosition),
@@ -63,13 +62,13 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T>
}
}
}
objout.writeObjectE(value);
offerWriter(out, objout);
subout.writeObjectE(value);
offerWriter(out, subout);
}
@ClassDepends
protected ProtobufWriter objectWriter(ProtobufWriter out, EnMember parentMember, T value) {
return parentMember != null ? out.pollChild() : out;
protected ProtobufWriter acceptWriter(ProtobufWriter out, EnMember member) {
return member != null ? out.pollChild() : out;
}
@ClassDepends
@@ -87,7 +86,8 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T>
}
Attribute attr = member.getAttribute();
boolean enumtostring = ((ProtobufFactory) factory).enumtostring;
this.memberSizeRequired |= ((ProtobufEncodeable) member.getEncoder()).requireSize();
this.memberSizeRequired |= !(member.getEncoder() instanceof SimpledCoder)
&& ((ProtobufEncodeable) member.getEncoder()).requireSize();
setTag(member, ProtobufFactory.getTag(attr.field(), attr.genericType(), member.getPosition(), enumtostring));
setTagSize(member, ProtobufFactory.computeSInt32SizeNoTag(member.getTag()));
}
@@ -107,7 +107,7 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T>
}
public boolean requiredMemberSize() {
return memberSizeRequired;
return true||memberSizeRequired;
}
@Override

View File

@@ -7,6 +7,7 @@ package org.redkale.convert.pb;
import java.lang.reflect.Type;
import java.util.stream.Stream;
import org.redkale.annotation.Nonnull;
import org.redkale.convert.*;
/**
@@ -26,7 +27,7 @@ public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T>
}
@Override
public void convertTo(ProtobufWriter out, EnMember member, Stream<T> value) {
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, Stream<T> value) {
this.checkInited();
Object[] array = value == null ? null : value.toArray();
if (array == null || array.length < 1) {
@@ -34,17 +35,17 @@ public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T>
}
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(array.length, itemEncoder, array);
boolean first = true;
for (Object item : array) {
out.writeField(member);
if (!first) {
out.writeField(member);
}
if (item == null) {
out.writeLength(0);
} else if (componentSimpled) {
itemEncoder.convertTo(out, member, item);
} else {
ProtobufWriter tmp = out.pollChild();
itemEncoder.convertTo(tmp, member, item);
out.offerChild(tmp);
itemEncoder.convertTo(out, member, item);
}
first = false;
}
out.writeArrayE();
}

View File

@@ -437,7 +437,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
@Override
public final void writeString(String value) {
byte[] bs = Utility.isLatin1(value) ? Utility.latin1ByteArray(value) : value.getBytes(StandardCharsets.UTF_8);
byte[] bs;
if (Utility.isLatin1(value)) {
bs = Utility.latin1ByteArray(value);
} else {
bs = value.getBytes(StandardCharsets.UTF_8);
}
writeLength(bs.length);
writeTo(bs);
}
@@ -1186,12 +1191,8 @@ public class ProtobufWriter extends Writer implements ByteTuple {
return;
}
ProtobufEncodeable encoder = (ProtobufEncodeable) member.getEncoder();
if (encoder instanceof SimpledCoder) {
this.writeField(member);
encoder.convertTo(this, value);
} else {
encoder.convertTo(this, member, value);
}
this.writeField(member);
encoder.convertTo(this, member, value);
}
@ClassDepends

View File

@@ -4941,6 +4941,9 @@ public final class Utility {
if (value == null) {
return -1;
}
if (value.isEmpty()) {
return 0;
}
char c;
int size = 0;
final String str = value;