1.VInt数字压缩, 支持正负数
2.TAG标识可获取原始基本类型
2.支持序列化写入流和反序列化读取流
代码分享
package axj.seri.abuf;
import axj.kt.KtB;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
/**
* Created with IDEA
*
* [@author](https://my.oschina.net/arthor):absir
* [@Date](https://my.oschina.net/u/2504391) 2019-08-14 13:45
*/
public class ABufOut {
final OutputStream out;
boolean writeStrEmpty;
OutBuf buf;
public static class OutBuf extends ByteArrayOutputStream {
public byte[] getBuf() {
return buf;
}
}
public ABufOut(OutputStream out) {
this.out = out;
}
public void writeInt(int i) throws IOException {
writeI(out, 0, i);
}
public void writeLong(long l) throws IOException {
writeL(out, 0, l);
}
public void writeString(CharSequence str) throws IOException {
if (str == null) {
writeNil();
} else {
int len = str.length();
writeI(out, TAG_STRI, len);
for (int i = 0; i < len; i++) {
writeInt(str.charAt(i));
}
}
}
public void writeBytes(byte[] bytes, int off, int len) throws IOException {
if (bytes == null) {
writeNil();
} else {
writeI(out, TAG_SPEC, SPEC_BUF);
if (len > off) {
writeI(out, 0, len - off);
out.write(bytes, off, len);
} else {
writeI(out, 0, 0);
}
}
}
public ByteArrayOutputStream buf() {
if (buf == null) {
buf = new OutBuf();
} else {
buf.reset();
}
return buf;
}
public void writeBuf() throws IOException {
writeI(out, TAG_SPEC, SPEC_BUF);
int len = buf == null ? 0 : buf.size();
writeI(out, 0, len);
out.write(buf.getBuf(), 0, len);
}
public void writeNil() throws IOException {
writeI(out, TAG_SPEC, SPEC_NIL);
}
public void writeLst() throws IOException {
writeI(out, TAG_SPEC, SPEC_LST);
}
public void writeMap() throws IOException {
writeI(out, TAG_SPEC, SPEC_MAP);
}
public void writeEnd() throws IOException {
writeI(out, TAG_SPEC, SPEC_END);
}
public void writeObject(Object val) throws Exception {
ABuf.ME.writeObject(val, this);
}
static class InBuf extends InputStream {
final InputStream in;
int max;
InBuf(InputStream in) {
this.in = in;
}
[@Override](https://my.oschina.net/u/1162528)
public int available() throws IOException {
return Math.max(max, in.available());
}
[@Override](https://my.oschina.net/u/1162528)
public int read() throws IOException {
if (max <= 0) {
return -1;
}
max--;
return in.read();
}
}
public enum ERead {
/**
* 数组
*/
LST,
/**
* 字典
*/
MAP,
/**
* 结束
*/
END,
}
/**
* Created with IDEA
*
* [@author](https://my.oschina.net/arthor):absir
* @Date 2019-08-14 13:45
*/
public static class ABufIn {
final InputStream in;
// 预加载bytes
int pByte = -1;
boolean merge;
boolean skip;
int tag;
StringBuilder sb;
InBuf inBuf;
int rtI;
long rtL;
// 返回为空
boolean rtNil;
// 结构深度
int inDepth;
public int getTag() {
return tag;
}
public boolean isRtNil() {
return rtNil;
}
public int getInDepth() {
return inDepth;
}
public ABufIn(InputStream in) {
this.in = in;
}
protected int maxLen() {
return 10485760;
}
protected StringBuilder getSb(int len) throws IOException {
if (len > maxLen()) {
throw new IOException("read len max " + len);
}
if (sb == null) {
sb = new StringBuilder(len);
}
sb.setLength(len);
return sb;
}
/**
* @param l long类型
* @param bs 返回数组
* @return
* @throws IOException
*/
public Object readNext(boolean l, boolean bs) throws IOException {
skipBuf();
rtNil = false;
if (l) {
rtL = readL(pByte, in, this);
pByte = -1;
if (tag <= TAG_NEGA) {
return null;
}
rtI = (int) rtL;
} else {
rtI = readI(pByte, in, this);
pByte = -1;
if (tag <= TAG_NEGA) {
return null;
}
}
if (tag == TAG_STRI) {
if (skip) {
skipLen(rtI);
return null;
} else {
if (rtI == 0) {
return KtB.STR;
}
int len = rtI;
getSb(len);
for (int i = 0; i < len; i++) {
sb.setCharAt(i, (char) readInt());
}
tag = TAG_STRI;
rtI = len;
return sb.toString();
}
} else {
switch (rtI) {
case SPEC_NIL:
if (!skip) {
rtNil = true;
}
return null;
case SPEC_BUF:
int len = readI(pByte, in, this);
tag = TAG_SPEC;
if (skip) {
skipLen(len);
return null;
} else {
if (bs) {
// 读取bytes
if (len == 0) {
return KtB.BYTES;
}
if (len > maxLen()) {
throw new IOException("read len max " + len);
}
byte[] buf = new byte[len];
for (int i = 0; i < len; i++) {
buf[i] = (byte) in.read();
}
return buf;
} else {
// 读取流
if (inBuf == null) {
inBuf = new InBuf(in);
}
inBuf.max = len;
return inBuf;
}
}
case SPEC_LST:
inDepth++;
return ERead.LST;
case SPEC_MAP:
inDepth++;
return ERead.MAP;
case SPEC_END:
inDepth--;
return ERead.END;
default:
return null;
}
}
}
protected void skipLen(int len) throws IOException {
for (int i = 0; i < len; i++) {
in.read();
}
}
public void skipBuf() throws IOException {
if (inBuf != null) {
while (inBuf.read() >= 0) ;
}
}
protected void skipDepth() throws IOException {
boolean skipO = skip;
int depthO = inDepth;
skip = true;
while (true) {
if (readNext(false, false) == ERead.END && inDepth < depthO) {
break;
}
}
// 恢复跳过状态
skip = skipO;
}
protected void skipRetr(Object retr) throws IOException {
if (retr == ERead.LST || retr == ERead.MAP) {
skipDepth();
} else {
skipBuf();
}
}
public int readInt() throws IOException {
Object retr = readNext(false, false);
if (tag <= TAG_NEGA) {
return rtI;
}
if (tag == TAG_STRI) {
return Integer.parseInt((String) retr);
}
skipRetr(retr);
return 0;
}
public long readLong() throws IOException {
Object retr = readNext(true, false);
if (tag <= TAG_NEGA) {
return rtL;
}
if (tag == TAG_STRI) {
return Long.parseLong((String) retr);
}
skipRetr(retr);
return 0;
}
public String readString() throws IOException {
Object retr = readNext(false, false);
switch (tag) {
case TAG_STRI:
return (String) retr;
case TAG_POSI:
case TAG_NEGA:
return String.valueOf(rtI);
}
skipRetr(retr);
return null;
}
public byte[] readBytes() throws IOException {
Object retr = readNext(false, true);
if (tag == TAG_SPEC && rtI == SPEC_BUF) {
return (byte[]) retr;
}
skipRetr(retr);
return null;
}
public InputStream readBuf() throws IOException {
Object retr = readNext(false, false);
if (tag == TAG_SPEC && rtI == SPEC_BUF) {
return inBuf;
}
skipRetr(retr);
return null;
}
public boolean readEnd() throws IOException {
pByte = in.read();
if (pByte == END_BYTE) {
pByte = -1;
return true;
}
return false;
}
public Object readObject(Type type) throws Exception {
return ABuf.ME.readObject(this, type);
}
}
static final int VINT_N = 0x80;
static final int VINT = VINT_N - 1;
static final int VINT0 = VINT >> 2;
/**
* 正数
*/
static final int TAG_POSI = 0;
/**
* 负数
*/
static final int TAG_NEGA = 1;
/**
* 字符串
*/
static final int TAG_STRI = 2;
/**
* 特殊定义
*/
static final int TAG_SPEC = 3;
/**
* 空值
*/
static final int SPEC_NIL = 0;
/**
* 数组
*/
static final int SPEC_BUF = 1;
/**
* 数组
*/
static final int SPEC_LST = 2;
/**
* 字典
*/
static final int SPEC_MAP = 3;
/**
* 结束
*/
static final int SPEC_END = 4;
/**
* 结束BYTE
*/
static final int END_BYTE = SPEC_END | (TAG_SPEC << 5);
static void writeI(OutputStream out, int tag, int i) throws IOException {
if (i < 0) {
tag = TAG_NEGA;
i = -i;
}
int b = i & VINT0;
if (tag != 0) {
b |= tag << 5;
}
i >>= 5;
while (true) {
if (i <= 0) {
out.write(b);
break;
} else {
b |= VINT_N;
out.write(b);
}
b = i & VINT;
i >>= 7;
}
}
static void writeL(OutputStream out, int tag, long l) throws IOException {
if (l < 0) {
tag = TAG_NEGA;
l = -l;
}
int b = (byte) (l & VINT0);
if (tag != 0) {
b |= tag << 5;
}
l >>= 5;
while (true) {
if (l <= 0) {
out.write(b);
break;
} else {
b |= VINT_N;
out.write(b);
}
b = (byte) (l & VINT);
l >>= 7;
}
}
static int readI(int b, InputStream in, ABufIn bufIn) throws IOException {
if (b < 0) {
b = in.read();
}
if (b < 0) {
throw new IOException("read stream ended");
}
int tag = (b & VINT) >> 5;
int i = b & VINT0;
if (bufIn != null) {
bufIn.tag = tag;
}
int p = 5;
while (true) {
if ((b & VINT_N) == 0) {
return tag == TAG_NEGA ? -i : i;
}
b = in.read();
i += (b & VINT) << p;
p += 7;
}
}
static long readL(int b, InputStream in, ABufIn bufIn) throws IOException {
if (b < 0) {
b = in.read();
}
if (b < 0) {
throw new IOException("read stream ended");
}
int tag = (b & VINT) >> 5;
long l = b & VINT0;
if (bufIn != null) {
bufIn.tag = tag;
}
int p = 5;
while (true) {
if ((b & VINT_N) == 0) {
return tag == TAG_NEGA ? -l : l;
}
b = in.read();
l += ((long) (b & VINT)) << p;
p += 7;
}
}
}
package axj.seri.abuf;
import axj.an.AInject;
import axj.ioc.APro;
import axj.kt.*;
import axj.seri.SBean;
import axj.seri.SJson;
import axj.seri.abuf.an.ABufJson;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import fastjson.ParseConfigB;
import fastjson.SerializeConfigB;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static com.alibaba.fastjson.JSON.DEFAULT_GENERATE_FEATURE;
/**
* Created with IDEA
*
* @author:absir
* @Date 2019-08-14 10:55
*/
public class ABuf extends SBean.Holder<ABuf.Att> {
static {
// 先动态添加注册ioc对象
APro.regPack(ABuf.class.getPackage().getName() + ".ap", true, false);
}
public static final ABuf ME = APro.getBean(ABuf.class);
@AInject(required = false)
IPropSFact[] facts;
static class Att {
// 字段
IPropS propS;
// 附加
Object at;
// 默认值
Object def;
// 字段
byte[] key;
}
@Override
protected Att getHolderAtt(SBean bean, SBean.Prop prop) {
if (prop.getKey() > 0) {
Field field = prop.getField();
if (field != null) {
IPropS propS = prop(prop.getClazz(), prop);
if (propS != null) {
Att att = new Att();
try {
att.propS = propS;
att.at = propS.at(prop.getClazz(), prop);
att.def = field.get(bean.getInstance());
ByteArrayOutputStream out = new ByteArrayOutputStream();
ABufOut.writeI(out, 0, prop.getKey());
att.key = out.toByteArray();
} catch (Throwable e) {
KtA.runTimeEx(e);
}
return att;
}
}
}
return null;
}
public interface IPropSFact {
/**
* 工厂模式
*
* @param prop
* @return
*/
IPropS propGet(SBean.IProp prop);
}
public interface IPropS<T> {
/**
* 附件属性
*
* @return
*/
T at(Class cls, SBean.IProp prop);
/**
* 写入
*
* @param val
* @param at
* @param out
*/
void write(Object val, T at, ABufOut out) throws Exception;
/**
* 获取绑定
*
* @param target
* @param at
* @return
* @throws Exception
*/
Object get(Object target, SBean.Prop prop, T at) throws Exception;
/**
* 读取
*
* @param merge
* @param at
* @param in
* @return
*/
Object read(Object merge, T at, ABufOut.ABufIn in) throws Exception;
}
protected IPropS prop(Class cls, SBean.Prop prop) {
if (prop != null) {
ABufJson bufJson = prop.getAtt(ABufJson.class, true);
if (bufJson != null && bufJson.value()) {
return bufJson.fastB() ? EPropS.PsJSonB : EPropS.PsJSon;
}
if (facts != null) {
for (IPropSFact fact : facts) {
IPropS propS = fact.propGet(prop);
if (propS != null) {
return propS;
}
}
}
}
if (KtCvt.as(cls, Character.class)) {
return EPropS.PsChar;
} else if (KtCvt.as(cls, Byte.class)) {
return EPropS.PsByte;
} else if (KtCvt.as(cls, Short.class)) {
return EPropS.PsShort;
} else if (KtCvt.as(cls, Integer.class)) {
return EPropS.PsInt;
} else if (KtCvt.as(cls, Long.class)) {
return EPropS.PsLong;
} else if (KtCvt.as(cls, Float.class)) {
return EPropS.PsFloat;
} else if (KtCvt.as(cls, Double.class)) {
return EPropS.PsDouble;
} else if (KtCvt.as(cls, String.class)) {
return EPropS.PsString;
} else if (cls == byte[].class) {
return EPropS.PsBytes;
} else if (cls.isEnum()) {
return EPropS.PsEnum;
} else if (cls.isArray()) {
return EPropS.PsAry;
} else if (Collection.class.isAssignableFrom(cls)) {
return EPropS.PsLst;
} else if (Map.class.isAssignableFrom(cls)) {
return EPropS.PsMap;
}
return EPropS.PsSBean;
}
static class KeyVal {
SBean.IProp prop;
IPropS val;
Object valAt;
IPropS key;
Object keyAt;
protected KeyVal(SBean.IProp prop) {
this.prop = prop;
Class cls = KtCls.raw(prop.getVType());
val = ME.prop(cls, null);
if (val == null) {
val = EPropS.PsObject;
}
valAt = val.at(cls, null);
if (prop.getOType() == SBean.EOType.Map) {
cls = KtCls.raw(prop.getKType());
key = ME.prop(cls, null);
if (key == null) {
key = EPropS.PsObject;
}
keyAt = key.at(cls, null);
}
}
}
enum EPropS implements IPropS {
PsInt {},
PsLong {
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
if (val == null) {
out.writeNil();
} else {
out.writeLong((Long) val);
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws IOException {
long l = in.readLong();
return at == Boolean.TRUE || in.isRtNil() ? null : l;
}
},
PsChar {
@Override
protected int toInt(Object val, Object at) {
return (int) (Character) (val);
}
@Override
protected Object fromInt(int i, Object at) {
return (char) i;
}
},
PsByte {
@Override
protected int toInt(Object val, Object at) {
return (int) (Byte) (val);
}
@Override
protected Object fromInt(int i, Object at) {
return (byte) i;
}
},
PsShort {
@Override
protected int toInt(Object val, Object at) {
return (int) (Short) (val);
}
@Override
protected Object fromInt(int i, Object at) {
return (short) i;
}
},
PsFloat {
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
out.writeString(val == null ? null : String.valueOf(val));
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws IOException {
String str = in.readString();
return str == null ? at == null ? 0 : null : Float.parseFloat(str);
}
},
PsDouble {
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
out.writeString(val == null ? null : String.valueOf(val));
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws IOException {
String str = in.readString();
return str == null ? at == null ? 0 : null : Double.parseDouble(str);
}
},
PsString {
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
out.writeString((CharSequence) val);
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws IOException {
return in.readString();
}
},
PsBytes {
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
byte[] bytes = (byte[]) val;
out.writeBytes(bytes, 0, bytes == null ? 0 : bytes.length);
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws IOException {
return in.readBytes();
}
},
PsEnum {
@Override
public Object at(Class cls, SBean.IProp prop) {
return SBean.enumKeys(cls);
}
@Override
public void write(Object val, Object at, ABufOut out) throws IOException {
if (val != null) {
for (SBean.EnumKey key : (SBean.EnumKey[]) at) {
if (val == key.en) {
out.writeInt(key.k);
return;
}
}
}
out.writeNil();
}
@Override
protected Object fromInt(int i, Object at) {
for (SBean.EnumKey key : (SBean.EnumKey[]) at) {
if (i == key.k) {
return key.en;
}
}
return null;
}
},
PsSBean {
@Override
public Object at(Class cls, SBean.IProp prop) {
SBean sBean = SBean.getSBean(cls, true);
if (sBean == null) {
throw new RuntimeException("PsSBean not match " + cls);
}
return sBean;
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
ME.write(val, (SBean) at, out);
}
@Override
public Object get(Object target, SBean.Prop prop, Object at) throws Exception {
return prop.getPubly(target, false, false);
}
@Override
public Object read(Object target, Object at, ABufOut.ABufIn in) throws Exception {
return ME.read(target, (SBean) at, in);
}
},
PsObject {
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
ME.writeObject(val, out);
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
return ME.readObject(in, null);
}
},
PsAry {
@Override
public Object at(Class cls, SBean.IProp prop) {
return new KeyVal(prop);
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
KeyVal keyVal = (KeyVal) at;
out.writeLst();
int len = Array.getLength(val);
for (int i = 0; i < len; i++) {
keyVal.val.write(Array.get(val, i), keyVal.valAt, out);
}
out.writeEnd();
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
KeyVal keyVal = (KeyVal) at;
return SBinder.ME.to(ME.readLstA(merge, keyVal, true, in), keyVal.prop.getClazz());
}
},
PsLst {
@Override
public Object at(Class cls, SBean.IProp prop) {
return new KeyVal(prop);
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
KeyVal keyVal = (KeyVal) at;
out.writeLst();
for (Object v : (Collection) val) {
keyVal.val.write(v, keyVal.valAt, out);
}
out.writeEnd();
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
KeyVal keyVal = (KeyVal) at;
return ME.readLstA(merge, keyVal, false, in);
}
},
PsMap {
@Override
public Object at(Class cls, SBean.IProp prop) {
return new KeyVal(prop);
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
KeyVal keyVal = (KeyVal) at;
out.writeMap();
for (Map.Entry entry : ((Map<?, ?>) val).entrySet()) {
keyVal.key.write(entry.getKey(), keyVal.keyAt, out);
keyVal.val.write(entry.getValue(), keyVal.valAt, out);
}
out.writeEnd();
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
KeyVal keyVal = (KeyVal) at;
Object retr = in.readNext(false, false);
if (retr == ABufOut.ERead.MAP) {
Map map = KtCvt.ToMap.newTo(keyVal.prop, keyVal.prop.getClazz(), 1);
while (!in.readEnd()) {
map.put(keyVal.key.read(merge, keyVal.keyAt, in), keyVal.val.read(merge, keyVal.valAt, in));
}
return map;
}
in.skipRetr(retr);
return null;
}
},
PsJSon {
@Override
public Object at(Class cls, SBean.IProp prop) {
return prop.getType();
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
SJson.ME().writeJSONString(out.buf(), val);
out.writeBuf();
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
InputStream inp = in.readBuf();
return inp == null ? null : SJson.ME().parseObject(inp, (Type) at);
}
},
PsJSonB {
@Override
public Object at(Class cls, SBean.IProp prop) {
return prop.getType();
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
JSON.writeJSONString(out.buf(), KtIo.utf8(), val, SerializeConfigB.ME, null, null, DEFAULT_GENERATE_FEATURE, SerializerFeature.WriteNonStringKeyAsString);
out.writeBuf();
}
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
InputStream inp = in.readBuf();
return inp == null ? null : JSON.parseObject(inp, KtIo.utf8(), (Type) at, ParseConfigB.ME, Feature.AllowUnQuotedFieldNames);
}
},
;
@Override
public Object at(Class cls, SBean.IProp prop) {
return Object.class.isAssignableFrom(cls) ? Boolean.TRUE : null;
}
@Override
public void write(Object val, Object at, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
out.writeInt(toInt(val, at));
}
}
protected int toInt(Object val, Object at) {
return (int) val;
}
@Override
public Object get(Object target, SBean.Prop prop, Object at) throws Exception {
return null;
}
@Override
public Object read(Object merge, Object at, ABufOut.ABufIn in) throws Exception {
int i = in.readInt();
return in.isRtNil() && at != null ? null : fromInt(i, at);
}
protected Object fromInt(int i, Object at) {
return i;
}
}
protected void write(Object target, SBean sBean, ABufOut out) throws Exception {
if (target == null) {
out.writeNil();
} else {
out.writeMap();
Att att;
for (SBean.Prop prop : sBean.props()) {
att = prop.getHolderAtt(ME);
if (att != null) {
Object v = prop.getPubly(target, false, false);
if (v != null && !v.equals(att.def)) {
if (att.propS == EPropS.PsString && !out.writeStrEmpty && ((String) v).length() == 0) {
continue;
}
// 写入字段
out.out.write(att.key);
att.propS.write(v, att.at, out);
}
}
}
out.writeEnd();
}
}
protected Object read(Object target, SBean sBean, ABufOut.ABufIn in) throws Exception {
Object retr = in.readNext(false, false);
if (retr == ABufOut.ERead.MAP) {
return readB(target, sBean, in);
}
in.skipRetr(retr);
return null;
}
protected Object readB(Object target, SBean sBean, ABufOut.ABufIn in) throws Exception {
if (target == null) {
target = sBean.newInstance();
}
while (!in.readEnd()) {
in.readNext(false, false);
if (in.tag != ABufOut.TAG_POSI) {
throw new IOException("read key tag err " + in.tag);
}
SBean.Prop prop = sBean.getPropKey(in.rtI);
Att att = prop == null ? null : prop.getHolderAtt(ME);
if (att == null) {
in.skipRetr(in.readNext(false, false));
} else {
Object merge = in.merge ? att.propS.get(target, prop, att.at) : null;
Object to = att.propS.read(merge, att.at, in);
if (!in.merge || to != merge) {
// 赋值
prop.setPubly(target, false, false, to, null);
}
}
}
return target;
}
protected void writeObject(Object val, ABufOut out) throws Exception {
if (val == null) {
out.writeNil();
} else {
Class cls = val.getClass();
if (Number.class.isAssignableFrom(cls)) {
if (cls == Long.class) {
out.writeLong((Long) val);
} else if (cls == Float.class || cls == Double.class) {
out.writeString(val.toString());
} else {
out.writeInt(((Number) val).intValue());
}
} else if (CharSequence.class.isAssignableFrom(cls)) {
out.writeString((CharSequence) val);
} else if (Map.class.isAssignableFrom(cls)) {
out.writeMap();
for (Map.Entry<?, ?> entry : ((Map<?, ?>) val).entrySet()) {
writeObject(entry.getKey(), out);
writeObject(entry.getValue(), out);
}
out.writeEnd();
} else if (Collection.class.isAssignableFrom(cls)) {
out.writeLst();
for (Object v : (Collection) val) {
writeObject(v, out);
}
out.writeEnd();
} else if (cls.isArray()) {
out.writeLst();
int len = Array.getLength(val);
for (int i = 0; i < len; i++) {
writeObject(Array.get(val, i), out);
}
out.writeEnd();
} else if (cls.isEnum()) {
EPropS.PsEnum.write(val, SBean.enumKeys(cls), out);
} else {
SBean sBean = SBean.getSBean(cls, true);
if (sBean == null) {
throw new IOException("write no support at " + cls);
} else {
write(val, sBean, out);
}
}
}
}
protected Object readObject(ABufOut.ABufIn in, Type type) throws Exception {
Object retr = in.readNext(true, true);
if (in.tag <= ABufOut.TAG_NEGA) {
return SBinder.ME.to(in.rtL, type, null);
}
if (in.tag == ABufOut.TAG_SPEC) {
if (in.rtI == ABufOut.SPEC_MAP) {
Class cls = KtCls.raw(type);
SBean sBean = SBean.getSBean(cls, true);
if (sBean == null) {
Type vType = null;
Type kType = null;
if (cls != null && Map.class.isAssignableFrom(cls)) {
vType = KtCls.typeVar(type, KtCvt.MapV);
kType = KtCls.typeVar(type, KtCvt.MapK);
}
// 返回map
Map map = new HashMap();
while (!in.readEnd()) {
map.put(readObject(in, kType), readObject(in, vType));
}
return map;
} else {
// 返回bean
return readB(null, sBean, in);
}
} else if (in.rtI == ABufOut.SPEC_LST) {
Class cls = KtCls.raw(type);
Type vType = type != null || Collection.class.isAssignableFrom(cls) ? KtCls.typeVar(type, KtCvt.ListT) : null;
// 返回list
Collection list = KtCvt.ToList.newTo(null, cls, 1);
while (!in.readEnd()) {
list.add(readObject(in, vType));
}
return SBinder.ME.to(list, type, null);
}
}
if (retr instanceof ABufOut.ERead) {
retr = null;
}
return SBinder.ME.to(retr, type, null);
}
protected Collection readLstA(Object merge, KeyVal keyVal, boolean ary, ABufOut.ABufIn in) throws Exception {
Object retr = in.readNext(false, false);
if (retr == ABufOut.ERead.LST) {
Collection list = ary ? new ArrayList(1) : KtCvt.ToList.newTo(keyVal.prop, keyVal.prop.getClazz(), 1);
while (!in.readEnd()) {
list.add(keyVal.val.read(merge, keyVal.valAt, in));
}
return list;
}
in.skipRetr(retr);
return null;
}
public static byte[] toBytes(Object object) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ME.writeObject(object, new ABufOut(out));
return out.toByteArray();
}
public static <T> T fromBytes(byte[] bytes, Class<T> cls) throws Exception {
return SBinder.ME.to(ME.readObject(new ABufOut.ABufIn(new ByteArrayInputStream(bytes)), cls), cls);
}
}