From fd5b63f58cb8b6c52b70cf20553547d03ddc1db0 Mon Sep 17 00:00:00 2001 From: redkale Date: Sat, 28 Sep 2024 17:23:33 +0800 Subject: [PATCH] convert --- .../convert/bson/BsonStreamReader.java | 2 +- .../convert/json/JsonByteBufferReader.java | 1 + .../convert/json/JsonStreamReader.java | 2 +- .../convert/pb/ProtobufByteBufferReader.java | 335 ++++++++++-------- .../redkale/convert/pb/ProtobufConvert.java | 11 - .../redkale/convert/pb/ProtobufReader.java | 80 ++--- .../convert/pb/ProtobufStreamReader.java | 65 +++- .../redkale/convert/pb/ProtobufWriter.java | 23 +- .../test/convert/GenericEntityTest.java | 62 ++-- 9 files changed, 326 insertions(+), 255 deletions(-) diff --git a/src/main/java/org/redkale/convert/bson/BsonStreamReader.java b/src/main/java/org/redkale/convert/bson/BsonStreamReader.java index 12ad885cd..72ebaa790 100644 --- a/src/main/java/org/redkale/convert/bson/BsonStreamReader.java +++ b/src/main/java/org/redkale/convert/bson/BsonStreamReader.java @@ -21,7 +21,7 @@ class BsonStreamReader extends BsonByteBufferReader { protected BsonStreamReader(InputStream in) { super(); - this.in = in; + this.in = in instanceof BufferedInputStream ? in : new BufferedInputStream(in); } @Override diff --git a/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java b/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java index 503c00404..0ba1f4027 100644 --- a/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java +++ b/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java @@ -110,6 +110,7 @@ public class JsonByteBufferReader extends JsonReader { * @param allowComment 是否容许含注释 * @return 有效字符 */ + @Override protected char nextGoodChar(boolean allowComment) { char c; for (; ; ) { diff --git a/src/main/java/org/redkale/convert/json/JsonStreamReader.java b/src/main/java/org/redkale/convert/json/JsonStreamReader.java index c6ad908c5..89bef0eb2 100644 --- a/src/main/java/org/redkale/convert/json/JsonStreamReader.java +++ b/src/main/java/org/redkale/convert/json/JsonStreamReader.java @@ -19,7 +19,7 @@ class JsonStreamReader extends JsonByteBufferReader { protected JsonStreamReader(InputStream in) { super(); - this.in = in; + this.in = in instanceof BufferedInputStream ? in : new BufferedInputStream(in); } @Override diff --git a/src/main/java/org/redkale/convert/pb/ProtobufByteBufferReader.java b/src/main/java/org/redkale/convert/pb/ProtobufByteBufferReader.java index 3378ff155..07c210a79 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufByteBufferReader.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufByteBufferReader.java @@ -6,33 +6,39 @@ package org.redkale.convert.pb; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import org.redkale.convert.ConvertException; +import org.redkale.util.ByteArray; /** @author zhangjx */ public class ProtobufByteBufferReader extends ProtobufReader { private ByteBuffer[] buffers; - private int currentIndex = 0; - private ByteBuffer currentBuffer; + private int currentIndex = 0; + protected ProtobufByteBufferReader(ByteBuffer... buffers) { this.buffers = buffers; - if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; + this.currentBuffer = buffers[currentIndex]; } @Override protected boolean recycle() { - super.recycle(); // this.position 初始化值为-1 + super.recycle(); this.currentIndex = 0; this.currentBuffer = null; this.buffers = null; return false; } - @Override - protected byte currentByte() { - return currentBuffer.get(currentBuffer.position()); + protected int remaining() { + int count = 0; + for (int i = currentIndex; i < buffers.length; i++) { + count += buffers[i].remaining(); + } + return count; } protected byte nextByte() { @@ -48,151 +54,172 @@ public class ProtobufByteBufferReader extends ProtobufReader { } } } - // - // //------------------------------------------------------------ - // /** - // * 判断对象是否存在下一个属性或者数组是否存在下一个元素 - // * - // * @param startPosition 起始位置 - // * @param contentLength 内容大小, 不确定的传-1 - // * - // * @return 是否存在 - // */ - // @Override - // public boolean hasNext(int startPosition, int contentLength) { - // //("-------------: " + startPosition + ", " + contentLength + ", " + this.position); - // if (startPosition >= 0 && contentLength >= 0) { - // return (this.position) < (startPosition + contentLength); - // } - // return (this.position + 1) < this.content.length; - // } - // - // @Override - // public byte[] readByteArray() { - // final int size = readRawVarint32(); - // byte[] bs = new byte[size]; - // System.arraycopy(content, position + 1, bs, 0, size); - // position += size; - // return bs; - // } - // - // protected int readRawVarint32() { //readUInt32 - // fastpath: - // { - // int tempPos = this.position; - // if ((tempPos + 1) == content.length) break fastpath; - // - // int x; - // if ((x = content[++tempPos]) >= 0) { - // this.position = tempPos; - // return x; - // } else if (content.length - (tempPos + 1) < 9) { - // break fastpath; - // } else if ((x ^= (content[++tempPos] << 7)) < 0) { - // x ^= (~0 << 7); - // } else if ((x ^= (content[++tempPos] << 14)) >= 0) { - // x ^= (~0 << 7) ^ (~0 << 14); - // } else if ((x ^= (content[++tempPos] << 21)) < 0) { - // x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21); - // } else { - // int y = content[++tempPos]; - // x ^= y << 28; - // x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28); - // if (y < 0 - // && content[++tempPos] < 0 - // && content[++tempPos] < 0 - // && content[++tempPos] < 0 - // && content[++tempPos] < 0 - // && content[++tempPos] < 0) { - // break fastpath; // Will throw malformedVarint() - // } - // } - // this.position = tempPos; - // return x; - // } - // return (int) readRawVarint64SlowPath(); - // } - // - // protected long readRawVarint64() { - // fastpath: - // { - // int tempPos = this.position; - // if ((tempPos + 1) == content.length) break fastpath; - // - // long x; - // int y; - // if ((y = content[++tempPos]) >= 0) { - // this.position = tempPos; - // return y; - // } else if (content.length - (tempPos + 1) < 9) { - // break fastpath; - // } else if ((y ^= (content[++tempPos] << 7)) < 0) { - // x = y ^ (~0 << 7); - // } else if ((y ^= (content[++tempPos] << 14)) >= 0) { - // x = y ^ ((~0 << 7) ^ (~0 << 14)); - // } else if ((y ^= (content[++tempPos] << 21)) < 0) { - // x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21)); - // } else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) { - // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28); - // } else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) { - // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35); - // } else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) { - // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42); - // } else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) { - // x ^= (~0L << 7) - // ^ (~0L << 14) - // ^ (~0L << 21) - // ^ (~0L << 28) - // ^ (~0L << 35) - // ^ (~0L << 42) - // ^ (~0L << 49); - // } else { - // x ^= ((long) content[++tempPos] << 56); - // x ^= (~0L << 7) - // ^ (~0L << 14) - // ^ (~0L << 21) - // ^ (~0L << 28) - // ^ (~0L << 35) - // ^ (~0L << 42) - // ^ (~0L << 49) - // ^ (~0L << 56); - // if (x < 0L) { - // if (content[++tempPos] < 0L) { - // break fastpath; // Will throw malformedVarint() - // } - // } - // } - // this.position = tempPos; - // return x; - // } - // return readRawVarint64SlowPath(); - // } - // - // protected long readRawVarint64SlowPath() { - // long result = 0; - // for (int shift = 0; shift < 64; shift += 7) { - // final byte b = content[++this.position]; - // result |= (long) (b & 0x7F) << shift; - // if ((b & 0x80) == 0) return result; - // } - // throw new ConvertException("readRawVarint64SlowPath error"); - // } - // - // protected int readRawLittleEndian32() { - // return ((content[++this.position] & 0xff) - // | ((content[++this.position] & 0xff) << 8) - // | ((content[++this.position] & 0xff) << 16) - // | ((content[++this.position] & 0xff) << 24)); - // } - // - // protected long readRawLittleEndian64() { - // return ((content[++this.position] & 0xffL) - // | ((content[++this.position] & 0xffL) << 8) - // | ((content[++this.position] & 0xffL) << 16) - // | ((content[++this.position] & 0xffL) << 24) - // | ((content[++this.position] & 0xffL) << 32) - // | ((content[++this.position] & 0xffL) << 40) - // | ((content[++this.position] & 0xffL) << 48) - // | ((content[++this.position] & 0xffL) << 56)); - // } + + protected byte[] nextBytes(int size) { + byte[] bs = new byte[size]; + if (this.currentBuffer.remaining() >= size) { + this.position += size; + this.currentBuffer.get(bs); + } else { + for (int i = 0; i < bs.length; i++) { + bs[i] = nextByte(); + } + } + return bs; + } + + @Override + public byte[] remainBytes() { + ByteArray array = new ByteArray(); + if (currentBuffer.hasRemaining()) { + array.put(currentBuffer); + } + int end = buffers.length - 1; + while (this.currentIndex < end) { + this.currentBuffer = this.buffers[++this.currentIndex]; + array.put(currentBuffer); + } + return array.getBytes(); + } + + @Override + public boolean hasNext() { + if (currentBuffer.hasRemaining()) { + return true; + } + int end = buffers.length - 1; + while (this.currentIndex < end) { + this.currentBuffer = this.buffers[++this.currentIndex]; + if (this.currentBuffer.hasRemaining()) { + return true; + } + } + return false; + } + + @Override + public final boolean readBoolean() { + return nextByte() != 0; + } + + @Override + public final String readString() { + final int size = readRawVarint32(); + return new String(nextBytes(size), StandardCharsets.UTF_8); + } + + @Override + public final byte[] readByteArray() { + final int size = readRawVarint32(); + return nextBytes(size); + } + + protected final int readRawVarint32() { // readUInt32 + fastpath: + { + if (!hasNext()) { + break fastpath; + } + int x; + if ((x = nextByte()) >= 0) { + return x; + } else if (remaining() < 9) { + break fastpath; + } else if ((x ^= (nextByte() << 7)) < 0) { + x ^= (~0 << 7); + } else if ((x ^= (nextByte() << 14)) >= 0) { + x ^= (~0 << 7) ^ (~0 << 14); + } else if ((x ^= (nextByte() << 21)) < 0) { + x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21); + } else { + int y = nextByte(); + x ^= y << 28; + x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28); + if (y < 0 && nextByte() < 0 && nextByte() < 0 && nextByte() < 0 && nextByte() < 0 && nextByte() < 0) { + break fastpath; // Will throw malformedVarint() + } + } + return x; + } + return (int) readRawVarint64SlowPath(); + } + + protected final long readRawVarint64() { + fastpath: + { + if (!hasNext()) { + break fastpath; + } + long x; + int y; + if ((y = nextByte()) >= 0) { + return y; + } else if (remaining() < 9) { + break fastpath; + } else if ((y ^= (nextByte() << 7)) < 0) { + x = y ^ (~0 << 7); + } else if ((y ^= (nextByte() << 14)) >= 0) { + x = y ^ ((~0 << 7) ^ (~0 << 14)); + } else if ((y ^= (nextByte() << 21)) < 0) { + x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21)); + } else if ((x = y ^ ((long) nextByte() << 28)) >= 0L) { + x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28); + } else if ((x ^= ((long) nextByte() << 35)) < 0L) { + x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35); + } else if ((x ^= ((long) nextByte() << 42)) >= 0L) { + x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42); + } else if ((x ^= ((long) nextByte() << 49)) < 0L) { + x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42) ^ (~0L << 49); + } else { + x ^= ((long) nextByte() << 56); + x ^= (~0L << 7) + ^ (~0L << 14) + ^ (~0L << 21) + ^ (~0L << 28) + ^ (~0L << 35) + ^ (~0L << 42) + ^ (~0L << 49) + ^ (~0L << 56); + if (x < 0L) { + if (nextByte() < 0L) { + break fastpath; // Will throw malformedVarint() + } + } + } + return x; + } + return readRawVarint64SlowPath(); + } + + protected final long readRawVarint64SlowPath() { + long result = 0; + for (int shift = 0; shift < 64; shift += 7) { + final byte b = nextByte(); + result |= (long) (b & 0x7F) << shift; + if ((b & 0x80) == 0) { + return result; + } + } + throw new ConvertException("readRawVarint64SlowPath error"); + } + + @Override + protected final int readRawLittleEndian32() { + return ((nextByte() & 0xff) + | ((nextByte() & 0xff) << 8) + | ((nextByte() & 0xff) << 16) + | ((nextByte() & 0xff) << 24)); + } + + @Override + protected final long readRawLittleEndian64() { + return ((nextByte() & 0xffL) + | ((nextByte() & 0xffL) << 8) + | ((nextByte() & 0xffL) << 16) + | ((nextByte() & 0xffL) << 24) + | ((nextByte() & 0xffL) << 32) + | ((nextByte() & 0xffL) << 40) + | ((nextByte() & 0xffL) << 48) + | ((nextByte() & 0xffL) << 56)); + } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufConvert.java b/src/main/java/org/redkale/convert/pb/ProtobufConvert.java index 58358c347..fade486f2 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufConvert.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufConvert.java @@ -614,9 +614,6 @@ public class ProtobufConvert extends BinaryConvert T convertFrom(final Type type, final InputStream in) { - if (true) { - throw new ConvertException(this.getClass().getSimpleName() + " not supported convertFrom InputStream"); - } if (type == null || in == null) { return null; } @@ -634,9 +631,6 @@ public class ProtobufConvert extends BinaryConvert T convertFrom(final Type type, final ByteBuffer... buffers) { - if (true) { - throw new ConvertException(this.getClass().getSimpleName() + " not supported convertFrom ByteBuffer"); - } if (type == null || Utility.isEmpty(buffers)) { return null; } @@ -782,9 +776,6 @@ public class ProtobufConvert extends BinaryConvert supplier, final Type type, final Object value) { - // if (true) throw new ConvertException(this.getClass().getSimpleName() + " not supported convertTo - // ByteBuffer"); Objects.requireNonNull(supplier); ProtobufByteBufferWriter writer = pollProtobufWriter(supplier); if (value == null) { diff --git a/src/main/java/org/redkale/convert/pb/ProtobufReader.java b/src/main/java/org/redkale/convert/pb/ProtobufReader.java index ee84c86b6..c81d5c278 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufReader.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufReader.java @@ -88,14 +88,6 @@ public class ProtobufReader extends Reader { return this; } - // 通常用于尾部解析 - public byte[] remainBytes() { - if (this.position >= this.limit) { - return new byte[0]; - } - return Arrays.copyOfRange(this.content, this.position + 1, this.limit); - } - /** 跳过属性的值 */ @Override @SuppressWarnings("unchecked") @@ -124,7 +116,7 @@ public class ProtobufReader extends Reader { @Override public final String readObjectB(final Class clazz) { - return (this.position + 1) < this.limit ? "" : null; + return hasNext() ? "" : null; } @Override @@ -183,11 +175,11 @@ public class ProtobufReader extends Reader { // ------------------------------------------------------------ @Override - public final boolean readBoolean() { + public boolean readBoolean() { return content[++this.position] != 0; } - public boolean[] readBools() { + public final boolean[] readBools() { int size = readRawVarint32(); boolean[] data = new boolean[size]; for (int i = 0; i < size; i++) { @@ -196,7 +188,7 @@ public class ProtobufReader extends Reader { return data; } - public Collection readBools(Creator creator) { + public final Collection readBools(Creator creator) { int size = readRawVarint32(); Collection data = creator.create(); for (int i = 0; i < size; i++) { @@ -210,11 +202,11 @@ public class ProtobufReader extends Reader { return (byte) readInt(); } - public byte[] readBytes() { + public final byte[] readBytes() { return readByteArray(); } - public Collection readBytes(Creator creator) { + public final Collection readBytes(Creator creator) { Collection data = creator.create(); for (byte b : readByteArray()) { data.add(b); @@ -227,7 +219,7 @@ public class ProtobufReader extends Reader { return (char) readInt(); } - public char[] readChars() { + public final char[] readChars() { int len = readRawVarint32(); List list = new ArrayList<>(len); while (len > 0) { @@ -242,7 +234,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readChars(Creator creator) { + public final Collection readChars(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -258,7 +250,7 @@ public class ProtobufReader extends Reader { return (short) readInt(); } - public short[] readShorts() { + public final short[] readShorts() { int len = readRawVarint32(); List list = new ArrayList<>(len); while (len > 0) { @@ -273,7 +265,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readShorts(Creator creator) { + public final Collection readShorts(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -290,7 +282,7 @@ public class ProtobufReader extends Reader { return (n >>> 1) ^ -(n & 1); } - public int[] readInts() { + public final int[] readInts() { int len = readRawVarint32(); List list = new ArrayList<>(len); while (len > 0) { @@ -305,7 +297,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readInts(Creator creator) { + public final Collection readInts(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -316,12 +308,12 @@ public class ProtobufReader extends Reader { return data; } - public AtomicInteger[] readAtomicIntegers() { + public final AtomicInteger[] readAtomicIntegers() { Collection data = readAtomicIntegers(LIS_CREATOR); return data.toArray(new AtomicInteger[data.size()]); } - public Collection readAtomicIntegers(Creator creator) { + public final Collection readAtomicIntegers(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -337,7 +329,7 @@ public class ProtobufReader extends Reader { return Float.intBitsToFloat(readRawLittleEndian32()); } - public float[] readFloats() { + public final float[] readFloats() { int len = readRawVarint32(); float[] rs = new float[len / 4]; for (int i = 0; i < rs.length; i++) { @@ -346,7 +338,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readFloats(Creator creator) { + public final Collection readFloats(Creator creator) { Collection data = creator.create(); int len = readRawVarint32() / 4; for (int i = 0; i < len; i++) { @@ -361,7 +353,7 @@ public class ProtobufReader extends Reader { return (n >>> 1) ^ -(n & 1); } - public long[] readLongs() { + public final long[] readLongs() { int len = readRawVarint32(); List list = new ArrayList<>(len); while (len > 0) { @@ -376,7 +368,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readLongs(Creator creator) { + public final Collection readLongs(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -387,12 +379,12 @@ public class ProtobufReader extends Reader { return data; } - public AtomicLong[] readAtomicLongs() { + public final AtomicLong[] readAtomicLongs() { Collection data = readAtomicLongs(LIS_CREATOR); return data.toArray(new AtomicLong[data.size()]); } - public Collection readAtomicLongs(Creator creator) { + public final Collection readAtomicLongs(Creator creator) { Collection data = creator.create(); int len = readRawVarint32(); while (len > 0) { @@ -403,12 +395,12 @@ public class ProtobufReader extends Reader { return data; } - public String[] readStrings(int tag) { + public final String[] readStrings(int tag) { Collection data = readStrings(tag, LIS_CREATOR); return data.toArray(new String[data.size()]); } - public Collection readStrings(int tag, Creator creator) { + public final Collection readStrings(int tag, Creator creator) { Collection data = creator.create(); while (true) { data.add(readString()); @@ -424,7 +416,7 @@ public class ProtobufReader extends Reader { return Double.longBitsToDouble(readRawLittleEndian64()); } - public double[] readDoubles() { + public final double[] readDoubles() { int len = readRawVarint32(); double[] rs = new double[len / 8]; for (int i = 0; i < rs.length; i++) { @@ -433,7 +425,7 @@ public class ProtobufReader extends Reader { return rs; } - public Collection readDoubles(Creator creator) { + public final Collection readDoubles(Creator creator) { Collection data = creator.create(); int len = readRawVarint32() / 8; for (int i = 0; i < len; i++) { @@ -453,18 +445,18 @@ public class ProtobufReader extends Reader { } @Override - public final String readString() { + public String readString() { final int size = readRawVarint32(); String val = new String(content, position + 1, size, StandardCharsets.UTF_8); position += size; return val; } - public boolean readNextTag(DeMember member) { + public final boolean readNextTag(DeMember member) { return readNextTag(member.getTag()); } - public boolean readNextTag(int memberTag) { + public final boolean readNextTag(int memberTag) { if (!hasNext()) { return false; } @@ -489,8 +481,9 @@ public class ProtobufReader extends Reader { this.cacheTag = tag; } - protected byte currentByte() { - return this.content[this.position]; + @Override + public final ValueType readType() { + throw new UnsupportedOperationException("Not supported yet."); } @Override @@ -507,6 +500,14 @@ public class ProtobufReader extends Reader { return bs; } + // 通常用于尾部解析 + public byte[] remainBytes() { + if (this.position >= this.limit) { + return new byte[0]; + } + return Arrays.copyOfRange(this.content, this.position + 1, this.limit); + } + protected int readRawVarint32() { // readUInt32 byte[] data = content; fastpath: @@ -631,9 +632,4 @@ public class ProtobufReader extends Reader { | ((content[++this.position] & 0xffL) << 48) | ((content[++this.position] & 0xffL) << 56)); } - - @Override - public ValueType readType() { - throw new UnsupportedOperationException("Not supported yet."); - } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufStreamReader.java b/src/main/java/org/redkale/convert/pb/ProtobufStreamReader.java index 126b3abd1..a9ac45b9a 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufStreamReader.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufStreamReader.java @@ -7,6 +7,7 @@ package org.redkale.convert.pb; import java.io.*; import org.redkale.convert.*; +import org.redkale.util.ByteArray; /** * 详情见: https://redkale.org @@ -17,34 +18,80 @@ class ProtobufStreamReader extends ProtobufByteBufferReader { private InputStream in; - private byte currByte; + private Byte backByte; protected ProtobufStreamReader(InputStream in) { super(); - this.in = in; + this.in = in instanceof BufferedInputStream ? in : new BufferedInputStream(in); } @Override protected boolean recycle() { super.recycle(); // this.position 初始化值为-1 this.in = null; - this.currByte = 0; + this.backByte = null; return false; } @Override - public byte nextByte() { - try { - byte b = (currByte = (byte) in.read()); - this.position++; + protected int remaining() { + int count = 0; + return count; + } + + @Override + protected byte nextByte() { + if (backByte != null) { + byte b = backByte; + backByte = null; return b; + } + try { + int v = in.read(); + if (v == -1) { + throw new ConvertException("eof"); + } + this.position++; + return (byte) v; } catch (IOException e) { throw new ConvertException(e); } } @Override - protected byte currentByte() { - return currByte; + protected byte[] nextBytes(int size) { + byte[] bs = new byte[size]; + for (int i = 0; i < bs.length; i++) { + bs[i] = nextByte(); + } + return bs; + } + + @Override + public byte[] remainBytes() { + ByteArray array = new ByteArray(); + try { + int v; + while ((v = in.read()) != -1) { + array.putByte(v); + } + } catch (IOException e) { + throw new ConvertException(e); + } + return array.getBytes(); + } + + @Override + public boolean hasNext() { + try { + int v = in.read(); + if (v == -1) { + return false; + } + backByte = (byte) v; + return true; + } catch (IOException e) { + return false; + } } } diff --git a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java index c7c7f2660..6ca348179 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufWriter.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufWriter.java @@ -1354,12 +1354,16 @@ public class ProtobufWriter extends Writer implements ByteTuple { writeTo(TENTHOUSAND_UINT_BYTES2[-value]); return; } + expand(6); + int curr = this.count; + byte[] data = this.content; while (true) { if ((value & ~0x7F) == 0) { - writeTo((byte) value); + data[curr++] = (byte) value; + this.count = curr; return; } else { - writeTo((byte) ((value & 0x7F) | 0x80)); + data[curr++] = (byte) ((value & 0x7F) | 0x80); value >>>= 7; } } @@ -1373,12 +1377,16 @@ public class ProtobufWriter extends Writer implements ByteTuple { writeTo(TENTHOUSAND_UINT_BYTES2[(int) -value]); return; } + expand(12); + int curr = this.count; + byte[] data = this.content; while (true) { if ((value & ~0x7FL) == 0) { - writeTo((byte) value); + data[curr++] = (byte) value; + this.count = curr; return; } else { - writeTo((byte) (((int) value & 0x7F) | 0x80)); + data[curr++] = (byte) (((int) value & 0x7F) | 0x80); value >>>= 7; } } @@ -1392,8 +1400,11 @@ public class ProtobufWriter extends Writer implements ByteTuple { writeTo(TENTHOUSAND_FIXED32_BYTES2[-value]); return; } - writeTo((byte) (value & 0xFF), (byte) ((value >> 8) & 0xFF), (byte) ((value >> 16) & 0xFF), (byte) - ((value >> 24) & 0xFF)); + writeTo( + (byte) (value & 0xFF), // 0 + (byte) ((value >> 8) & 0xFF), // 1 + (byte) ((value >> 16) & 0xFF), // 2 + (byte) ((value >> 24) & 0xFF)); // 3 } protected void writeFixed64(long value) { diff --git a/src/test/java/org/redkale/test/convert/GenericEntityTest.java b/src/test/java/org/redkale/test/convert/GenericEntityTest.java index bddcad232..4aad875b3 100644 --- a/src/test/java/org/redkale/test/convert/GenericEntityTest.java +++ b/src/test/java/org/redkale/test/convert/GenericEntityTest.java @@ -54,17 +54,6 @@ public class GenericEntityTest { @Test public void runJson2() throws Exception { - JsonConvert convert = JsonConvert.root(); - InputStream in = ConvertHelper.createInputStream(createBytes()); - GenericEntity bean = convert.convertFrom(ENTITY_TYPE, in); - Assertions.assertEquals(JSON, bean.toString()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - convert.convertTo(out, ENTITY_TYPE, bean); - Assertions.assertArrayEquals(createBytes(), out.toByteArray()); - } - - @Test - public void runJson3() throws Exception { JsonConvert convert = JsonConvert.root(); ByteBuffer in = ConvertHelper.createByteBuffer(createBytes()); GenericEntity bean = convert.convertFrom(ENTITY_TYPE, in); @@ -74,6 +63,17 @@ public class GenericEntityTest { Assertions.assertArrayEquals(createBytes(), ConvertHelper.toBytes(buffers)); } + @Test + public void runJson3() throws Exception { + JsonConvert convert = JsonConvert.root(); + InputStream in = ConvertHelper.createInputStream(createBytes()); + GenericEntity bean = convert.convertFrom(ENTITY_TYPE, in); + Assertions.assertEquals(JSON, bean.toString()); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + convert.convertTo(out, ENTITY_TYPE, bean); + Assertions.assertArrayEquals(createBytes(), out.toByteArray()); + } + @Test public void runPb1() throws Exception { ProtobufConvert convert = ProtobufConvert.root(); @@ -90,12 +90,12 @@ public class GenericEntityTest { ProtobufConvert convert = ProtobufConvert.root(); GenericEntity bean = createBean(); byte[] bs = convert.convertTo(bean); - // InputStream in = ConvertHelper.createInputStream(bs); - // GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); - // Assertions.assertEquals(JSON, rs.toString()); - // ByteArrayOutputStream out = new ByteArrayOutputStream(); - // convert.convertTo(out, ENTITY_TYPE, rs); - // Assertions.assertArrayEquals(bs, out.toByteArray()); + ByteBuffer in = ConvertHelper.createByteBuffer(bs); +// GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); +// Assertions.assertEquals(JSON, rs.toString()); +// Supplier out = ConvertHelper.createSupplier(); +// ByteBuffer[] buffers = convert.convertTo(out, ENTITY_TYPE, rs); +// Assertions.assertArrayEquals(bs, ConvertHelper.toBytes(buffers)); } @Test @@ -103,12 +103,12 @@ public class GenericEntityTest { ProtobufConvert convert = ProtobufConvert.root(); GenericEntity bean = createBean(); byte[] bs = convert.convertTo(bean); - // ByteBuffer in = ConvertHelper.createByteBuffer(bs); - // GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); - // Assertions.assertEquals(JSON, rs.toString()); - // Supplier out = ConvertHelper.createSupplier(); - // ByteBuffer[] buffers = convert.convertTo(out, ENTITY_TYPE, rs); - // Assertions.assertArrayEquals(bs, ConvertHelper.toBytes(buffers)); + InputStream in = ConvertHelper.createInputStream(bs); +// GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); +// Assertions.assertEquals(JSON, rs.toString()); +// ByteArrayOutputStream out = new ByteArrayOutputStream(); +// convert.convertTo(out, ENTITY_TYPE, rs); +// Assertions.assertArrayEquals(bs, out.toByteArray()); } @Test @@ -127,12 +127,12 @@ public class GenericEntityTest { BsonConvert convert = BsonConvert.root(); GenericEntity bean = createBean(); byte[] bs = convert.convertTo(bean); - // InputStream in = ConvertHelper.createInputStream(bs); + // ByteBuffer in = ConvertHelper.createByteBuffer(bs); // GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); // Assertions.assertEquals(JSON, rs.toString()); - // ByteArrayOutputStream out = new ByteArrayOutputStream(); - // convert.convertTo(out, ENTITY_TYPE, rs); - // Assertions.assertArrayEquals(bs, out.toByteArray()); + // Supplier out = ConvertHelper.createSupplier(); + // ByteBuffer[] buffers = convert.convertTo(out, ENTITY_TYPE, rs); + // Assertions.assertArrayEquals(bs, ConvertHelper.toBytes(buffers)); } @Test @@ -140,12 +140,12 @@ public class GenericEntityTest { BsonConvert convert = BsonConvert.root(); GenericEntity bean = createBean(); byte[] bs = convert.convertTo(bean); - // ByteBuffer in = ConvertHelper.createByteBuffer(bs); + // InputStream in = ConvertHelper.createInputStream(bs); // GenericEntity rs = convert.convertFrom(ENTITY_TYPE, in); // Assertions.assertEquals(JSON, rs.toString()); - // Supplier out = ConvertHelper.createSupplier(); - // ByteBuffer[] buffers = convert.convertTo(out, ENTITY_TYPE, rs); - // Assertions.assertArrayEquals(bs, ConvertHelper.toBytes(buffers)); + // ByteArrayOutputStream out = new ByteArrayOutputStream(); + // convert.convertTo(out, ENTITY_TYPE, rs); + // Assertions.assertArrayEquals(bs, out.toByteArray()); } private byte[] createBytes() {