This commit is contained in:
redkale
2024-10-04 11:01:49 +08:00
parent b7a604ebee
commit 5c5bce467f
12 changed files with 299 additions and 301 deletions

View File

@@ -21,10 +21,14 @@ import org.redkale.util.*;
*/
public abstract class Convert<R extends Reader, W extends Writer> {
// 值为true时 String类型值为""Boolean类型值为false时不会输出默认为false
/**
* 值为true时 (String)""(Boolean)false值不会输出默认为false
*/
public static final int FEATURE_TINY = 1 << 1;
// 值为true时 字段值为null时会输出默认为false
/**
* 值为true时 字段值为null时会输出默认为false
*/
public static final int FEATURE_NULLABLE = 1 << 2;
// 配置属性集合, 1<<1至1<<10为系统内置
@@ -42,6 +46,7 @@ public abstract class Convert<R extends Reader, W extends Writer> {
}
protected <S extends W> S configWrite(S writer) {
writer.features = features;
return writer;
}

View File

@@ -17,35 +17,41 @@ import org.redkale.convert.*;
*/
public class ProtobufArrayDecoder<T> extends ArrayDecoder<ProtobufReader, T>
implements ProtobufTagDecodeable<ProtobufReader, T[]> {
protected final boolean componentPrimitived;
protected final boolean componentSimpled;
public ProtobufArrayDecoder(ProtobufFactory factory, Type type) {
public ProtobufArrayDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentDecoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
}
@Override
public T[] convertFrom(ProtobufReader in, DeMember member) {
this.checkInited();
final boolean simpled = this.componentSimpled;
if (componentPrimitived) {
return convertPrimitivedFrom(in, member);
} else if (componentSimpled) {
return convertSimpledFrom(in, member);
} else {
return convertObjectFrom(in, member);
}
}
protected T[] convertObjectFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final List<T> result = new ArrayList();
final int limit = in.limit();
while (in.hasNext()) {
boolean nodata = false;
if (!simpled) {
int contentLen = in.readRawVarint32();
if (contentLen == 0) {
nodata = true;
} else {
in.limit(in.position() + contentLen + 1);
}
}
if (nodata) {
// 读长度
int contentLen = in.readRawVarint32();
// 读数据
if (contentLen == 0) {
result.add(null);
} else {
in.limit(in.position() + contentLen + 1);
result.add(itemDecoder.convertFrom(in));
in.limit(limit);
}
@@ -54,7 +60,36 @@ public class ProtobufArrayDecoder<T> extends ArrayDecoder<ProtobufReader, T>
}
}
in.readArrayE();
T[] rs = this.componentArrayFunction.apply(result.size());
return result.toArray(rs);
T[] data = this.componentArrayFunction.apply(result.size());
return result.toArray(data);
}
protected T[] convertSimpledFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final List<T> result = new ArrayList();
while (in.hasNext()) {
// 读数据
result.add(itemDecoder.convertFrom(in));
if (!in.readNextTag(member)) { // 元素结束
break;
}
}
in.readArrayE();
T[] data = this.componentArrayFunction.apply(result.size());
return result.toArray(data);
}
protected T[] convertPrimitivedFrom(ProtobufReader in, DeMember member) {
ProtobufPrimitivable<T> primCoder = (ProtobufPrimitivable) this.componentDecoder;
List<T> result = new ArrayList<>();
int len = in.readRawVarint32();
while (len > 0) {
T val = primCoder.convertFrom(in);
len -= primCoder.computeSize(val);
result.add(val);
}
T[] data = this.componentArrayFunction.apply(result.size());
return result.toArray(data);
}
}

View File

@@ -17,21 +17,30 @@ import org.redkale.convert.*;
public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T>
implements ProtobufEncodeable<ProtobufWriter, T[]> {
protected final boolean componentSimpled;
protected final boolean componentSizeRequired;
protected final boolean componentPrimitived;
public ProtobufArrayEncoder(ProtobufFactory factory, Type type) {
protected final boolean componentSimpled;
public ProtobufArrayEncoder(ConvertFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentEncoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentEncoder() instanceof SimpledCoder;
this.componentSizeRequired = !(getComponentEncoder() instanceof ProtobufPrimitivable);
}
@Override
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, T[] value) {
this.checkInited();
if (value == null || value.length < 1) {
if (value == null || value.length == 0) {
return;
}
if (componentPrimitived) {
convertPrimitivedTo(out, member, value);
} else {
convertObjectTo(out, member, value);
}
}
protected void convertObjectTo(final ProtobufWriter out, @Nonnull EnMember member, T[] value) {
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(value.length, itemEncoder, value);
boolean first = true;
@@ -49,25 +58,38 @@ public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T>
out.writeArrayE();
}
protected void convertPrimitivedTo(final ProtobufWriter out, @Nonnull EnMember member, T[] value) {
out.writeLength(computeSize(out, 0, value));
Encodeable itemCoder = getComponentEncoder();
for (T item : value) {
itemCoder.convertTo(out, item);
}
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, T[] value) {
if (value == null || value.length < 1) {
if (value == null || value.length == 0) {
return 0;
}
int dataSize = 0;
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
for (T item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
if (componentPrimitived) {
int dataSize = 0;
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return dataSize;
} else {
int dataSize = tagSize * value.length;
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize;
}
if (componentSizeRequired) {
dataSize += tagSize * value.length;
}
return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize;
}
@Override
public boolean requireSize() {
return !componentSimpled;
return !componentPrimitived;
}
@Override

View File

@@ -11,7 +11,6 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.function.IntFunction;
import java.util.stream.Stream;
import org.redkale.convert.SimpledCoder;
import org.redkale.convert.ext.AtomicBooleanSimpledCoder;
@@ -879,193 +878,6 @@ public abstract class ProtobufCoders {
}
}
public static class ProtobufPrimitiveArraySimpledCoder<T> extends SimpledCoder<ProtobufReader, ProtobufWriter, T[]>
implements ProtobufEncodeable<ProtobufWriter, T[]> {
private final IntFunction<T[]> arrayFunc;
private final SimpledCoder<ProtobufReader, ProtobufWriter, T> componentCoder;
public ProtobufPrimitiveArraySimpledCoder(ProtobufPrimitivable primitiveCoder) {
this.componentCoder = (SimpledCoder) primitiveCoder;
this.arrayFunc = Creator.funcArray(TypeToken.typeToClass(this.componentCoder.getType()));
}
@Override
public void convertTo(ProtobufWriter out, T[] value) {
if (value == null || value.length == 0) {
return;
}
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
T[] array = value;
int len = 0;
for (T item : array) {
len += primCoder.computeSize(item == null ? 0 : item);
}
out.writeLength(len);
for (T item : array) {
itemCoder.convertTo(out, item);
}
}
@Override
public T[] convertFrom(ProtobufReader in) {
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
List<T> data = new ArrayList<>();
int len = in.readRawVarint32();
while (len > 0) {
T val = itemCoder.convertFrom(in);
len -= primCoder.computeSize(val);
data.add(val);
}
return data.toArray(this.arrayFunc);
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, T[] value) {
if (value == null || value.length == 0) {
return 0;
}
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) this.componentCoder;
int len = 0;
for (T item : value) {
len += primCoder.computeSize(item);
}
return len;
}
@Override
public final ProtobufTypeEnum typeEnum() {
return ProtobufTypeEnum.BYTES;
}
}
public static class ProtobufPrimitiveCollectionSimpledCoder<T>
extends SimpledCoder<ProtobufReader, ProtobufWriter, Collection<T>>
implements ProtobufEncodeable<ProtobufWriter, Collection<T>> {
private final Creator<? extends Collection> creator;
private final SimpledCoder<ProtobufReader, ProtobufWriter, T> componentCoder;
public ProtobufPrimitiveCollectionSimpledCoder(
Creator<? extends Collection> creator, ProtobufPrimitivable primitiveCoder) {
this.creator = creator;
this.componentCoder = (SimpledCoder) primitiveCoder;
}
@Override
public void convertTo(ProtobufWriter out, Collection<T> values) {
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
Collection<T> array = values;
if (array != null && !array.isEmpty()) {
int len = 0;
for (T item : array) {
len += primCoder.computeSize(item == null ? 0 : item);
}
out.writeLength(len);
for (T item : array) {
itemCoder.convertTo(out, item);
}
}
}
@Override
public Collection<T> convertFrom(ProtobufReader in) {
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
Collection<T> data = creator.create();
int len = in.readRawVarint32();
while (len > 0) {
T val = itemCoder.convertFrom(in);
len -= primCoder.computeSize(val);
data.add(val);
}
return data;
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, Collection<T> value) {
if (value == null || value.isEmpty()) {
return 0;
}
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) this.componentCoder;
int len = 0;
for (T item : value) {
len += primCoder.computeSize(item);
}
return len;
}
@Override
public final ProtobufTypeEnum typeEnum() {
return ProtobufTypeEnum.BYTES;
}
}
public static class ProtobufPrimitiveStreamSimpledCoder<T>
extends SimpledCoder<ProtobufReader, ProtobufWriter, Stream<T>>
implements ProtobufEncodeable<ProtobufWriter, Stream<T>> {
private final SimpledCoder<ProtobufReader, ProtobufWriter, T> componentCoder;
public ProtobufPrimitiveStreamSimpledCoder(ProtobufPrimitivable primitiveCoder) {
this.componentCoder = (SimpledCoder) primitiveCoder;
}
@Override
public void convertTo(ProtobufWriter out, Stream<T> value) {
if (value == null) {
return;
}
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
Object[] array = value.toArray();
int len = 0;
for (Object item : array) {
len += primCoder.computeSize(item == null ? 0 : item);
}
out.writeLength(len);
for (Object item : array) {
itemCoder.convertTo(out, (T) item);
}
}
@Override
public Stream<T> convertFrom(ProtobufReader in) {
SimpledCoder<ProtobufReader, ProtobufWriter, T> itemCoder = this.componentCoder;
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) itemCoder;
List<T> data = new ArrayList<>();
int len = in.readRawVarint32();
while (len > 0) {
T val = itemCoder.convertFrom(in);
len -= primCoder.computeSize(val);
data.add(val);
}
return data.stream();
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, Stream<T> value) {
if (value == null) {
return 0;
}
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) this.componentCoder;
int len = 0;
for (Object item : value.toArray()) {
len += primCoder.computeSize(item);
}
return len;
}
@Override
public final ProtobufTypeEnum typeEnum() {
return ProtobufTypeEnum.BYTES;
}
}
// ------------------------------------- boolean[] -------------------------------------
public static class ProtobufBoolArraySimpledCoder extends SimpledCoder<ProtobufReader, ProtobufWriter, boolean[]>
implements ProtobufEncodeable<ProtobufWriter, boolean[]> {

View File

@@ -18,34 +18,41 @@ import org.redkale.convert.*;
public class ProtobufCollectionDecoder<T> extends CollectionDecoder<ProtobufReader, T>
implements ProtobufTagDecodeable<ProtobufReader, Collection<T>> {
protected final boolean componentPrimitived;
protected final boolean componentSimpled;
public ProtobufCollectionDecoder(ProtobufFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentDecoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
}
@Override
public Collection<T> convertFrom(ProtobufReader in, DeMember member) {
this.checkInited();
final boolean simpled = this.componentSimpled;
if (componentPrimitived) {
return convertPrimitivedFrom(in, member);
} else if (componentSimpled) {
return convertSimpledFrom(in, member);
} else {
return convertObjectFrom(in, member);
}
}
protected Collection<T> convertObjectFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final Collection<T> result = this.creator.create();
final int limit = in.limit();
while (in.hasNext()) {
boolean nodata = false;
if (!simpled) {
int contentLen = in.readRawVarint32();
if (contentLen == 0) {
nodata = true;
} else {
in.limit(in.position() + contentLen + 1);
}
}
if (nodata) {
// 读长度
int contentLen = in.readRawVarint32();
// 读数据
if (contentLen == 0) {
result.add(null);
} else {
in.limit(in.position() + contentLen + 1);
result.add(itemDecoder.convertFrom(in));
in.limit(limit);
}
@@ -56,4 +63,31 @@ public class ProtobufCollectionDecoder<T> extends CollectionDecoder<ProtobufRead
in.readArrayE();
return result;
}
protected Collection<T> convertSimpledFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final Collection<T> result = this.creator.create();
while (in.hasNext()) {
// 读数据
result.add(itemDecoder.convertFrom(in));
if (!in.readNextTag(member)) { // 元素结束
break;
}
}
in.readArrayE();
return result;
}
protected Collection<T> convertPrimitivedFrom(ProtobufReader in, DeMember member) {
ProtobufPrimitivable<T> primCoder = (ProtobufPrimitivable) this.componentDecoder;
Collection<T> result = this.creator.create();
int len = in.readRawVarint32();
while (len > 0) {
T val = primCoder.convertFrom(in);
len -= primCoder.computeSize(val);
result.add(val);
}
return result;
}
}

View File

@@ -7,8 +7,8 @@ package org.redkale.convert.pb;
import java.lang.reflect.Type;
import java.util.Collection;
import org.redkale.annotation.Nonnull;
import org.redkale.convert.*;
import org.redkale.util.Utility;
/**
* @author zhangjx
@@ -17,21 +17,30 @@ import org.redkale.util.Utility;
public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWriter, T>
implements ProtobufEncodeable<ProtobufWriter, Collection<T>> {
protected final boolean componentSimpled;
protected final boolean componentSizeRequired;
protected final boolean componentPrimitived;
public ProtobufCollectionEncoder(ProtobufFactory factory, Type type) {
protected final boolean componentSimpled;
public ProtobufCollectionEncoder(ConvertFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentEncoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentEncoder() instanceof SimpledCoder;
this.componentSizeRequired = !(getComponentEncoder() instanceof ProtobufPrimitivable);
}
@Override
public void convertTo(final ProtobufWriter out, EnMember member, Collection<T> value) {
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, Collection<T> value) {
this.checkInited();
if (Utility.isEmpty(value)) {
if (value == null || value.isEmpty()) {
return;
}
if (componentPrimitived) {
convertPrimitivedTo(out, member, value);
} else {
convertObjectTo(out, member, value);
}
}
protected void convertObjectTo(final ProtobufWriter out, @Nonnull EnMember member, Collection<T> value) {
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(value.size(), itemEncoder, value);
boolean first = true;
@@ -49,25 +58,38 @@ public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWrit
out.writeArrayE();
}
protected void convertPrimitivedTo(final ProtobufWriter out, @Nonnull EnMember member, Collection<T> value) {
out.writeLength(computeSize(out, 0, value));
Encodeable itemCoder = getComponentEncoder();
for (T item : value) {
itemCoder.convertTo(out, item);
}
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, Collection<T> 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 (componentPrimitived) {
int dataSize = 0;
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return dataSize;
} else {
int dataSize = tagSize * value.size();
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize;
}
if (componentSizeRequired) {
dataSize += tagSize * value.size();
}
return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize;
}
@Override
public boolean requireSize() {
return !componentSimpled;
return !componentPrimitived;
}
@Override

View File

@@ -214,13 +214,6 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
} else if (componentType == Double.class) {
Creator<? extends Collection> creator = loadCreator(createClazz);
return (Decodeable) new ProtobufCoders.ProtobufDoubleCollectionSimpledCoder(creator);
} else {
Decodeable componentCoder = findDecoder(componentType);
if (componentCoder instanceof ProtobufPrimitivable) {
Creator<? extends Collection> creator = loadCreator(createClazz);
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) componentCoder;
return (Decodeable) new ProtobufCoders.ProtobufPrimitiveCollectionSimpledCoder(creator, primCoder);
}
}
return new ProtobufCollectionDecoder(this, type);
}
@@ -245,12 +238,6 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
return (Encodeable) new ProtobufCoders.ProtobufLongCollectionSimpledCoder(creator);
} else if (componentType == Double.class) {
return (Encodeable) new ProtobufCoders.ProtobufDoubleCollectionSimpledCoder(creator);
} else {
Encodeable componentCoder = findEncoder(componentType);
if (componentCoder instanceof ProtobufPrimitivable) {
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) componentCoder;
return (Encodeable) new ProtobufCoders.ProtobufPrimitiveCollectionSimpledCoder(creator, primCoder);
}
}
return new ProtobufCollectionEncoder(this, type);
}
@@ -274,12 +261,6 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
return (Decodeable) ProtobufCoders.ProtobufLongStreamSimpledCoder.instance;
} else if (componentType == Double.class) {
return (Decodeable) ProtobufCoders.ProtobufDoubleStreamSimpledCoder.instance;
} else {
Decodeable componentCoder = findDecoder(componentType);
if (componentCoder instanceof ProtobufPrimitivable) {
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) componentCoder;
return (Decodeable) new ProtobufCoders.ProtobufPrimitiveStreamSimpledCoder(primCoder);
}
}
return new ProtobufStreamDecoder(this, type);
}
@@ -303,12 +284,6 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
return (Encodeable) ProtobufCoders.ProtobufLongStreamSimpledCoder.instance;
} else if (componentType == Double.class) {
return (Encodeable) ProtobufCoders.ProtobufDoubleStreamSimpledCoder.instance;
} else {
Encodeable componentCoder = findEncoder(componentType);
if (componentCoder instanceof ProtobufPrimitivable) {
ProtobufPrimitivable primCoder = (ProtobufPrimitivable) componentCoder;
return (Encodeable) new ProtobufCoders.ProtobufPrimitiveStreamSimpledCoder(primCoder);
}
}
return new ProtobufStreamEncoder(this, type);
}

View File

@@ -57,7 +57,7 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
out.writeMapB(values.size(), kencoder, vencoder, value);
AtomicBoolean first = new AtomicBoolean(true);
values.forEach((key, val0) -> {
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
if (ignoreColumns == null || !ignoreColumns.contains(key.toString())) {
V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0);
if (!first.get()) {
out.writeField(member);
@@ -82,16 +82,6 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
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;
@@ -110,7 +100,7 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
BiFunction<K, V, V> mapFieldFunc = out.mapFieldFunc();
AtomicInteger size = new AtomicInteger();
value.forEach((key, val0) -> {
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
if (ignoreColumns == null || !ignoreColumns.contains(key.toString())) {
V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0);
if (val != null) {
size.addAndGet(tagSize);

View File

@@ -4,12 +4,15 @@
*/
package org.redkale.convert.pb;
import org.redkale.convert.Decodeable;
import org.redkale.convert.Encodeable;
/**
* 只能用于基本类型, 不能用于如String的其他类型
* @author zhangjx
* @param <T> 基本类型泛型
*/
public interface ProtobufPrimitivable<T> {
public interface ProtobufPrimitivable<T> extends Decodeable<ProtobufReader, T>, Encodeable<ProtobufWriter, T> {
// 获取java类型分类
public Class primitiveType();

View File

@@ -17,34 +17,41 @@ import org.redkale.convert.*;
public class ProtobufStreamDecoder<T> extends StreamDecoder<ProtobufReader, T>
implements ProtobufTagDecodeable<ProtobufReader, Stream<T>> {
protected final boolean componentPrimitived;
protected final boolean componentSimpled;
public ProtobufStreamDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentDecoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentDecoder() instanceof SimpledCoder;
}
@Override
public Stream<T> convertFrom(ProtobufReader in, DeMember member) {
this.checkInited();
final boolean simpled = this.componentSimpled;
if (componentPrimitived) {
return convertPrimitivedFrom(in, member);
} else if (componentSimpled) {
return convertSimpledFrom(in, member);
} else {
return convertObjectFrom(in, member);
}
}
protected Stream<T> convertObjectFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final List<T> result = new ArrayList();
final int limit = in.limit();
while (in.hasNext()) {
boolean nodata = false;
if (!simpled) {
int contentLen = in.readRawVarint32();
if (contentLen == 0) {
nodata = true;
} else {
in.limit(in.position() + contentLen + 1);
}
}
if (nodata) {
// 读长度
int contentLen = in.readRawVarint32();
// 读数据
if (contentLen == 0) {
result.add(null);
} else {
in.limit(in.position() + contentLen + 1);
result.add(itemDecoder.convertFrom(in));
in.limit(limit);
}
@@ -55,4 +62,31 @@ public class ProtobufStreamDecoder<T> extends StreamDecoder<ProtobufReader, T>
in.readArrayE();
return result.stream();
}
protected Stream<T> convertSimpledFrom(ProtobufReader in, DeMember member) {
final Decodeable<ProtobufReader, T> itemDecoder = this.componentDecoder;
in.readArrayB(itemDecoder);
final List<T> result = new ArrayList();
while (in.hasNext()) {
// 读数据
result.add(itemDecoder.convertFrom(in));
if (!in.readNextTag(member)) { // 元素结束
break;
}
}
in.readArrayE();
return result.stream();
}
protected Stream<T> convertPrimitivedFrom(ProtobufReader in, DeMember member) {
ProtobufPrimitivable<T> primCoder = (ProtobufPrimitivable) this.componentDecoder;
List<T> result = new ArrayList<>();
int len = in.readRawVarint32();
while (len > 0) {
T val = primCoder.convertFrom(in);
len -= primCoder.computeSize(val);
result.add(val);
}
return result.stream();
}
}

View File

@@ -17,26 +17,35 @@ import org.redkale.convert.*;
public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T>
implements ProtobufEncodeable<ProtobufWriter, Stream<T>> {
protected final boolean componentPrimitived;
protected final boolean componentSimpled;
protected final boolean componentSizeRequired;
public ProtobufStreamEncoder(ConvertFactory factory, Type type) {
super(factory, type);
this.componentPrimitived = getComponentEncoder() instanceof ProtobufPrimitivable;
this.componentSimpled = getComponentEncoder() instanceof SimpledCoder;
this.componentSizeRequired = !(getComponentEncoder() instanceof ProtobufPrimitivable);
}
@Override
public void convertTo(final ProtobufWriter out, @Nonnull EnMember member, Stream<T> value) {
this.checkInited();
Object[] array = value == null ? null : value.toArray();
Object[] array = out.getStreamArray(value);
if (array == null || array.length < 1) {
return;
}
if (componentPrimitived) {
convertPrimitivedTo(out, member, array);
} else {
convertObjectTo(out, member, array);
}
}
protected void convertObjectTo(final ProtobufWriter out, @Nonnull EnMember member, Object[] value) {
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
out.writeArrayB(array.length, itemEncoder, array);
out.writeArrayB(value.length, itemEncoder, value);
boolean first = true;
for (Object item : array) {
for (Object item : value) {
if (!first) {
out.writeField(member);
}
@@ -50,15 +59,43 @@ public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T>
out.writeArrayE();
}
protected void convertPrimitivedTo(final ProtobufWriter out, @Nonnull EnMember member, Object[] value) {
out.writeLength(computeSize(out, 0, value));
Encodeable itemCoder = getComponentEncoder();
for (Object item : value) {
itemCoder.convertTo(out, (T) item);
}
}
@Override
public int computeSize(ProtobufWriter out, int tagSize, Stream<T> value) {
// Stream被forEach之后就不可用了 所以不能进行遍历
throw new UnsupportedOperationException("Not supported yet.");
Object[] array = out.putStreamArray(value);
if (array == null || array.length < 1) {
return 0;
}
return computeSize(out, tagSize, array);
}
protected int computeSize(ProtobufWriter out, int tagSize, Object[] value) {
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
if (componentPrimitived) {
int dataSize = 0;
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return dataSize;
} else {
int dataSize = tagSize * value.length;
for (Object item : value) {
dataSize += itemEncoder.computeSize(out, tagSize, item);
}
return ProtobufFactory.computeSInt32SizeNoTag(dataSize) + dataSize;
}
}
@Override
public boolean requireSize() {
return !componentSimpled;
return !componentPrimitived;
}
@Override

View File

@@ -70,6 +70,8 @@ public abstract class ProtobufWriter extends Writer {
protected ProtobufBytesWriter child;
protected Map<Stream, Object[]> streamArrayCache;
protected ProtobufWriter() {}
@Override
@@ -111,6 +113,7 @@ public abstract class ProtobufWriter extends Writer {
this.features = 0;
this.enumtostring = false;
this.count = 0;
this.streamArrayCache = null;
return true;
}
@@ -138,6 +141,32 @@ public abstract class ProtobufWriter extends Writer {
return count;
}
public final @Nullable Object[] putStreamArray(Stream stream) {
if (stream == null) {
return null;
}
if (this.streamArrayCache == null) {
this.streamArrayCache = new HashMap<>();
}
Object[] rs = stream.toArray();
this.streamArrayCache.put(stream, rs);
return rs;
}
public final @Nullable Object[] getStreamArray(Stream stream) {
if (stream == null) {
return null;
}
if (this.streamArrayCache == null) {
return stream.toArray();
}
Object[] rs = this.streamArrayCache.get(stream);
if (rs == null) {
rs = stream.toArray();
}
return rs;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "@" + Objects.hashCode(this) + "[count=" + this.count + "]";