diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java index a0c50e269..db3142754 100644 --- a/src/main/java/org/redkale/convert/EnMember.java +++ b/src/main/java/org/redkale/convert/EnMember.java @@ -62,7 +62,7 @@ public final class EnMember { // 主要给protobuf使用 tag的大小 int tagSize; - public EnMember(Attribute attribute, int tag, Encodeable encoder) { + public EnMember(Attribute attribute, Encodeable encoder) { this.attribute = attribute; this.encoder = encoder; Class t = attribute.type(); diff --git a/src/main/java/org/redkale/convert/MapDecoder.java b/src/main/java/org/redkale/convert/MapDecoder.java index 11965fa11..ace77a4cf 100644 --- a/src/main/java/org/redkale/convert/MapDecoder.java +++ b/src/main/java/org/redkale/convert/MapDecoder.java @@ -162,4 +162,21 @@ public class MapDecoder implements Decodeable getValueDecoder() { 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; + } } diff --git a/src/main/java/org/redkale/convert/MapEncoder.java b/src/main/java/org/redkale/convert/MapEncoder.java index b1d6a4a27..81b2470df 100644 --- a/src/main/java/org/redkale/convert/MapEncoder.java +++ b/src/main/java/org/redkale/convert/MapEncoder.java @@ -140,4 +140,21 @@ public class MapEncoder implements Encodeable getValueEncoder() { 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; + } } diff --git a/src/main/java/org/redkale/convert/Writer.java b/src/main/java/org/redkale/convert/Writer.java index bff48527f..17252c255 100644 --- a/src/main/java/org/redkale/convert/Writer.java +++ b/src/main/java/org/redkale/convert/Writer.java @@ -205,7 +205,7 @@ public abstract class Writer { * * @param member 字段 */ - public final void writeField(final EnMember member) { + public void writeField(final EnMember member) { Attribute attr = member.getAttribute(); this.writeField(member, attr.field(), attr.genericType(), member.getPosition()); } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java index 990fdc8d3..68b01a998 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufArrayEncoder.java @@ -33,13 +33,8 @@ public class ProtobufArrayEncoder extends ArrayEncoder return; } Encodeable itemEncoder = this.componentEncoder; - T[] array = value; - // if (componentSizeRequired) { - // int tagSize = ProtobufFactory.computeSInt32SizeNoTag(member.getTag()); - // out.writeLength(computeSize(tagSize, value)); - // } - out.writeArrayB(array.length, itemEncoder, array); - for (T item : array) { + out.writeArrayB(value.length, itemEncoder, value); + for (T item : value) { out.writeField(member); if (item == null) { out.writeLength(0); @@ -48,7 +43,6 @@ public class ProtobufArrayEncoder extends ArrayEncoder } else { ProtobufWriter tmp = out.pollChild(); itemEncoder.convertTo(tmp, item); - out.writeTuple(tmp); out.offerChild(tmp); } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufByteBufferWriter.java b/src/main/java/org/redkale/convert/pb/ProtobufByteBufferWriter.java index 5efe7b9b9..1ad4be233 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufByteBufferWriter.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufByteBufferWriter.java @@ -35,6 +35,31 @@ public class ProtobufByteBufferWriter extends ProtobufWriter { 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 public ByteBuffer[] toBuffers() { if (buffers == null) { diff --git a/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java index 750dc8ab0..4e3dbbcd9 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufCollectionEncoder.java @@ -8,6 +8,7 @@ package org.redkale.convert.pb; import java.lang.reflect.Type; import java.util.Collection; import org.redkale.convert.*; +import org.redkale.util.Utility; /** * @author zhangjx @@ -28,14 +29,10 @@ public class ProtobufCollectionEncoder extends CollectionEncoder value) { this.checkInited(); - if (value == null || value.isEmpty()) { + if (Utility.isEmpty(value)) { return; } ProtobufEncodeable itemEncoder = (ProtobufEncodeable) this.componentEncoder; - // if (componentSizeRequired) { - // int tagSize = ProtobufFactory.computeSInt32SizeNoTag(member.getTag()); - // out.writeLength(computeSize(tagSize, value)); - // } out.writeArrayB(value.size(), itemEncoder, value); for (T item : value) { out.writeField(member); @@ -46,7 +43,6 @@ public class ProtobufCollectionEncoder extends CollectionEncoder extends MapDecoder protected final boolean enumtostring; + protected final DeMember keyMember; + + protected final DeMember valueMember; + public ProtobufMapDecoder(ConvertFactory factory, Type type) { super(factory, type); 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 @@ -35,9 +46,9 @@ public class ProtobufMapDecoder extends MapDecoder while (in.hasNext()) { int contentLen = in.readRawVarint32(); in.limit(in.position() + contentLen + 1); - in.readTag(); + in.readTag(); // key tag K key = kdecoder.convertFrom(in); - in.readTag(); + in.readTag(); // value tag V value = vdecoder.convertFrom(in); result.put(key, value); in.limit(limit); diff --git a/src/main/java/org/redkale/convert/pb/ProtobufMapEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufMapEncoder.java index a18d30367..cf4e0d569 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufMapEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufMapEncoder.java @@ -9,6 +9,8 @@ import java.lang.reflect.Type; import java.util.*; import java.util.function.BiFunction; import org.redkale.convert.*; +import org.redkale.util.Attribute; +import org.redkale.util.TypeToken; import org.redkale.util.Utility; /** @@ -19,13 +21,18 @@ import org.redkale.util.Utility; public class ProtobufMapEncoder extends MapEncoder implements ProtobufEncodeable> { - private final int keyTag; - private final int valTag; + private final EnMember keyMember; + + private final EnMember valueMember; public ProtobufMapEncoder(ConvertFactory factory, Type type) { super(factory, type); - this.keyTag = ProtobufFactory.getTag(1, ((ProtobufEncodeable) keyEncoder).typeEnum()); - this.valTag = ProtobufFactory.getTag(2, ((ProtobufEncodeable) valueEncoder).typeEnum()); + this.keyMember = new EnMember(createAttribute("key", keyEncoder.getType()), keyEncoder); + 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 @@ -38,22 +45,29 @@ public class ProtobufMapEncoder extends MapEncoder } Set ignoreColumns = this.ignoreMapColumns; BiFunction mapFieldFunc = out.mapFieldFunc(); - Encodeable kencoder = this.keyEncoder; - Encodeable vencoder = this.valueEncoder; + ProtobufEncodeable kencoder = (ProtobufEncodeable) this.keyEncoder; + ProtobufEncodeable vencoder = (ProtobufEncodeable) this.valueEncoder; + boolean keySimpled = kencoder instanceof SimpledCoder; + boolean valSimpled = vencoder instanceof SimpledCoder; out.writeMapB(values.size(), kencoder, vencoder, value); - values.forEach((key, val) -> { + values.forEach((key, val0) -> { if (ignoreColumns == null || !ignoreColumns.contains(key)) { - V v = mapFieldFunc == null ? val : mapFieldFunc.apply(key, val); - if (v != null) { + V val = mapFieldFunc == null ? val0 : mapFieldFunc.apply(key, val0); + if (val != null) { out.writeField(member); - ProtobufWriter tmp = out.pollChild(); - tmp.writeTag(keyTag); - kencoder.convertTo(tmp, key); - tmp.writeTag(valTag); - vencoder.convertTo(tmp, v); - - out.writeTuple(tmp); + if (keySimpled) { + tmp.writeField(keyMember); + kencoder.convertTo(tmp, key); + } else { + kencoder.convertTo(tmp, keyMember, key); + } + if (valSimpled) { + tmp.writeField(valueMember); + vencoder.convertTo(tmp, val); + } else { + vencoder.convertTo(tmp, valueMember, val); + } out.offerChild(tmp); } } @@ -78,4 +92,8 @@ public class ProtobufMapEncoder extends MapEncoder public final ProtobufTypeEnum typeEnum() { return ProtobufTypeEnum.BYTES; } + + static Attribute createAttribute(String field, Type type) { + return Attribute.create(Map.class, field, TypeToken.typeToClass(type), type, null, null, null); + } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java index 765456080..2d294dd65 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufObjectEncoder.java @@ -69,13 +69,7 @@ public class ProtobufObjectEncoder extends ObjectEncoder @ClassDepends protected ProtobufWriter objectWriter(ProtobufWriter out, EnMember parentMember, T value) { - // if (parentMember != null) { - // out.writeLength(computeSize(out, parentMember.getTagSize(), value)); - // } - if (out.length() > out.initOffset) { - return out.pollChild().configParentFunc(out); - } - return out; + return parentMember != null ? out.pollChild() : out; } @ClassDepends diff --git a/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java b/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java index 43d8e94f1..7efbef559 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufStreamEncoder.java @@ -43,7 +43,6 @@ public class ProtobufStreamEncoder extends StreamEncoder } else { ProtobufWriter tmp = out.pollChild(); itemEncoder.convertTo(tmp, item); - out.writeTuple(tmp); out.offerChild(tmp); } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java index 5a448e9ed..624c70b9e 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java @@ -23,7 +23,7 @@ public class ProtobufWriter extends Writer implements ByteTuple { "redkale.convert.protobuf.writer.buffer.defsize", 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 int TENTHOUSAND_MAX = 10001; @@ -62,33 +62,30 @@ public class ProtobufWriter extends Writer implements ByteTuple { } } - protected int initOffset; - protected int count; protected boolean enumtostring; protected ProtobufWriter parent; - private byte[] content; + protected ProtobufWriter child; - private List children; + // 链表结构 + protected ProtobufWriter delegate; + + private byte[] content; private ArrayDeque pool; - protected ProtobufWriter(ProtobufWriter parent) { - this(); - this.parent = parent; - if (parent != null) { - this.features = parent.features; - this.enumtostring = parent.enumtostring; - } - } - protected ProtobufWriter(byte[] bs) { this.content = bs; } + private ProtobufWriter(byte[] bs, int count) { + this.content = bs; + this.count = count; + } + public ProtobufWriter() { this(DEFAULT_SIZE); } @@ -97,10 +94,9 @@ public class ProtobufWriter extends Writer implements ByteTuple { this.content = new byte[Math.max(size, DEFAULT_SIZE)]; } - public ProtobufWriter(ByteArray array) { - this.content = array.content(); - this.initOffset = array.offset(); - this.count = array.length(); + public ProtobufWriter(ByteTuple tuple) { + this.content = tuple.content(); + this.count = tuple.length(); } @Override @@ -110,23 +106,10 @@ public class ProtobufWriter extends Writer implements ByteTuple { } 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; } protected final ProtobufWriter configFieldFunc(ProtobufWriter out) { - if (out == null) { - return this; - } this.mapFieldFunc = out.mapFieldFunc; this.objFieldFunc = out.objFieldFunc; this.objExtFunc = out.objExtFunc; @@ -146,27 +129,39 @@ public class ProtobufWriter extends Writer implements ByteTuple { @Override protected boolean recycle() { super.recycle(); + if (this.delegate != null && this.pool != null) { + List list = new ArrayList<>(); + ProtobufWriter next = this; + while ((next = next.child) != null) { + list.add(next); + } + for (ProtobufWriter item : list) { + offerPool(item); + } + } this.parent = null; + this.child = null; + this.delegate = null; this.mapFieldFunc = null; this.objFieldFunc = null; this.objExtFunc = null; this.features = 0; this.enumtostring = false; this.count = 0; - this.initOffset = 0; if (this.content.length > DEFAULT_SIZE) { this.content = new byte[DEFAULT_SIZE]; } - if (this.children != null) { - for (ProtobufWriter child : children) { - offerChild2(child); - } - this.children = null; - } 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 queue = this.pool; if (queue == null) { this.pool = new ArrayDeque<>(CHILD_SIZE); @@ -176,76 +171,43 @@ public class ProtobufWriter extends Writer implements ByteTuple { if (result == null) { 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) { - Queue queue = this.pool; - if (child != null && queue != null && queue.size() < CHILD_SIZE) { - child.recycle(); - queue.offer(child); - } - } - - public final ProtobufWriter createChild2() { - Queue 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 queue = this.pool; - if (child != null && queue != null && queue.size() < CHILD_SIZE) { - child.recycle(); - queue.offer(child); + public void offerChild(ProtobufWriter child) { + if (child != null) { + int len = child.length(); + ProtobufWriter next = child; + while ((next = next.child) != null) { + len += next.length(); + } + child.parent.writeSelfLength(len); } } @Override public final int length() { - int total = count; - if (children != null) { - for (ProtobufWriter child : children) { - int len = child.length(); - total += ProtobufFactory.computeSInt32SizeNoTag(len) + len; - } - } - return total; + return count; } @Override 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; } @Override public final int offset() { - return initOffset; + return 0; } /** @@ -267,12 +229,26 @@ public class ProtobufWriter extends Writer implements ByteTuple { @Override public byte[] toArray() { - if (children != null) { - return content(); + if (delegate == null) { + 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) { @@ -291,8 +267,12 @@ public class ProtobufWriter extends Writer implements ByteTuple { } public void writeTo(final byte ch) { - expand(1); - content[count++] = ch; + if (delegate == null) { + expand(1); + content[count++] = ch; + } else { + delegate.writeTo(ch); + } } 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) { - expand(len); - System.arraycopy(chs, start, content, count, len); - count += len; + if (delegate == null) { + expand(len); + System.arraycopy(chs, start, content, count, len); + count += len; + } else { + delegate.writeTo(chs, start, len); + } } public ProtobufWriter clear() { this.count = 0; - this.initOffset = 0; + this.delegate = null; return this; } @@ -345,15 +329,7 @@ public class ProtobufWriter extends Writer implements ByteTuple { @Override public final void writeObjectE(Object obj) { - if (parent != null) { - parent.writeTuple(this); - } - } - - protected final void writeTuple(ByteTuple tuple) { - int len = tuple.length(); - writeLength(len); - writeTo(tuple.content(), tuple.offset(), len); + // do nothing } @Override @@ -386,6 +362,15 @@ public class ProtobufWriter extends Writer implements ByteTuple { // do nothing } + /** + * 输出一个字段名 + * + * @param member 字段 + */ + public final void writeField(final EnMember member) { + writeTag(member.getTag()); + } + // 被ObjectEncoder调用 @Override 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 - public final void writeObjectField2(@Nullable EnMember member, Object obj) { + public final void writeObjectField(@Nullable EnMember member, Object obj) { Object value; if (objFieldFunc == null) { value = member.getFieldValue(obj); @@ -1201,41 +1187,11 @@ public class ProtobufWriter extends Writer implements ByteTuple { return; } ProtobufEncodeable encoder = (ProtobufEncodeable) member.getEncoder(); - if (encoder.requireSize()) { - 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 { + if (encoder instanceof SimpledCoder) { this.writeField(member); 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) { if (value >= 0 && value < TENTHOUSAND_MAX) { writeTo(TENTHOUSAND_UINT_BYTES[value]); @@ -1264,18 +1231,22 @@ public class ProtobufWriter extends Writer implements ByteTuple { writeTo(TENTHOUSAND_UINT_BYTES2[-value]); return; } - expand(5); - int curr = this.count; - byte[] data = this.content; - while (true) { - if ((value & ~0x7F) == 0) { - data[curr++] = (byte) value; - this.count = curr; - return; - } else { - data[curr++] = (byte) ((value & 0x7F) | 0x80); - value >>>= 7; + if (delegate == null) { + expand(5); + int curr = this.count; + byte[] data = this.content; + while (true) { + if ((value & ~0x7F) == 0) { + data[curr++] = (byte) value; + this.count = curr; + return; + } else { + 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]); return; } - expand(10); - int curr = this.count; - byte[] data = this.content; - while (true) { - if ((value & ~0x7FL) == 0) { - data[curr++] = (byte) value; - this.count = curr; - return; - } else { - data[curr++] = (byte) (((int) value & 0x7F) | 0x80); - value >>>= 7; + if (delegate == null) { + expand(10); + int curr = this.count; + byte[] data = this.content; + while (true) { + if ((value & ~0x7FL) == 0) { + data[curr++] = (byte) value; + this.count = curr; + return; + } else { + data[curr++] = (byte) (((int) value & 0x7F) | 0x80); + value >>>= 7; + } } + } else { + delegate.writeUInt64(value); } }