org.redkalex.convert.pson.ProtobufReader Maven / Gradle / Ivy
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkalex.convert.pson;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import org.redkale.convert.*;
import org.redkale.util.*;
/**
*
* @author zhangjx
*/
public class ProtobufReader extends Reader {
protected int position = -1;
private byte[] content;
protected int cachetag = Integer.MIN_VALUE;
public static ObjectPool createPool(int max) {
return new ObjectPool<>(max, (Object... params) -> new ProtobufReader(), null, (t) -> t.recycle());
}
public ProtobufReader() {
}
public ProtobufReader(byte[] bytes) {
setBytes(bytes, 0, bytes.length);
}
public ProtobufReader(byte[] bytes, int start, int len) {
setBytes(bytes, start, len);
}
public final void setBytes(byte[] bytes) {
if (bytes == null) {
this.position = 0;
} else {
setBytes(bytes, 0, bytes.length);
}
}
public final void setBytes(byte[] bytes, int start, int len) {
if (bytes == null) {
this.position = 0;
} else {
this.content = bytes;
this.position = start - 1;
}
}
protected boolean recycle() {
this.position = -1;
this.content = null;
return true;
}
public void close() {
this.recycle();
}
/**
* 跳过属性的值
*/
@Override
@SuppressWarnings("unchecked")
public final void skipValue() {
readTag();
}
@Override
public final String readObjectB(final Class clazz) {
return "";
}
@Override
public final void readObjectE(final Class clazz) {
}
@Override
public final int readMapB(DeMember member, byte[] typevals, Decodeable keyDecoder, Decodeable valueDecoder) {
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readMapE() {
}
/**
* 判断下一个非空白字符是否为[
*
* @param member DeMember
* @param typevals byte[]
* @param componentDecoder Decodeable
*
* @return SIGN_NOLENGTH 或 SIGN_NULL
*/
@Override
public final int readArrayB(DeMember member, byte[] typevals, Decodeable componentDecoder) {
if (member == null || componentDecoder == null) return Reader.SIGN_NOLENBUTBYTES;
Type type = componentDecoder.getType();
if (!(type instanceof Class)) return Reader.SIGN_NOLENBUTBYTES;
Class clazz = (Class) type;
if (clazz.isPrimitive() || clazz == Boolean.class
|| clazz == Byte.class || clazz == Short.class
|| clazz == Character.class || clazz == Integer.class
|| clazz == Float.class || clazz == Long.class
|| clazz == Double.class) {
return Reader.SIGN_NOLENBUTBYTES;
}
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readArrayE() {
}
/**
* 判断下一个非空白字节是否:
*/
@Override
public final void readBlank() {
}
@Override
public final int position() {
return this.position;
}
@Override
public final int readMemberContentLength(DeMember member, Decodeable decoder) {
if (member == null && decoder == null) return -1; //为byte[]
if (member != null && !(member.getDecoder() instanceof ProtobufArrayDecoder)) return -1;
return readRawVarint32(); //readUInt32
}
@Override
public final DeMember readFieldName(final DeMember[] members) {
int tag = readTag();
int pos = tag >>> 3;
for (DeMember member : members) {
if (member.getPosition() == pos) {
return member;
}
}
backTag(tag);
return null;
}
//------------------------------------------------------------
@Override
public final boolean readBoolean() {
return readRawVarint64() != 0;
}
@Override
public final byte readByte() {
return (byte) readInt();
}
@Override
public final char readChar() {
return (char) readInt();
}
@Override
public final short readShort() {
return (short) readInt();
}
@Override
public final int readInt() { //readSInt32
int n = readRawVarint32();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final long readLong() { //readSInt64
long n = readRawVarint64();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final float readFloat() {
return Float.intBitsToFloat(readRawLittleEndian32());
}
@Override
public final double readDouble() {
return Double.longBitsToDouble(readRawLittleEndian64());
}
@Override
public final String readClassName() {
return "";
}
@Override
public final String readSmallString() {
return readString();
}
@Override
public final String readString() {
return new String(readByteArray(), StandardCharsets.UTF_8);
}
protected final int readTag() {
if (cachetag != Integer.MIN_VALUE) {
int tag = cachetag;
cachetag = Integer.MIN_VALUE;
return tag;
}
return readRawVarint32();
}
protected final void backTag(int tag) {
this.cachetag = tag;
}
protected byte currentByte() {
return this.content[this.position];
}
/**
* 判断对象是否存在下一个属性或者数组是否存在下一个元素
*
* @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));
}
@Override
public ValueType readType() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy