protobuf
This commit is contained in:
@@ -62,7 +62,7 @@ public final class EnMember<W extends Writer, T, F> {
|
|||||||
// 主要给protobuf使用 tag的大小
|
// 主要给protobuf使用 tag的大小
|
||||||
int tagSize;
|
int tagSize;
|
||||||
|
|
||||||
public EnMember(Attribute<T, F> attribute, int tag, Encodeable<W, F> encoder) {
|
public EnMember(Attribute<T, F> attribute, Encodeable<W, F> encoder) {
|
||||||
this.attribute = attribute;
|
this.attribute = attribute;
|
||||||
this.encoder = encoder;
|
this.encoder = encoder;
|
||||||
Class t = attribute.type();
|
Class t = attribute.type();
|
||||||
|
|||||||
@@ -162,4 +162,21 @@ public class MapDecoder<R extends Reader, K, V> implements Decodeable<R, Map<K,
|
|||||||
public Decodeable<R, V> getValueDecoder() {
|
public Decodeable<R, V> getValueDecoder() {
|
||||||
return valueDecoder;
|
return valueDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
protected void setTag(DeMember member, int tag) {
|
||||||
|
member.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setTagSize(DeMember member, int tagSize) {
|
||||||
|
member.tagSize = tagSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setIndex(DeMember member, int index) {
|
||||||
|
member.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPosition(DeMember member, int position) {
|
||||||
|
member.position = position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,4 +140,21 @@ public class MapEncoder<W extends Writer, K, V> implements Encodeable<W, Map<K,
|
|||||||
public Encodeable<W, V> getValueEncoder() {
|
public Encodeable<W, V> getValueEncoder() {
|
||||||
return valueEncoder;
|
return valueEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
protected void setTag(EnMember member, int tag) {
|
||||||
|
member.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setTagSize(EnMember member, int tagSize) {
|
||||||
|
member.tagSize = tagSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setIndex(EnMember member, int index) {
|
||||||
|
member.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPosition(EnMember member, int position) {
|
||||||
|
member.position = position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ public abstract class Writer {
|
|||||||
*
|
*
|
||||||
* @param member 字段
|
* @param member 字段
|
||||||
*/
|
*/
|
||||||
public final void writeField(final EnMember member) {
|
public void writeField(final EnMember member) {
|
||||||
Attribute attr = member.getAttribute();
|
Attribute attr = member.getAttribute();
|
||||||
this.writeField(member, attr.field(), attr.genericType(), member.getPosition());
|
this.writeField(member, attr.field(), attr.genericType(), member.getPosition());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,8 @@ public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Encodeable itemEncoder = this.componentEncoder;
|
Encodeable itemEncoder = this.componentEncoder;
|
||||||
T[] array = value;
|
out.writeArrayB(value.length, itemEncoder, value);
|
||||||
// if (componentSizeRequired) {
|
for (T item : value) {
|
||||||
// int tagSize = ProtobufFactory.computeSInt32SizeNoTag(member.getTag());
|
|
||||||
// out.writeLength(computeSize(tagSize, value));
|
|
||||||
// }
|
|
||||||
out.writeArrayB(array.length, itemEncoder, array);
|
|
||||||
for (T item : array) {
|
|
||||||
out.writeField(member);
|
out.writeField(member);
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
out.writeLength(0);
|
out.writeLength(0);
|
||||||
@@ -48,7 +43,6 @@ public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T>
|
|||||||
} else {
|
} else {
|
||||||
ProtobufWriter tmp = out.pollChild();
|
ProtobufWriter tmp = out.pollChild();
|
||||||
itemEncoder.convertTo(tmp, item);
|
itemEncoder.convertTo(tmp, item);
|
||||||
out.writeTuple(tmp);
|
|
||||||
out.offerChild(tmp);
|
out.offerChild(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,31 @@ public class ProtobufByteBufferWriter extends ProtobufWriter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ProtobufWriter pollChild() {
|
||||||
|
ProtobufWriter rs = super.pollChild();
|
||||||
|
this.delegate = null;
|
||||||
|
this.child = null;
|
||||||
|
rs.parent = null;
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void offerChild(ProtobufWriter child) {
|
||||||
|
int total = child.length();
|
||||||
|
ProtobufWriter next = child;
|
||||||
|
while ((next = next.child) != null) {
|
||||||
|
total += next.length();
|
||||||
|
}
|
||||||
|
writeLength(total);
|
||||||
|
writeTo(child.content(), 0, child.length());
|
||||||
|
next = child;
|
||||||
|
while ((next = next.child) != null) {
|
||||||
|
writeTo(next.content(), 0, next.length());
|
||||||
|
}
|
||||||
|
offerPool(child);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer[] toBuffers() {
|
public ByteBuffer[] toBuffers() {
|
||||||
if (buffers == null) {
|
if (buffers == null) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.redkale.convert.pb;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
@@ -28,14 +29,10 @@ public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWrit
|
|||||||
@Override
|
@Override
|
||||||
public void convertTo(ProtobufWriter out, EnMember member, Collection<T> value) {
|
public void convertTo(ProtobufWriter out, EnMember member, Collection<T> value) {
|
||||||
this.checkInited();
|
this.checkInited();
|
||||||
if (value == null || value.isEmpty()) {
|
if (Utility.isEmpty(value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
|
ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder;
|
||||||
// if (componentSizeRequired) {
|
|
||||||
// int tagSize = ProtobufFactory.computeSInt32SizeNoTag(member.getTag());
|
|
||||||
// out.writeLength(computeSize(tagSize, value));
|
|
||||||
// }
|
|
||||||
out.writeArrayB(value.size(), itemEncoder, value);
|
out.writeArrayB(value.size(), itemEncoder, value);
|
||||||
for (T item : value) {
|
for (T item : value) {
|
||||||
out.writeField(member);
|
out.writeField(member);
|
||||||
@@ -46,7 +43,6 @@ public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWrit
|
|||||||
} else {
|
} else {
|
||||||
ProtobufWriter tmp = out.pollChild();
|
ProtobufWriter tmp = out.pollChild();
|
||||||
itemEncoder.convertTo(tmp, item);
|
itemEncoder.convertTo(tmp, item);
|
||||||
out.writeTuple(tmp);
|
|
||||||
out.offerChild(tmp);
|
out.offerChild(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.redkale.convert.pb;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
|
import static org.redkale.convert.pb.ProtobufMapEncoder.createAttribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhangjx
|
* @author zhangjx
|
||||||
@@ -19,9 +20,19 @@ public class ProtobufMapDecoder<K, V> extends MapDecoder<ProtobufReader, K, V>
|
|||||||
|
|
||||||
protected final boolean enumtostring;
|
protected final boolean enumtostring;
|
||||||
|
|
||||||
|
protected final DeMember keyMember;
|
||||||
|
|
||||||
|
protected final DeMember valueMember;
|
||||||
|
|
||||||
public ProtobufMapDecoder(ConvertFactory factory, Type type) {
|
public ProtobufMapDecoder(ConvertFactory factory, Type type) {
|
||||||
super(factory, type);
|
super(factory, type);
|
||||||
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
|
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
|
||||||
|
int keyTag = ProtobufFactory.getTag(1, ((ProtobufEncodeable) keyDecoder).typeEnum());
|
||||||
|
int valTag = ProtobufFactory.getTag(2, ((ProtobufEncodeable) valueDecoder).typeEnum());
|
||||||
|
this.keyMember = new DeMember(createAttribute("key", keyDecoder.getType()), keyTag, keyDecoder);
|
||||||
|
this.valueMember = new DeMember(createAttribute("value", valueDecoder.getType()), valTag, valueDecoder);
|
||||||
|
setTagSize(keyMember, ProtobufFactory.computeSInt32SizeNoTag(keyMember.getTag()));
|
||||||
|
setTagSize(valueMember, ProtobufFactory.computeSInt32SizeNoTag(valueMember.getTag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -35,9 +46,9 @@ public class ProtobufMapDecoder<K, V> extends MapDecoder<ProtobufReader, K, V>
|
|||||||
while (in.hasNext()) {
|
while (in.hasNext()) {
|
||||||
int contentLen = in.readRawVarint32();
|
int contentLen = in.readRawVarint32();
|
||||||
in.limit(in.position() + contentLen + 1);
|
in.limit(in.position() + contentLen + 1);
|
||||||
in.readTag();
|
in.readTag(); // key tag
|
||||||
K key = kdecoder.convertFrom(in);
|
K key = kdecoder.convertFrom(in);
|
||||||
in.readTag();
|
in.readTag(); // value tag
|
||||||
V value = vdecoder.convertFrom(in);
|
V value = vdecoder.convertFrom(in);
|
||||||
result.put(key, value);
|
result.put(key, value);
|
||||||
in.limit(limit);
|
in.limit(limit);
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import java.lang.reflect.Type;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
|
import org.redkale.util.Attribute;
|
||||||
|
import org.redkale.util.TypeToken;
|
||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,13 +21,18 @@ import org.redkale.util.Utility;
|
|||||||
public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
|
public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
|
||||||
implements ProtobufEncodeable<ProtobufWriter, Map<K, V>> {
|
implements ProtobufEncodeable<ProtobufWriter, Map<K, V>> {
|
||||||
|
|
||||||
private final int keyTag;
|
private final EnMember keyMember;
|
||||||
private final int valTag;
|
|
||||||
|
private final EnMember valueMember;
|
||||||
|
|
||||||
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
|
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
|
||||||
super(factory, type);
|
super(factory, type);
|
||||||
this.keyTag = ProtobufFactory.getTag(1, ((ProtobufEncodeable) keyEncoder).typeEnum());
|
this.keyMember = new EnMember(createAttribute("key", keyEncoder.getType()), keyEncoder);
|
||||||
this.valTag = ProtobufFactory.getTag(2, ((ProtobufEncodeable) valueEncoder).typeEnum());
|
this.valueMember = new EnMember(createAttribute("value", valueEncoder.getType()), valueEncoder);
|
||||||
|
setTag(keyMember, ProtobufFactory.getTag(1, ((ProtobufEncodeable) keyEncoder).typeEnum()));
|
||||||
|
setTag(valueMember, ProtobufFactory.getTag(2, ((ProtobufEncodeable) valueEncoder).typeEnum()));
|
||||||
|
setTagSize(keyMember, ProtobufFactory.computeSInt32SizeNoTag(keyMember.getTag()));
|
||||||
|
setTagSize(valueMember, ProtobufFactory.computeSInt32SizeNoTag(valueMember.getTag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,22 +45,29 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
|
|||||||
}
|
}
|
||||||
Set<String> ignoreColumns = this.ignoreMapColumns;
|
Set<String> ignoreColumns = this.ignoreMapColumns;
|
||||||
BiFunction<K, V, V> mapFieldFunc = out.mapFieldFunc();
|
BiFunction<K, V, V> mapFieldFunc = out.mapFieldFunc();
|
||||||
Encodeable kencoder = this.keyEncoder;
|
ProtobufEncodeable kencoder = (ProtobufEncodeable) this.keyEncoder;
|
||||||
Encodeable vencoder = this.valueEncoder;
|
ProtobufEncodeable vencoder = (ProtobufEncodeable) this.valueEncoder;
|
||||||
|
boolean keySimpled = kencoder instanceof SimpledCoder;
|
||||||
|
boolean valSimpled = vencoder instanceof SimpledCoder;
|
||||||
out.writeMapB(values.size(), kencoder, vencoder, value);
|
out.writeMapB(values.size(), kencoder, vencoder, value);
|
||||||
values.forEach((key, val) -> {
|
values.forEach((key, val0) -> {
|
||||||
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
|
if (ignoreColumns == null || !ignoreColumns.contains(key)) {
|
||||||
V v = mapFieldFunc == null ? val : mapFieldFunc.apply(key, val);
|
V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0);
|
||||||
if (v != null) {
|
if (val != null) {
|
||||||
out.writeField(member);
|
out.writeField(member);
|
||||||
|
|
||||||
ProtobufWriter tmp = out.pollChild();
|
ProtobufWriter tmp = out.pollChild();
|
||||||
tmp.writeTag(keyTag);
|
if (keySimpled) {
|
||||||
kencoder.convertTo(tmp, key);
|
tmp.writeField(keyMember);
|
||||||
tmp.writeTag(valTag);
|
kencoder.convertTo(tmp, key);
|
||||||
vencoder.convertTo(tmp, v);
|
} else {
|
||||||
|
kencoder.convertTo(tmp, keyMember, key);
|
||||||
out.writeTuple(tmp);
|
}
|
||||||
|
if (valSimpled) {
|
||||||
|
tmp.writeField(valueMember);
|
||||||
|
vencoder.convertTo(tmp, val);
|
||||||
|
} else {
|
||||||
|
vencoder.convertTo(tmp, valueMember, val);
|
||||||
|
}
|
||||||
out.offerChild(tmp);
|
out.offerChild(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,4 +92,8 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V>
|
|||||||
public final ProtobufTypeEnum typeEnum() {
|
public final ProtobufTypeEnum typeEnum() {
|
||||||
return ProtobufTypeEnum.BYTES;
|
return ProtobufTypeEnum.BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Attribute createAttribute(String field, Type type) {
|
||||||
|
return Attribute.create(Map.class, field, TypeToken.typeToClass(type), type, null, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,13 +69,7 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T>
|
|||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
protected ProtobufWriter objectWriter(ProtobufWriter out, EnMember parentMember, T value) {
|
protected ProtobufWriter objectWriter(ProtobufWriter out, EnMember parentMember, T value) {
|
||||||
// if (parentMember != null) {
|
return parentMember != null ? out.pollChild() : out;
|
||||||
// out.writeLength(computeSize(out, parentMember.getTagSize(), value));
|
|
||||||
// }
|
|
||||||
if (out.length() > out.initOffset) {
|
|
||||||
return out.pollChild().configParentFunc(out);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T>
|
|||||||
} else {
|
} else {
|
||||||
ProtobufWriter tmp = out.pollChild();
|
ProtobufWriter tmp = out.pollChild();
|
||||||
itemEncoder.convertTo(tmp, item);
|
itemEncoder.convertTo(tmp, item);
|
||||||
out.writeTuple(tmp);
|
|
||||||
out.offerChild(tmp);
|
out.offerChild(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
"redkale.convert.protobuf.writer.buffer.defsize",
|
"redkale.convert.protobuf.writer.buffer.defsize",
|
||||||
Integer.getInteger("redkale.convert.writer.buffer.defsize", 1024));
|
Integer.getInteger("redkale.convert.writer.buffer.defsize", 1024));
|
||||||
|
|
||||||
private static final int CHILD_SIZE = 8;
|
private static final int CHILD_SIZE = 32;
|
||||||
protected static final byte[] EMPTY_BYTES = new byte[0];
|
protected static final byte[] EMPTY_BYTES = new byte[0];
|
||||||
|
|
||||||
protected static final int TENTHOUSAND_MAX = 10001;
|
protected static final int TENTHOUSAND_MAX = 10001;
|
||||||
@@ -62,33 +62,30 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int initOffset;
|
|
||||||
|
|
||||||
protected int count;
|
protected int count;
|
||||||
|
|
||||||
protected boolean enumtostring;
|
protected boolean enumtostring;
|
||||||
|
|
||||||
protected ProtobufWriter parent;
|
protected ProtobufWriter parent;
|
||||||
|
|
||||||
private byte[] content;
|
protected ProtobufWriter child;
|
||||||
|
|
||||||
private List<ProtobufWriter> children;
|
// 链表结构
|
||||||
|
protected ProtobufWriter delegate;
|
||||||
|
|
||||||
|
private byte[] content;
|
||||||
|
|
||||||
private ArrayDeque<ProtobufWriter> pool;
|
private ArrayDeque<ProtobufWriter> pool;
|
||||||
|
|
||||||
protected ProtobufWriter(ProtobufWriter parent) {
|
|
||||||
this();
|
|
||||||
this.parent = parent;
|
|
||||||
if (parent != null) {
|
|
||||||
this.features = parent.features;
|
|
||||||
this.enumtostring = parent.enumtostring;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ProtobufWriter(byte[] bs) {
|
protected ProtobufWriter(byte[] bs) {
|
||||||
this.content = bs;
|
this.content = bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ProtobufWriter(byte[] bs, int count) {
|
||||||
|
this.content = bs;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
public ProtobufWriter() {
|
public ProtobufWriter() {
|
||||||
this(DEFAULT_SIZE);
|
this(DEFAULT_SIZE);
|
||||||
}
|
}
|
||||||
@@ -97,10 +94,9 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
this.content = new byte[Math.max(size, DEFAULT_SIZE)];
|
this.content = new byte[Math.max(size, DEFAULT_SIZE)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtobufWriter(ByteArray array) {
|
public ProtobufWriter(ByteTuple tuple) {
|
||||||
this.content = array.content();
|
this.content = tuple.content();
|
||||||
this.initOffset = array.offset();
|
this.count = tuple.length();
|
||||||
this.count = array.length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,23 +106,10 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final ProtobufWriter configWrite() {
|
protected final ProtobufWriter configWrite() {
|
||||||
this.initOffset = this.count;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final ProtobufWriter configParentFunc(ProtobufWriter parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
if (parent != null) {
|
|
||||||
this.features = parent.features;
|
|
||||||
this.enumtostring = parent.enumtostring;
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final ProtobufWriter configFieldFunc(ProtobufWriter out) {
|
protected final ProtobufWriter configFieldFunc(ProtobufWriter out) {
|
||||||
if (out == null) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.mapFieldFunc = out.mapFieldFunc;
|
this.mapFieldFunc = out.mapFieldFunc;
|
||||||
this.objFieldFunc = out.objFieldFunc;
|
this.objFieldFunc = out.objFieldFunc;
|
||||||
this.objExtFunc = out.objExtFunc;
|
this.objExtFunc = out.objExtFunc;
|
||||||
@@ -146,27 +129,39 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean recycle() {
|
protected boolean recycle() {
|
||||||
super.recycle();
|
super.recycle();
|
||||||
|
if (this.delegate != null && this.pool != null) {
|
||||||
|
List<ProtobufWriter> list = new ArrayList<>();
|
||||||
|
ProtobufWriter next = this;
|
||||||
|
while ((next = next.child) != null) {
|
||||||
|
list.add(next);
|
||||||
|
}
|
||||||
|
for (ProtobufWriter item : list) {
|
||||||
|
offerPool(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
this.parent = null;
|
this.parent = null;
|
||||||
|
this.child = null;
|
||||||
|
this.delegate = null;
|
||||||
this.mapFieldFunc = null;
|
this.mapFieldFunc = null;
|
||||||
this.objFieldFunc = null;
|
this.objFieldFunc = null;
|
||||||
this.objExtFunc = null;
|
this.objExtFunc = null;
|
||||||
this.features = 0;
|
this.features = 0;
|
||||||
this.enumtostring = false;
|
this.enumtostring = false;
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.initOffset = 0;
|
|
||||||
if (this.content.length > DEFAULT_SIZE) {
|
if (this.content.length > DEFAULT_SIZE) {
|
||||||
this.content = new byte[DEFAULT_SIZE];
|
this.content = new byte[DEFAULT_SIZE];
|
||||||
}
|
}
|
||||||
if (this.children != null) {
|
|
||||||
for (ProtobufWriter child : children) {
|
|
||||||
offerChild2(child);
|
|
||||||
}
|
|
||||||
this.children = null;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ProtobufWriter pollChild() {
|
protected final void offerPool(ProtobufWriter item) {
|
||||||
|
if (this.pool != null && this.pool.size() < CHILD_SIZE) {
|
||||||
|
item.recycle();
|
||||||
|
this.pool.offer(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtobufWriter pollChild() {
|
||||||
Queue<ProtobufWriter> queue = this.pool;
|
Queue<ProtobufWriter> queue = this.pool;
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
this.pool = new ArrayDeque<>(CHILD_SIZE);
|
this.pool = new ArrayDeque<>(CHILD_SIZE);
|
||||||
@@ -176,76 +171,43 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = new ProtobufWriter();
|
result = new ProtobufWriter();
|
||||||
}
|
}
|
||||||
return result.configFieldFunc(this);
|
if (delegate == null) {
|
||||||
|
result.parent = this;
|
||||||
|
this.child = result;
|
||||||
|
delegate = result;
|
||||||
|
} else {
|
||||||
|
result.parent = delegate;
|
||||||
|
delegate.child = result;
|
||||||
|
delegate = result;
|
||||||
|
}
|
||||||
|
result.configFieldFunc(result.parent);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offerChild(final ProtobufWriter child) {
|
public void offerChild(ProtobufWriter child) {
|
||||||
Queue<ProtobufWriter> queue = this.pool;
|
if (child != null) {
|
||||||
if (child != null && queue != null && queue.size() < CHILD_SIZE) {
|
int len = child.length();
|
||||||
child.recycle();
|
ProtobufWriter next = child;
|
||||||
queue.offer(child);
|
while ((next = next.child) != null) {
|
||||||
}
|
len += next.length();
|
||||||
}
|
}
|
||||||
|
child.parent.writeSelfLength(len);
|
||||||
public final ProtobufWriter createChild2() {
|
|
||||||
Queue<ProtobufWriter> queue = this.pool;
|
|
||||||
if (queue == null) {
|
|
||||||
this.pool = new ArrayDeque<>(CHILD_SIZE);
|
|
||||||
queue = this.pool;
|
|
||||||
}
|
|
||||||
ProtobufWriter result = queue.poll();
|
|
||||||
if (result == null) {
|
|
||||||
result = new ProtobufWriter();
|
|
||||||
}
|
|
||||||
if (this.children == null) {
|
|
||||||
this.children = new ArrayList<>();
|
|
||||||
}
|
|
||||||
this.children.add(result);
|
|
||||||
return result.configFieldFunc(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void offerChild2(final ProtobufWriter child) {
|
|
||||||
Queue<ProtobufWriter> queue = this.pool;
|
|
||||||
if (child != null && queue != null && queue.size() < CHILD_SIZE) {
|
|
||||||
child.recycle();
|
|
||||||
queue.offer(child);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int length() {
|
public final int length() {
|
||||||
int total = count;
|
return count;
|
||||||
if (children != null) {
|
|
||||||
for (ProtobufWriter child : children) {
|
|
||||||
int len = child.length();
|
|
||||||
total += ProtobufFactory.computeSInt32SizeNoTag(len) + len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] content() {
|
public byte[] content() {
|
||||||
if (children != null) {
|
|
||||||
byte[] data = new byte[length()];
|
|
||||||
System.arraycopy(content, 0, data, 0, count);
|
|
||||||
int pos = count;
|
|
||||||
Utility.println("自身对象: ", content, 0, count);
|
|
||||||
for (ProtobufWriter child : children) {
|
|
||||||
int len = child.length();
|
|
||||||
data[pos++] = (byte) len;
|
|
||||||
Utility.println("子对象: ", child.content(), 0, child.length());
|
|
||||||
System.arraycopy(child.content(), 0, data, pos, len);
|
|
||||||
pos += len;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int offset() {
|
public final int offset() {
|
||||||
return initOffset;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,12 +229,26 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toArray() {
|
public byte[] toArray() {
|
||||||
if (children != null) {
|
if (delegate == null) {
|
||||||
return content();
|
byte[] copy = new byte[count];
|
||||||
|
System.arraycopy(content, 0, copy, 0, count);
|
||||||
|
return copy;
|
||||||
|
} else {
|
||||||
|
int total = count;
|
||||||
|
ProtobufWriter next = this;
|
||||||
|
while ((next = next.child) != null) {
|
||||||
|
total += next.length();
|
||||||
|
}
|
||||||
|
byte[] data = new byte[total];
|
||||||
|
System.arraycopy(content, 0, data, 0, count);
|
||||||
|
next = this;
|
||||||
|
int pos = count;
|
||||||
|
while ((next = next.child) != null) {
|
||||||
|
System.arraycopy(next.content(), 0, data, pos, next.length());
|
||||||
|
pos += next.length();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
byte[] copy = new byte[count];
|
|
||||||
System.arraycopy(content, 0, copy, 0, count);
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtobufWriter enumtostring(boolean enumtostring) {
|
public ProtobufWriter enumtostring(boolean enumtostring) {
|
||||||
@@ -291,8 +267,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeTo(final byte ch) {
|
public void writeTo(final byte ch) {
|
||||||
expand(1);
|
if (delegate == null) {
|
||||||
content[count++] = ch;
|
expand(1);
|
||||||
|
content[count++] = ch;
|
||||||
|
} else {
|
||||||
|
delegate.writeTo(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void writeTo(final byte... chs) {
|
public final void writeTo(final byte... chs) {
|
||||||
@@ -300,14 +280,18 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeTo(final byte[] chs, final int start, final int len) {
|
public void writeTo(final byte[] chs, final int start, final int len) {
|
||||||
expand(len);
|
if (delegate == null) {
|
||||||
System.arraycopy(chs, start, content, count, len);
|
expand(len);
|
||||||
count += len;
|
System.arraycopy(chs, start, content, count, len);
|
||||||
|
count += len;
|
||||||
|
} else {
|
||||||
|
delegate.writeTo(chs, start, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtobufWriter clear() {
|
public ProtobufWriter clear() {
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.initOffset = 0;
|
this.delegate = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,15 +329,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void writeObjectE(Object obj) {
|
public final void writeObjectE(Object obj) {
|
||||||
if (parent != null) {
|
// do nothing
|
||||||
parent.writeTuple(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final void writeTuple(ByteTuple tuple) {
|
|
||||||
int len = tuple.length();
|
|
||||||
writeLength(len);
|
|
||||||
writeTo(tuple.content(), tuple.offset(), len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -386,6 +362,15 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出一个字段名
|
||||||
|
*
|
||||||
|
* @param member 字段
|
||||||
|
*/
|
||||||
|
public final void writeField(final EnMember member) {
|
||||||
|
writeTag(member.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
// 被ObjectEncoder调用
|
// 被ObjectEncoder调用
|
||||||
@Override
|
@Override
|
||||||
public final void writeField(EnMember member, String fieldName, Type fieldType, int fieldPos) {
|
public final void writeField(EnMember member, String fieldName, Type fieldType, int fieldPos) {
|
||||||
@@ -1189,8 +1174,9 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@ClassDepends // objExtFunc扩展字段时member=null
|
@ClassDepends // objExtFunc扩展字段时member=null
|
||||||
public final void writeObjectField2(@Nullable EnMember member, Object obj) {
|
public final void writeObjectField(@Nullable EnMember member, Object obj) {
|
||||||
Object value;
|
Object value;
|
||||||
if (objFieldFunc == null) {
|
if (objFieldFunc == null) {
|
||||||
value = member.getFieldValue(obj);
|
value = member.getFieldValue(obj);
|
||||||
@@ -1201,41 +1187,11 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProtobufEncodeable encoder = (ProtobufEncodeable) member.getEncoder();
|
ProtobufEncodeable encoder = (ProtobufEncodeable) member.getEncoder();
|
||||||
if (encoder.requireSize()) {
|
if (encoder instanceof SimpledCoder) {
|
||||||
writeLength(encoder.computeSize(this, member.getTagSize(), value));
|
|
||||||
}
|
|
||||||
encoder.convertTo(this, member, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@ClassDepends // objExtFunc扩展字段时member=null
|
|
||||||
public final void writeObjectField(final EnMember member, Object obj) {
|
|
||||||
Object value;
|
|
||||||
if (objFieldFunc == null) {
|
|
||||||
value = member.getFieldValue(obj);
|
|
||||||
} else {
|
|
||||||
value = objFieldFunc.apply(member.getAttribute(), obj);
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Encodeable encoder = member.getEncoder();
|
|
||||||
if (encoder instanceof MapEncoder) {
|
|
||||||
if (!((Map) value).isEmpty()) {
|
|
||||||
((MapEncoder) encoder).convertTo(this, member, (Map) value);
|
|
||||||
}
|
|
||||||
} else if (encoder instanceof ProtobufArrayEncoder) {
|
|
||||||
ProtobufArrayEncoder arrayEncoder = (ProtobufArrayEncoder) encoder;
|
|
||||||
arrayEncoder.convertTo(this, member, (Object[]) value);
|
|
||||||
} else if (encoder instanceof ProtobufCollectionEncoder) {
|
|
||||||
ProtobufCollectionEncoder collectionEncoder = (ProtobufCollectionEncoder) encoder;
|
|
||||||
collectionEncoder.convertTo(this, member, (Collection) value);
|
|
||||||
} else if (encoder instanceof ProtobufStreamEncoder) {
|
|
||||||
ProtobufStreamEncoder streamEncoder = (ProtobufStreamEncoder) encoder;
|
|
||||||
streamEncoder.convertTo(this, member, (Stream) value);
|
|
||||||
} else {
|
|
||||||
this.writeField(member);
|
this.writeField(member);
|
||||||
encoder.convertTo(this, value);
|
encoder.convertTo(this, value);
|
||||||
|
} else {
|
||||||
|
encoder.convertTo(this, member, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1256,6 +1212,17 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final void writeSelfLength(int value) {
|
||||||
|
ProtobufWriter old = this.delegate;
|
||||||
|
this.delegate = null;
|
||||||
|
if (value < 128) {
|
||||||
|
writeTo((byte) value);
|
||||||
|
} else {
|
||||||
|
writeUInt32(value);
|
||||||
|
}
|
||||||
|
this.delegate = old;
|
||||||
|
}
|
||||||
|
|
||||||
protected void writeUInt32(int value) {
|
protected void writeUInt32(int value) {
|
||||||
if (value >= 0 && value < TENTHOUSAND_MAX) {
|
if (value >= 0 && value < TENTHOUSAND_MAX) {
|
||||||
writeTo(TENTHOUSAND_UINT_BYTES[value]);
|
writeTo(TENTHOUSAND_UINT_BYTES[value]);
|
||||||
@@ -1264,18 +1231,22 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
writeTo(TENTHOUSAND_UINT_BYTES2[-value]);
|
writeTo(TENTHOUSAND_UINT_BYTES2[-value]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
expand(5);
|
if (delegate == null) {
|
||||||
int curr = this.count;
|
expand(5);
|
||||||
byte[] data = this.content;
|
int curr = this.count;
|
||||||
while (true) {
|
byte[] data = this.content;
|
||||||
if ((value & ~0x7F) == 0) {
|
while (true) {
|
||||||
data[curr++] = (byte) value;
|
if ((value & ~0x7F) == 0) {
|
||||||
this.count = curr;
|
data[curr++] = (byte) value;
|
||||||
return;
|
this.count = curr;
|
||||||
} else {
|
return;
|
||||||
data[curr++] = (byte) ((value & 0x7F) | 0x80);
|
} else {
|
||||||
value >>>= 7;
|
data[curr++] = (byte) ((value & 0x7F) | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
delegate.writeUInt32(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1287,18 +1258,22 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
writeTo(TENTHOUSAND_UINT_BYTES2[(int) -value]);
|
writeTo(TENTHOUSAND_UINT_BYTES2[(int) -value]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
expand(10);
|
if (delegate == null) {
|
||||||
int curr = this.count;
|
expand(10);
|
||||||
byte[] data = this.content;
|
int curr = this.count;
|
||||||
while (true) {
|
byte[] data = this.content;
|
||||||
if ((value & ~0x7FL) == 0) {
|
while (true) {
|
||||||
data[curr++] = (byte) value;
|
if ((value & ~0x7FL) == 0) {
|
||||||
this.count = curr;
|
data[curr++] = (byte) value;
|
||||||
return;
|
this.count = curr;
|
||||||
} else {
|
return;
|
||||||
data[curr++] = (byte) (((int) value & 0x7F) | 0x80);
|
} else {
|
||||||
value >>>= 7;
|
data[curr++] = (byte) (((int) value & 0x7F) | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
delegate.writeUInt64(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user