-
Notifications
You must be signed in to change notification settings - Fork 11
tinybuf序列化协议
夏楚 edited this page Jul 6, 2021
·
3 revisions
本文旨在设计一种轻量级的序列化协议,该协议能满足轻量、可嵌入式移植、序列化反序列高性能、序列化后字节压缩度高等要求。
-
null
:未定义和赋值的类型。 -
int
:整数,可变长度整数,最大支持int64,整数又可以分成正整数负整数 -
bool
:布尔型,布尔型分为真或假 -
double
:双精度浮点型 -
string
:字符串型,可以存放二进制数据 -
map
:key-value字典数据类型 -
array
:数组型
类型 | 类型枚举值 | 解释 |
---|---|---|
null |
0 | 空类型,未定义的类型 |
positive int |
1 | 可变长度正整数 |
negtive int |
2 | 可变长度负整数 |
bool true |
3 | 布尔真 |
bool false |
4 | 布尔假 |
double |
5 | 双精度浮点型 |
string |
6 | UTF8字符串 |
map |
7 | 字典 |
array |
8 | 数组 |
- null类型固定为1个字节长度,类型值为0
- 内存布局:
0 1 2 3 4 5 6 7
+---------------+
| |
| 0(null) |
| |
+---------------+
-
可变长度正整数长度浮动不固定,采用 1 + N模式,第一个字节固定为1,表明为可变长度正整数。
-
后续字节采用小端模式排列,低位字节在前,高位字节在后。
-
每个字节的最高位
bit
表明有无后续字节,其余7bit
表明有效长度。 -
最大可表述64位有符号整数。
-
内存布局:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0
+---------------+-+-------------+---------------+---------------+
| |b| | |b| |
|1(positive int)|i| length0 | .... |i| lengthN |
| |t| | |t| |
| |0| | |N| |
+---------------+-+-------------+---------------+---------------+
-
序列化算法:
/** * 序列化整型 * @param in 整型 * @param out 序列化字节存放地址,最少预留10个字节 * @return 序列化字节长度 */ static inline int int_serialize(uint64_t in, uint8_t *out){ int index = 0; for(int i = 0; i <= (8 * sizeof(in)) / 7 ; ++i, ++index){ //取最低位7bit out[index] = in & 0x7F; //右移7位 in >>= 7; if(!in){ //剩余字节为0,最高位bit为0,停止序列化 break; } //后面还有字节,那么最高位bit为1 out[index] |= 0x80; } //返回序列化后总字节数 return ++index; }
-
反序列化算法:
/** * 反序列化整型 * @param in 输入字节流 * @param in_size 输入字节数 * @param out 序列化后的整型 * @return 代表反序列化消耗的字节数 */ static inline int int_deserialize(const uint8_t *in, int in_size, uint64_t *out){ if(in_size < 1){ return 0; } *out = 0; int index = 0; while (1){ uint8_t byte = in[index]; (*out) |= (byte & 0x7F) << ((index++) * 7); if((byte & 0x80) == 0){ //最高位为0,所以没有更多后续字节 break; } //后续还有字节 if(index >= in_size){ //字节不够,反序列失败 return 0; } if(index * 7 > 56 ){ //7bit 最多左移动56位,最大支持64位有符号整形 return -1; } } //序列号成功 return index; }
-
可变长度负整数长度浮动不固定,采用 1 + N模式,第一个字节固定为2,表明为可变长度负整数。
-
负整数在序列化时,先翻转成正整数,然后按照正整数方式序列化
-
内存布局:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0
+---------------+-+-------------+---------------+---------------+
| |b| | |b| |
|2(negtive int) |i| length0 | .... |i| lengthN |
| |t| | |t| |
| |0| | |N| |
+---------------+-+-------------+---------------+---------------+
-
布尔真类型固定为1个字节长度,类型值为3
-
内存布局:
0 1 2 3 4 5 6 7
+---------------+
| |
| 3(bool true) |
| |
+---------------+
-
布尔真类型固定为1个字节长度,类型值为4
-
内存布局:
0 1 2 3 4 5 6 7
+---------------+
| |
| 4(bool false) |
| |
+---------------+
-
双精度浮点型长度固定为9个字节,第一个字节固定为5,其余字节为double值。
-
double值为8个字节,采用大端模式排列。
-
内存布局:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 +---------------+---------------+---------------+---------------+ | | | | | | 5(double) | double[7] | double[6] | double[5] | | | | | | +---------------+- - - - - - - -+- - - - - - - -+- - - - - - - -+ | | | | | | double[4] | double[3] | double[2] | double[1] | | | | | | +- - - - - - - -+---------------+---------------+---------------+ | | | double[0] | | | +---------------+
-
字符串序列化后分成3部分。
-
第一部分固定为6表明为字符串。
-
第二部分为浮动长度的整数,表明字符串字节长度。
-
第三部分是字符串内容,不固定长度。
-
内存布局:
0 1 2 3 4 5 6 7 +---------------+------------------------------------+---------------+ | | | | | 6(string) | string length(variable length int) | string bytes | | | | | +---------------+------------------------------------+---------------+
- map序列化主要分成4部分。
- 第一个字节固定为7,表明为map
- 第二部分为浮动长度整数,表明map中key-value对个数。
- 第三部分为key-value对,其中key固定为string类型,value可能是各种类型。
- 内存布局:
0 1 2 3 4 5 6 7
+---------------+---------------------+----------+--------+-----+----------+---------+
| | | | | | | |
| 7(map) | map size N | key0 | value0 | ... | keyN-1 | valueN-1|
| |(variable length int)| (string) | | | (string) | |
+---------------+---------------------+----------+--------+-----+----------+---------+
- array序列化主要分成3部分。
- 第一个字节固定为8,表明为array
- 第二部分为浮动长度整数,表明array中元素个数。
- 第三部分为元素值,元素值可能是各种类型。
- 内存布局:
0 1 2 3 4 5 6 7
+---------------+----------------------+---------+-----+--------+
| | | | | |
| 8(array) | array size N | value0 | ... |valueN-1|
| | (variable length int)| | | |
+---------------+----------------------+---------+-----+--------+