Serialize
Zeze有一个很小的自己的序列化实现。麻雀虽小五脏俱全。 Zeze.Transaction.Bean是在ByteBuffer基础上构建的一套对象序列化实现。 主要涉及以下三个类:
- Zeze.Serialize.Serializable 接口
- Zeze.Serialize.IByteBuffer 接口(目前只用于提供ByteBuffer的只读方法)
- Zeze.Serialize.ByteBuffer 实现
以下是序列化标准的定义:
类型枚举(4-bit)
- 0: 有符号整数(byte,short,int,long,bool)
- 1: 单精度浮点数(float)
- 2: 双精度浮点数(double)
- 3: 二进制数据/字符串(binary,string)
- 4: 序列容器(list,set)
- 5: 关联容器(map)
- 6: bean
- 7: 动态bean(dynamic)
- 8: vector2(float*2)
- 9: vector2int(int*2)
- 10: vector3(float*3)
- 11: vector3int(int*3)
- 12: vector4(float*4)
- 13~15: 可自行扩展定义非标准类型
整数压缩
比如:用户定义了long类型,当值小于64时,仅用一个字节保存。
* 有符号整数(支持64位补码有符号整数的所有值)
正整数:
1字节(< 0x 40): 00xx xxxx (取低有效位,按大端排列)
2字节(< 0x 2000): 010x xxxx +1B
3字节(< 0x 10 0000): 0110 xxxx +2B
4字节(< 0x 800 0000): 0111 0xxx +3B
5字节(< 0x 4 0000 0000): 0111 10xx +4B
6字节(< 0x 200 0000 0000): 0111 110x +5B
7字节(< 0x 1 0000 0000 0000): 0111 1110 +6B
8字节(< 0x80 0000 0000 0000): 0111 1111 0xxx xxxx +6B
9字节( unlimited): 0111 1111 1xxx xxxx +7B
负整数:
1字节(>=-0x 40): 11xx xxxx
2字节(>=-0x 2000): 101x xxxx +1B
3字节(>=-0x 10 0000): 1001 xxxx +2B
4字节(>=-0x 800 0000): 1000 1xxx +3B
5字节(>=-0x 4 0000 0000): 1000 01xx +4B
6字节(>=-0x 200 0000 0000): 1000 001x +5B
7字节(>=-0x 1 0000 0000 0000): 1000 0001 +6B
8字节(>=-0x80 0000 0000 0000): 1000 0000 1xxx xxxx +6B
9字节( unlimited): 1000 0000 0xxx xxxx +7B
* 无符号整数(支持32位无符号整数的所有值)
仅用于序列化长度,数量,增量等特定情况
1字节(<0x 80): 0xxx xxxx (取低有效位,按大端排列)
2字节(<0x 4000): 10xx xxxx +1B
3字节(<0x 20 0000): 110x xxxx +2B
4字节(<0x1000 0000): 1110 xxxx +3B
5字节( unlimited): 1111 0000 +4B
布尔(bool)
- 与有符号整数的序列化兼容
- 序列化时false当作0,true当作1; 反序列化时0当作false,其余当作true
单精度浮点数(float)
- 按IEEE754标准序列化成小端排列的固定4个字节
双精度浮点数(double)
- 按IEEE754标准序列化成小端排列的固定8个字节
二进制数据(binary)
- 无符号整数: 数据的字节长度
- 数据的原始内容
字符串(string)
- 按二进制数据序列化字符串的UTF-8编码数据
序列容器(list,set)
- 单字节: (高位)nnnn tttt(低位)
- t: 容器元素的类型枚举
- n=0~14: 容器元素的数量
- n=15: 附加一个无符号整数(x),用15+x表示容器元素的数量
- 按以上指定类型及枚举顺序连续序列化容器的所有元素
关联容器(map)
- 单字节: (高位)kkkk vvvv(低位)
- k: 容器键(key)的类型枚举
- v: 容器值(value)的类型枚举
- 无符号整数: 容器键值对的数量
- 按以上指定类型及枚举顺序连续序列化容器的所有键值, 即”键值键值…“的顺序
二维浮点向量类型(vector2)
- 按float类型序列化x字段
- 按float类型序列化y字段
二维整数向量类型(vector2int)
- 按有符号整数类型序列化x字段
- 按有符号整数类型序列化y字段
三维浮点向量类型(vector3)
- 按float类型序列化x字段
- 按float类型序列化y字段
- 按float类型序列化z字段
三维整数向量类型(vector3int)
- 按有符号整数类型序列化x字段
- 按有符号整数类型序列化y字段
- 按有符号整数类型序列化z字段
四维浮点向量类型(vector4)
- 按float类型序列化x字段
- 按float类型序列化y字段
- 按float类型序列化z字段
- 按float类型序列化w字段
字段标签(tag)
- 单字节: (高位)iiii tttt(低位)
- i=0: 特殊含义
- t=0: 结束标签
- t=1: 结束当前层的标签,后续是上一层(父类)的序列化
- t=2~15: 未定义,保留扩展
- i=1~14: 距上个字段ID的增量(初始为首个字段ID), t表示字段的类型枚举
- i=15: 附加一个无符号整数(x),用15+x表示ID增量, t表示字段的类型枚举
- i=0: 特殊含义
bean
- 按”字段标签,字段值,字段标签,字段值,…,结束标签(单字节0)”的顺序序列化
- 序列化字段的顺序要求按字段ID从小到大排列, 字段ID的支持范围: [1,0x7fffffff]
- 字段值如果等于默认值,可省略该字段标签及其值的序列化
- 反序列化时要求先重置bean的所有字段为默认值再反序列化
- 有继承关系的bean要求先序列化子类字段,然后插入结束当前层的标签,再序列化上一级父类
- 默认值的定义:
- 数值=0
- 二进制数据长度=0
- 字符串长度=0
- 容器元素数量=0
- bean的所有字段均为默认值
- 动态bean为未定义值(空值)
动态bean(dynamic)
- 有符号整数: 动态bean的ID
- bean的序列化
协议帧(protocol)
- 小端排列的固定4字节无符号整数: 模块ID(moduleId)
- 小端排列的固定4字节无符号整数: 协议ID(protocolId)
- 小端排列的固定4字节无符号整数: 下面bean的序列化字节长度
- bean的序列化
关于序列化的兼容性
- 有符号整数,单精度浮点数,双精度浮点数之间可以自动转换,但要注意高位截断和降低精度问题
- binary和string之间可以互相转换,但要注意binary转到string时有无法正确解码UTF-8而抛出异常的可能
- list和set之间可以互相转换,但要注意list转成set后再序列化可能会改变顺序
- bean可以转成动态bean,默认typeId=0; 动态bean可以转换成bean,但要注意不同bean类型之间的字段兼容性
- 以上没提到的类型转换说明不兼容,反序列化会自动忽略不兼容的字段