package jane.core;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* 基于{@link Octets}的可扩展字节流的类型
* <p>
* 包括各种所需的序列化/反序列化
* @formatter:off
*/
public class OctetsStream extends Octets
{
protected transient int _pos; // 当前的读写位置
protected transient boolean _hasExInfo; // 是否需要详细的异常信息(默认不需要,可以加快unmarshal失败的性能)
public static OctetsStream wrap(byte[] data, int pos, int size)
{
OctetsStream os = new OctetsStream();
os._buffer = data;
if(size > data.length) os._count = data.length;
else if(size < 0) os._count = 0;
else os._count = size;
os._pos = pos;
return os;
}
public static OctetsStream wrap(byte[] data, int size)
{
OctetsStream os = new OctetsStream();
os._buffer = data;
if(size > data.length) os._count = data.length;
else if(size < 0) os._count = 0;
else os._count = size;
return os;
}
public static OctetsStream wrap(byte[] data)
{
if(data == null) throw new NullPointerException();
OctetsStream os = new OctetsStream();
os._buffer = data;
os._count = data.length;
return os;
}
public static OctetsStream wrap(Octets o)
{
OctetsStream os = new OctetsStream();
os._buffer = o._buffer;
os._count = o._count;
return os;
}
public OctetsStream()
{
}
public OctetsStream(int size)
{
super(size);
}
public OctetsStream(Octets o)
{
super(o);
}
public OctetsStream(byte[] data)
{
super(data);
}
public OctetsStream(byte[] data, int pos, int size)
{
super(data, pos, size);
}
public boolean eos()
{
return _pos >= _count;
}
@Override
public int position()
{
return _pos;
}
public void setPosition(int pos)
{
_pos = pos;
}
@Override
public int remain()
{
return _count - _pos;
}
public boolean hasExceptionInfo()
{
return _hasExInfo;
}
public void setExceptionInfo(boolean enable)
{
_hasExInfo = enable;
}
@Override
public OctetsStream wraps(byte[] data, int size)
{
_buffer = data;
if(size > data.length) _count = data.length;
else if(size < 0) _count = 0;
else _count = size;
return this;
}
@Override
public OctetsStream wraps(byte[] data)
{
if(data == null) throw new NullPointerException();
_buffer = data;
_count = data.length;
return this;
}
public OctetsStream wraps(Octets o)
{
_buffer = o._buffer;
_count = o._count;
return this;
}
@Override
public OctetsStream clone()
{
OctetsStream os = new OctetsStream(this);
os._pos = _pos;
os._hasExInfo = _hasExInfo;
return os;
}
@Override
public String toString()
{
return "[" + _pos + '/' + _count + '/' + _buffer.length + ']';
}
@Override
public StringBuilder dump(StringBuilder s)
{
if(s == null) s = new StringBuilder(_count * 3 + 16);
return super.dump(s).append(':').append(_pos);
}
public OctetsStream marshal1(byte x)
{
int count = _count;
int countNew = count + 1;
reserve(countNew);
_buffer[count] = x;
_count = countNew;
return this;
}
public OctetsStream marshal2(int x)
{
int count = _count;
int countNew = count + 2;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 8);
buf[count + 1] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal3(int x)
{
int count = _count;
int countNew = count + 3;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 16);
buf[count + 1] = (byte)(x >> 8);
buf[count + 2] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal4(int x)
{
int count = _count;
int countNew = count + 4;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 24);
buf[count + 1] = (byte)(x >> 16);
buf[count + 2] = (byte)(x >> 8);
buf[count + 3] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal5(byte b, int x)
{
int count = _count;
int countNew = count + 5;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = b;
buf[count + 1] = (byte)(x >> 24);
buf[count + 2] = (byte)(x >> 16);
buf[count + 3] = (byte)(x >> 8);
buf[count + 4] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal5(long x)
{
int count = _count;
int countNew = count + 5;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 32);
buf[count + 1] = (byte)(x >> 24);
buf[count + 2] = (byte)(x >> 16);
buf[count + 3] = (byte)(x >> 8);
buf[count + 4] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal6(long x)
{
int count = _count;
int countNew = count + 6;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 40);
buf[count + 1] = (byte)(x >> 32);
buf[count + 2] = (byte)(x >> 24);
buf[count + 3] = (byte)(x >> 16);
buf[count + 4] = (byte)(x >> 8);
buf[count + 5] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal7(long x)
{
int count = _count;
int countNew = count + 7;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 48);
buf[count + 1] = (byte)(x >> 40);
buf[count + 2] = (byte)(x >> 32);
buf[count + 3] = (byte)(x >> 24);
buf[count + 4] = (byte)(x >> 16);
buf[count + 5] = (byte)(x >> 8);
buf[count + 6] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal8(long x)
{
int count = _count;
int countNew = count + 8;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = (byte)(x >> 56);
buf[count + 1] = (byte)(x >> 48);
buf[count + 2] = (byte)(x >> 40);
buf[count + 3] = (byte)(x >> 32);
buf[count + 4] = (byte)(x >> 24);
buf[count + 5] = (byte)(x >> 16);
buf[count + 6] = (byte)(x >> 8);
buf[count + 7] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal9(byte b, long x)
{
int count = _count;
int countNew = count + 9;
reserve(countNew);
byte[] buf = _buffer;
buf[count ] = b;
buf[count + 1] = (byte)(x >> 56);
buf[count + 2] = (byte)(x >> 48);
buf[count + 3] = (byte)(x >> 40);
buf[count + 4] = (byte)(x >> 32);
buf[count + 5] = (byte)(x >> 24);
buf[count + 6] = (byte)(x >> 16);
buf[count + 7] = (byte)(x >> 8);
buf[count + 8] = (byte)x;
_count = countNew;
return this;
}
public OctetsStream marshal(boolean b)
{
int count = _count;
int countNew = count + 1;
reserve(countNew);
_buffer[count] = (byte)(b ? 1 : 0);
_count = countNew;
return this;
}
public OctetsStream marshal(Boolean b)
{
return b != null ? marshal(b.booleanValue()) : marshal1((byte)0);
}
public OctetsStream marshal(char x)
{
return marshal((int)x);
}
public OctetsStream marshal(Character x)
{
return x != null ? marshal((int)x) : marshal1((byte)0);
}
public OctetsStream marshal(byte x)
{
return marshal((int)x);
}
public OctetsStream marshal(Byte x)
{
return x != null ? marshal(x.intValue()) : marshal1((byte)0);
}
public OctetsStream marshal(short x)
{
return marshal((int)x);
}
public OctetsStream marshal(Short x)
{
return x != null ? marshal(x.intValue()) : marshal1((byte)0);
}
public OctetsStream marshal(int x)
{
if(x >= 0)
{
if(x < 0x40) return marshal1((byte)x); // 00xx xxxx
if(x < 0x2000) return marshal2(x + 0x4000); // 010x xxxx +1B
if(x < 0x100000) return marshal3(x + 0x600000); // 0110 xxxx +2B
if(x < 0x8000000) return marshal4(x + 0x70000000); // 0111 0xxx +3B
return marshal5((byte)0x78, x); // 0111 1000 +4B
}
if(x >= -0x40) return marshal1((byte)x); // 11xx xxxx
if(x >= -0x2000) return marshal2(x - 0x4000); // 101x xxxx +1B
if(x >= -0x100000) return marshal3(x - 0x600000); // 1001 xxxx +2B
if(x >= -0x8000000) return marshal4(x - 0x70000000); // 1000 1xxx +3B
return marshal5((byte)0x87, x); // 1000 0111 +4B
}
public OctetsStream marshal(Integer x)
{
return x != null ? marshal(x.intValue()) : marshal1((byte)0);
}
public static int marshalLen(int x)
{
if(x >= 0)
{
if(x < 0x40) return 1;
if(x < 0x2000) return 2;
if(x < 0x100000) return 3;
if(x < 0x8000000) return 4;
return 5;
}
if(x >= -0x40) return 1;
if(x >= -0x2000) return 2;
if(x >= -0x100000) return 3;
if(x >= -0x8000000) return 4;
return 5;
}
public OctetsStream marshal(long x)
{
if(x >= 0)
{
if(x < 0x8000000) return marshal((int)x);
if(x < 0x400000000L) return marshal5(x + 0x7800000000L); // 0111 10xx +4B
if(x < 0x20000000000L) return marshal6(x + 0x7c0000000000L); // 0111 110x +5B
if(x < 0x1000000000000L) return marshal7(x + 0x7e000000000000L); // 0111 1110 +6B
if(x < 0x80000000000000L) return marshal8(x + 0x7f00000000000000L); // 0111 1111 0+7B
return marshal9((byte)0x7f, x + 0x8000000000000000L); // 0111 1111 1+8B
}
if(x >= -0x8000000) return marshal((int)x);
if(x >= -0x400000000L) return marshal5(x - 0x7800000000L); // 1000 01xx +4B
if(x >= -0x20000000000L) return marshal6(x - 0x7c0000000000L); // 1000 001x +5B
if(x >= -0x1000000000000L) return marshal7(x - 0x7e000000000000L); // 1000 0001 +6B
if(x >= -0x80000000000000L) return marshal8(x - 0x7f00000000000000L); // 1000 0000 1+7B
return marshal9((byte)0x80, x - 0x8000000000000000L); // 1000 0000 0+8B
}
public OctetsStream marshal(Long x)
{
return x != null ? marshal(x.longValue()) : marshal1((byte)0);
}
public static int marshalLen(long x)
{
if(x >= 0)
{
if(x < 0x8000000) return marshalLen((int)x);
if(x < 0x400000000L) return 5;
if(x < 0x20000000000L) return 6;
if(x < 0x1000000000000L) return 7;
if(x < 0x80000000000000L) return 8;
return 9;
}
if(x >= -0x8000000) return marshalLen((int)x);
if(x >= -0x400000000L) return 5;
if(x >= -0x20000000000L) return 6;
if(x >= -0x1000000000000L) return 7;
if(x >= -0x80000000000000L) return 8;
return 9;
}
public OctetsStream marshalUInt(int x)
{
if(x < 0x80) return marshal1((byte)(x > 0 ? x : 0)); // 0xxx xxxx
if(x < 0x4000) return marshal2(x + 0x8000); // 10xx xxxx +1B
if(x < 0x200000) return marshal3(x + 0xc00000); // 110x xxxx +2B
if(x < 0x10000000) return marshal4(x + 0xe0000000); // 1110 xxxx +3B
return marshal5((byte)0xf0, x); // 1111 0000 +4B
}
public int marshalUIntBack(int p, int x)
{
int t = _count;
if(p < 5 || p > t) throw new IllegalArgumentException("p=" + p + ", _count=" + t);
if(x < 0x80) { _count = p - 1; marshal1((byte)(x > 0 ? x : 0)); _count = t; return 1; }
if(x < 0x4000) { _count = p - 2; marshal2(x + 0x8000); _count = t; return 2; }
if(x < 0x200000) { _count = p - 3; marshal3(x + 0xc00000); _count = t; return 3; }
if(x < 0x10000000) { _count = p - 4; marshal4(x + 0xe0000000); _count = t; return 4; }
{ _count = p - 5; marshal5((byte)0xf0, x); _count = t; return 5; }
}
public static int marshalUIntLen(int x)
{
if(x < 0x80) return 1;
if(x < 0x4000) return 2;
if(x < 0x200000) return 3;
if(x < 0x10000000) return 4;
return 5;
}
public OctetsStream marshalUTF8(char x)
{
if(x < 0x80) return marshal1((byte)x); // 0xxx xxxx
if(x < 0x800) return marshal2(((x << 2) & 0x1f00) + (x & 0x3f) + 0xc080); // 110x xxxx 10xx xxxx
return marshal3(((x << 4) & 0xf0000) + ((x << 2) & 0x3f00) + (x & 0x3f) + 0xe08080); // 1110 xxxx 10xx xxxx 10xx xxxx
}
public OctetsStream marshal(float x)
{
return marshal4(Float.floatToRawIntBits(x));
}
public OctetsStream marshal(Float x)
{
return marshal4(Float.floatToRawIntBits(x != null ? x : 0));
}
public OctetsStream marshal(double x)
{
return marshal8(Double.doubleToRawLongBits(x));
}
public OctetsStream marshal(Double x)
{
return marshal8(Double.doubleToRawLongBits(x != null ? x : 0));
}
public OctetsStream marshal(byte[] bytes)
{
marshalUInt(bytes.length);
append(bytes, 0, bytes.length);
return this;
}
public OctetsStream marshal(Octets o)
{
if(o == null)
{
marshal1((byte)0);
return this;
}
marshalUInt(o._count);
append(o._buffer, 0, o._count);
return this;
}
public OctetsStream marshal(String str)
{
int cn;
if(str == null || (cn = str.length()) <= 0)
{
marshal1((byte)0);
return this;
}
int bn = 0;
for(int i = 0; i < cn; ++i)
{
int c = str.charAt(i);
if(c < 0x80) ++bn;
else bn += (c < 0x800 ? 2 : 3);
}
marshalUInt(bn);
reserve(_count + bn);
if(bn == cn)
{
for(int i = 0; i < cn; ++i)
marshal1((byte)str.charAt(i));
}
else
{
for(int i = 0; i < cn; ++i)
marshalUTF8(str.charAt(i));
}
return this;
}
public OctetsStream marshal(Bean<?> b)
{
return b != null ? b.marshal(this) : marshal1((byte)0);
}
public OctetsStream marshalProtocol(Bean<?> b)
{
return b.marshalProtocol(this);
}
public static int getKVType(Object o)
{
if(o instanceof Number)
{
if(o instanceof Float) return 4;
if(o instanceof Double) return 5;
return 0;
}
if(o instanceof Bean) return 2;
if(o instanceof Boolean || o instanceof Character) return 0;
return 1;
}
private OctetsStream marshalId(int id, int type) // id must be in [1,190]
{
if(id < 63)
marshal1((byte)((id << 2) + type));
else
marshal2((type << 8) + id - 63 + 0xfc00);
return this;
}
private OctetsStream marshalIdSubType(int id, int subType) // id must be in [1,190], subType must be > 0
{
if(id < 63)
marshal2((id << 10) + subType + 0x300);
else
marshal3(((id - 63) << 8) + subType + 0xff0000);
return this;
}
public OctetsStream marshalVar(int id, Object o)
{
if(id < 1 || id > 190) throw new IllegalArgumentException("id must be in [1,190]: " + id);
if(o instanceof Number)
{
if(o instanceof Float)
{
float v = (Float)o;
if(v != 0) marshalIdSubType(id, 8).marshal(v);
}
else if(o instanceof Double)
{
double v = (Double)o;
if(v != 0) marshalIdSubType(id, 9).marshal(v);
}
else // Byte,Short,Integer,Long
{
long v = ((Number)o).longValue();
if(v != 0) marshalId(id, 0).marshal(v);
}
}
else if(o instanceof Bean)
{
int n = _count;
((Bean<?>)o).marshal(marshalId(id, 2));
if(_count - n < 3) resize(n);
}
else if(o instanceof Octets)
{
Octets oct = (Octets)o;
if(!oct.empty()) marshalId(id, 1).marshal(oct);
}
else if(o instanceof String)
{
String str = (String)o;
if(!str.isEmpty()) marshalId(id, 1).marshal(str);
}
else if(o instanceof Boolean)
{
boolean v = (Boolean)o;
if(v) marshalId(id, 0).marshal1((byte)1);
}
else if(o instanceof Character)
{
char v = (Character)o;
if(v != 0) marshalId(id, 0).marshal(v);
}
else if(o instanceof Collection)
{
Collection<?> list = (Collection<?>)o;
int n = list.size();
if(n > 0)
{
int vType = getKVType(list.iterator().next());
marshalIdSubType(id, vType).marshalUInt(n);
for(Object v : list)
marshalKV(vType, v);
}
}
else if(o instanceof Map)
{
Map<?, ?> map = (Map<?, ?>)o;
int n = map.size();
if(n > 0)
{
Entry<?, ?> et = map.entrySet().iterator().next();
int kType = getKVType(et.getKey());
int vType = getKVType(et.getValue());
marshalIdSubType(id, 0x40 + (kType << 3) + vType).marshalUInt(n);
for(Entry<?, ?> e : map.entrySet())
marshalKV(kType, e.getKey()).marshalKV(vType, e.getValue());
}
}
return this;
}
public OctetsStream marshalKV(int kvType, Object o)
{
switch(kvType)
{
case 0:
if(o instanceof Number ) marshal(((Number)o).longValue());
else if(o instanceof Boolean ) marshal1((byte)((Boolean)o ? 1 : 0));
else if(o instanceof Character) marshal(((Character)o).charValue());
else marshal1((byte)0);
break;
case 1:
if(o instanceof Octets) marshal((Octets)o);
else if(o != null) marshal(o.toString());
else marshal1((byte)0);
break;
case 2:
if(o instanceof Bean) marshal((Bean<?>)o);
else marshal1((byte)0);
break;
case 4:
if(o instanceof Number ) marshal(((Number)o).floatValue());
else if(o instanceof Boolean ) marshal((float)((Boolean)o ? 1 : 0));
else if(o instanceof Character) marshal((float)(Character)o);
else marshal(0.0f);
break;
case 5:
if(o instanceof Number ) marshal(((Number)o).doubleValue());
else if(o instanceof Boolean ) marshal((double)((Boolean)o ? 1 : 0));
else if(o instanceof Character) marshal((double)(Character)o);
else marshal(0.0);
break;
default:
throw new IllegalArgumentException("kvtype must be in {0,1,2,4,5}: " + kvType);
}
return this;
}
public byte unmarshalInt1() throws MarshalException
{
int pos = _pos;
if(pos >= _count) throw MarshalException.createEOF(_hasExInfo);
byte r = _buffer[pos];
_pos = pos + 1;
return r;
}
public int unmarshalInt2() throws MarshalException
{
int pos = _pos;
int posNew = pos + 2;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
_pos = posNew;
return (b0 << 8) + (b1 & 0xff);
}
public int unmarshalInt3() throws MarshalException
{
int pos = _pos;
int posNew = pos + 3;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
_pos = posNew;
return ((b0 & 0xff) << 16) +
((b1 & 0xff) << 8) +
(b2 & 0xff);
}
public int unmarshalInt4() throws MarshalException
{
int pos = _pos;
int posNew = pos + 4;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
byte b3 = buf[pos + 3];
_pos = posNew;
return ( b0 << 24) +
((b1 & 0xff) << 16) +
((b2 & 0xff) << 8) +
(b3 & 0xff);
}
public long unmarshalLong5() throws MarshalException
{
int pos = _pos;
int posNew = pos + 5;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
byte b3 = buf[pos + 3];
byte b4 = buf[pos + 4];
_pos = posNew;
return ((b0 & 0xffL) << 32) +
((b1 & 0xffL) << 24) +
((b2 & 0xff ) << 16) +
((b3 & 0xff ) << 8) +
(b4 & 0xff );
}
public long unmarshalLong6() throws MarshalException
{
int pos = _pos;
int posNew = pos + 6;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
byte b3 = buf[pos + 3];
byte b4 = buf[pos + 4];
byte b5 = buf[pos + 5];
_pos = posNew;
return ((b0 & 0xffL) << 40) +
((b1 & 0xffL) << 32) +
((b2 & 0xffL) << 24) +
((b3 & 0xff ) << 16) +
((b4 & 0xff ) << 8) +
(b5 & 0xff );
}
public long unmarshalLong7() throws MarshalException
{
int pos = _pos;
int posNew = pos + 7;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
byte b3 = buf[pos + 3];
byte b4 = buf[pos + 4];
byte b5 = buf[pos + 5];
byte b6 = buf[pos + 6];
_pos = posNew;
return ((b0 & 0xffL) << 48) +
((b1 & 0xffL) << 40) +
((b2 & 0xffL) << 32) +
((b3 & 0xffL) << 24) +
((b4 & 0xff ) << 16) +
((b5 & 0xff ) << 8) +
(b6 & 0xff );
}
public long unmarshalLong8() throws MarshalException
{
int pos = _pos;
int posNew = pos + 8;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
byte[] buf = _buffer;
byte b0 = buf[pos ];
byte b1 = buf[pos + 1];
byte b2 = buf[pos + 2];
byte b3 = buf[pos + 3];
byte b4 = buf[pos + 4];
byte b5 = buf[pos + 5];
byte b6 = buf[pos + 6];
byte b7 = buf[pos + 7];
_pos = posNew;
return ((long)b0 << 56) +
((b1 & 0xffL) << 48) +
((b2 & 0xffL) << 40) +
((b3 & 0xffL) << 32) +
((b4 & 0xffL) << 24) +
((b5 & 0xff ) << 16) +
((b6 & 0xff ) << 8) +
(b7 & 0xff );
}
public float unmarshalFloat() throws MarshalException
{
return Float.intBitsToFloat(unmarshalInt4());
}
public double unmarshalDouble() throws MarshalException
{
return Double.longBitsToDouble(unmarshalLong8());
}
public OctetsStream unmarshalSkip(int n) throws MarshalException
{
if(n < 0) throw MarshalException.create(_hasExInfo);
int pos = _pos;
int posNew = pos + n;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
if(posNew < pos) throw MarshalException.create(_hasExInfo);
_pos = posNew;
return this;
}
public OctetsStream unmarshalSkipOctets() throws MarshalException
{
return unmarshalSkip(unmarshalUInt());
}
public OctetsStream unmarshalSkipBean() throws MarshalException
{
for(;;)
{
int tag = unmarshalInt1();
if(tag == 0) return this;
unmarshalSkipVar(tag & 3);
}
}
public OctetsStream unmarshalSkipVar(int type) throws MarshalException
{
switch(type)
{
case 0: return unmarshalSkipInt(); // int/long: [1~9]
case 1: return unmarshalSkipOctets(); // octets: n [n]
case 2: return unmarshalSkipBean(); // bean: ... 00
case 3: return unmarshalSkipVarSub(unmarshalInt1()); // float/double/collection/map: ...
default: throw MarshalException.create(_hasExInfo);
}
}
public Object unmarshalVar(int type) throws MarshalException
{
switch(type)
{
case 0: return unmarshalLong();
case 1: return unmarshalOctets();
case 2: { DynBean db = new DynBean(); db.unmarshal(this); return db; }
case 3: return unmarshalVarSub(unmarshalInt1());
default: throw MarshalException.create(_hasExInfo);
}
}
public OctetsStream unmarshalSkipVarSub(int subType) throws MarshalException // [tkkkvvv] [4]/[8]/<n>[kv*n]
{
if(subType == 8) return unmarshalSkip(4); // float: [4]
if(subType == 9) return unmarshalSkip(8); // double: [8]
if(subType < 8) // collection: <n>[v*n]
{
subType &= 7;
for(int n = unmarshalUInt(); n > 0; --n)
unmarshalSkipKV(subType);
}
else // map: <n>[kv*n]
{
int keytype = (subType >> 3) & 7;
subType &= 7;
for(int n = unmarshalUInt(); n > 0; --n)
{
unmarshalSkipKV(keytype);
unmarshalSkipKV(subType);
}
}
return this;
}
public Object unmarshalVarSub(int subType) throws MarshalException
{
if(subType == 8) return unmarshalFloat();
if(subType == 9) return unmarshalDouble();
if(subType < 8)
{
subType &= 7;
int n = unmarshalUInt();
Collection<Object> list = new ArrayList<>(n < 0x10000 ? n : 0x10000);
for(; n > 0; --n)
list.add(unmarshalKV(subType));
return list;
}
int keytype = (subType >> 3) & 7;
subType &= 7;
int n = unmarshalUInt();
Map<Object, Object> map = new HashMap<>(n < 0x10000 ? n : 0x10000);
for(; n > 0; --n)
map.put(unmarshalKV(keytype), unmarshalKV(subType));
return map;
}
public OctetsStream unmarshalSkipKV(int kvType) throws MarshalException
{
switch(kvType)
{
case 0: return unmarshalSkipInt(); // int/long: [1~9]
case 1: return unmarshalSkipOctets(); // octets: n [n]
case 2: return unmarshalSkipBean(); // bean: ... 00
case 4: return unmarshalSkip(4); // float: [4]
case 5: return unmarshalSkip(8); // double: [8]
default: throw MarshalException.create(_hasExInfo);
}
}
public Object unmarshalKV(int kvType) throws MarshalException
{
switch(kvType)
{
case 0: return unmarshalLong();
case 1: return unmarshalOctets();
case 2: { DynBean db = new DynBean(); db.unmarshal(this); return db; }
case 4: return unmarshalFloat();
case 5: return unmarshalDouble();
default: throw MarshalException.create(_hasExInfo);
}
}
public OctetsStream unmarshalSkipInt() throws MarshalException
{
int b = unmarshalInt1() & 0xff;
switch(b >> 3)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x14: case 0x15: case 0x16: case 0x17: unmarshalSkip(1); break;
case 0x0c: case 0x0d: case 0x12: case 0x13: unmarshalSkip(2); break;
case 0x0e: case 0x11: unmarshalSkip(3); break;
case 0x0f:
switch(b & 7)
{
case 0: case 1: case 2: case 3: unmarshalSkip(4); break;
case 4: case 5: unmarshalSkip(5); break;
case 6: unmarshalSkip(6); break;
default: unmarshalSkip(6 - (unmarshalInt1() >> 7)); break;
}
break;
default: // 0x10
switch(b & 7)
{
case 4: case 5: case 6: case 7: unmarshalSkip(4); break;
case 2: case 3: unmarshalSkip(5); break;
case 1: unmarshalSkip(6); break;
default: unmarshalSkip(7 + (unmarshalInt1() >> 7)); break;
}
}
return this;
}
public int unmarshalInt() throws MarshalException
{
int b = unmarshalInt1();
switch((b >> 3) & 0x1f)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: return b;
case 0x08: case 0x09: case 0x0a: case 0x0b: return ((b - 0x40) << 8) + (unmarshalInt1() & 0xff);
case 0x14: case 0x15: case 0x16: case 0x17: return ((b + 0x40) << 8) + (unmarshalInt1() & 0xff);
case 0x0c: case 0x0d: return ((b - 0x60) << 16) + (unmarshalInt2() & 0xffff);
case 0x12: case 0x13: return ((b + 0x60) << 16) + (unmarshalInt2() & 0xffff);
case 0x0e: return ((b - 0x70) << 24) + unmarshalInt3();
case 0x11: return ((b + 0x70) << 24) + unmarshalInt3();
case 0x0f:
switch(b & 7)
{
case 0: case 1: case 2: case 3: return unmarshalInt4();
case 4: case 5: return unmarshalSkip(1).unmarshalInt4();
case 6: return unmarshalSkip(2).unmarshalInt4();
default: return unmarshalSkip(2 - (unmarshalInt1() >> 7)).unmarshalInt4();
}
default: // 0x10
switch(b & 7)
{
case 4: case 5: case 6: case 7: return unmarshalInt4();
case 2: case 3: return unmarshalSkip(1).unmarshalInt4();
case 1: return unmarshalSkip(2).unmarshalInt4();
default: return unmarshalSkip(3 + (unmarshalInt1() >> 7)).unmarshalInt4();
}
}
}
public long unmarshalLong() throws MarshalException
{
int b = unmarshalInt1();
switch((b >> 3) & 0x1f)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: return b;
case 0x08: case 0x09: case 0x0a: case 0x0b: return ((b - 0x40) << 8) + (unmarshalInt1() & 0xff);
case 0x14: case 0x15: case 0x16: case 0x17: return ((b + 0x40) << 8) + (unmarshalInt1() & 0xff);
case 0x0c: case 0x0d: return ((b - 0x60) << 16) + (unmarshalInt2() & 0xffff);
case 0x12: case 0x13: return ((b + 0x60) << 16) + (unmarshalInt2() & 0xffff);
case 0x0e: return ((b - 0x70) << 24) + unmarshalInt3();
case 0x11: return ((b + 0x70) << 24) + unmarshalInt3();
case 0x0f:
switch(b & 7)
{
case 0: case 1: case 2: case 3: return ((long)(b - 0x78) << 32) + (unmarshalInt4() & 0xffffffffL);
case 4: case 5: return ((long)(b - 0x7c) << 40) + unmarshalLong5();
case 6: return unmarshalLong6();
default: long r = unmarshalLong7(); return r < 0x80000000000000L ?
r : ((r - 0x80000000000000L) << 8) + (unmarshalInt1() & 0xff);
}
default: // 0x10
switch(b & 7)
{
case 4: case 5: case 6: case 7: return ((long)(b + 0x78) << 32) + (unmarshalInt4() & 0xffffffffL);
case 2: case 3: return ((long)(b + 0x7c) << 40) + unmarshalLong5();
case 1: return 0xffff000000000000L + unmarshalLong6();
default: long r = unmarshalLong7(); return r >= 0x80000000000000L ?
0xff00000000000000L + r : ((r + 0x80000000000000L) << 8) + (unmarshalInt1() & 0xff);
}
}
}
public int unmarshalUInt() throws MarshalException
{
int b = unmarshalInt1() & 0xff;
switch(b >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: return b;
case 8: case 9: case 10: case 11: return ((b & 0x3f) << 8) + (unmarshalInt1() & 0xff);
case 12: case 13: return ((b & 0x1f) << 16) + (unmarshalInt2() & 0xffff);
case 14: return ((b & 0x0f) << 24) + unmarshalInt3();
default: int r = unmarshalInt4(); if(r < 0) throw MarshalException.create(_hasExInfo); return r;
}
}
public char unmarshalUTF8() throws MarshalException
{
int b = unmarshalInt1();
if(b >= 0) return (char)b;
if(b < -0x20) return (char)(((b & 0x1f) << 6) + (unmarshalInt1() & 0x3f));
int c = unmarshalInt1();
return (char)(((b & 0xf) << 12) + ((c & 0x3f) << 6) + (unmarshalInt1() & 0x3f));
}
public int unmarshalInt(int type) throws MarshalException
{
if(type == 0) return unmarshalInt();
if(type == 3)
{
type = unmarshalInt1();
if(type == 8) return (int)unmarshalFloat();
if(type == 9) return (int)unmarshalDouble();
unmarshalSkipVarSub(type);
return 0;
}
unmarshalSkipVar(type);
return 0;
}
public long unmarshalLong(int type) throws MarshalException
{
if(type == 0) return unmarshalLong();
if(type == 3)
{
type = unmarshalInt1();
if(type == 8) return (long)unmarshalFloat();
if(type == 9) return (long)unmarshalDouble();
unmarshalSkipVarSub(type);
return 0;
}
unmarshalSkipVar(type);
return 0;
}
public float unmarshalFloat(int type) throws MarshalException
{
if(type == 3)
{
type = unmarshalInt1();
if(type == 8) return unmarshalFloat();
if(type == 9) return (float)unmarshalDouble();
unmarshalSkipVarSub(type);
return 0;
}
if(type == 0) return unmarshalLong();
unmarshalSkipVar(type);
return 0;
}
public double unmarshalDouble(int type) throws MarshalException
{
if(type == 3)
{
type = unmarshalInt1();
if(type == 9) return unmarshalDouble();
if(type == 8) return unmarshalFloat();
unmarshalSkipVarSub(type);
return 0;
}
if(type == 0) return unmarshalLong();
unmarshalSkipVar(type);
return 0;
}
public int unmarshalIntKV(int type) throws MarshalException
{
if(type == 0) return unmarshalInt();
if(type == 4) return (int)unmarshalFloat();
if(type == 5) return (int)unmarshalDouble();
unmarshalSkipKV(type);
return 0;
}
public long unmarshalLongKV(int type) throws MarshalException
{
if(type == 0) return unmarshalLong();
if(type == 4) return (long)unmarshalFloat();
if(type == 5) return (long)unmarshalDouble();
unmarshalSkipKV(type);
return 0;
}
public float unmarshalFloatKV(int type) throws MarshalException
{
if(type == 4) return unmarshalFloat();
if(type == 5) return (float)unmarshalDouble();
if(type == 0) return unmarshalLong();
unmarshalSkipKV(type);
return 0;
}
public double unmarshalDoubleKV(int type) throws MarshalException
{
if(type == 5) return unmarshalDouble();
if(type == 4) return unmarshalFloat();
if(type == 0) return unmarshalLong();
unmarshalSkipKV(type);
return 0;
}
public byte[] unmarshalBytes() throws MarshalException
{
int size = unmarshalUInt();
if(size <= 0) return EMPTY;
int pos = _pos;
int posNew = pos + size;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
if(posNew < pos) throw MarshalException.create(_hasExInfo);
byte[] r = new byte[size];
System.arraycopy(_buffer, pos, r, 0, size);
_pos = posNew;
return r;
}
public Octets unmarshalOctets() throws MarshalException
{
return Octets.wrap(unmarshalBytes());
}
public Octets unmarshalOctetsKV(int type) throws MarshalException
{
if(type == 1) return unmarshalOctets();
unmarshalSkipKV(type);
return new Octets();
}
public OctetsStream unmarshal(Octets o) throws MarshalException
{
int size = unmarshalUInt();
if(size <= 0)
{
o.clear();
return this;
}
int pos = _pos;
int posNew = pos + size;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
if(posNew < pos) throw MarshalException.create(_hasExInfo);
o.replace(_buffer, pos, size);
_pos = posNew;
return this;
}
public OctetsStream unmarshal(Octets o, int type) throws MarshalException
{
if(type == 1) return unmarshal(o);
unmarshalSkipVar(type);
return this;
}
public Octets unmarshalRaw(int size) throws MarshalException
{
if(size <= 0) return new Octets();
int pos = _pos;
int posNew = pos + size;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
if(posNew < pos) throw MarshalException.create(_hasExInfo);
Octets o = new Octets(_buffer, pos, size);
_pos = posNew;
return o;
}
public OctetsStream unmarshal(Bean<?> b) throws MarshalException
{
return b.unmarshal(this);
}
public OctetsStream unmarshalProtocol(Bean<?> b) throws MarshalException
{
return b.unmarshalProtocol(this);
}
public OctetsStream unmarshalBean(Bean<?> b, int type) throws MarshalException
{
if(type == 2) return b.unmarshal(this);
unmarshalSkipVar(type);
return this;
}
public <B extends Bean<B>> B unmarshalBean(B b) throws MarshalException
{
b.unmarshal(this);
return b;
}
public <B extends Bean<B>> B unmarshalProtocolBean(B b) throws MarshalException
{
b.unmarshalProtocol(this);
return b;
}
public <B extends Bean<B>> B unmarshalBeanKV(B b, int type) throws MarshalException
{
if(type == 2)
b.unmarshal(this);
else
unmarshalSkipKV(type);
return b;
}
public byte[] unmarshalBytes(int type) throws MarshalException
{
if(type == 1) return unmarshalBytes();
unmarshalSkipVar(type);
return EMPTY;
}
public byte[] unmarshalBytesKV(int type) throws MarshalException
{
if(type == 1) return unmarshalBytes();
unmarshalSkipKV(type);
return EMPTY;
}
public String unmarshalString() throws MarshalException
{
int size = unmarshalUInt();
if(size <= 0) return "";
int pos = _pos;
int posNew = pos + size;
if(posNew > _count) throw MarshalException.createEOF(_hasExInfo);
if(posNew < pos) throw MarshalException.create(_hasExInfo);
char[] tmp = new char[size];
int n = 0;
while(_pos < posNew)
tmp[n++] = unmarshalUTF8();
_pos = posNew;
return new String(tmp, 0, n);
}
public String unmarshalString(int type) throws MarshalException
{
if(type == 1) return unmarshalString();
if(type == 0) return String.valueOf(unmarshalLong());
if(type == 3)
{
type = unmarshalInt1();
if(type == 8) return String.valueOf(unmarshalFloat());
if(type == 9) return String.valueOf(unmarshalDouble());
unmarshalSkipVarSub(type);
}
else
unmarshalSkipVar(type);
return "";
}
public String unmarshalStringKV(int type) throws MarshalException
{
if(type == 1) return unmarshalString();
if(type == 0) return String.valueOf(unmarshalLong());
if(type == 4) return String.valueOf(unmarshalFloat());
if(type == 5) return String.valueOf(unmarshalDouble());
unmarshalSkipKV(type);
return "";
}
}