pb
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]> {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 + "]";
|
||||
|
||||
Reference in New Issue
Block a user