一、简单介绍msgpack
1)原理
基本编码格式,核心压缩方式可参看官方说明messagepack specification
Overview
format name | first byte (in binary) | first byte (in hex) |
---|---|---|
positive fixint | 0xxxxxxx | 0x00 - 0x7f |
fixmap | 1000xxxx | 0x80 - 0x8f |
fixarray | 1001xxxx | 0x90 - 0x9f |
fixstr | 101xxxxx | 0xa0 - 0xbf |
nil | 11000000 | 0xc0 |
(never used) | 11000001 | 0xc1 |
false | 11000010 | 0xc2 |
true | 11000011 | 0xc3 |
bin 8 | 11000100 | 0xc4 |
bin 16 | 11000101 | 0xc5 |
bin 32 | 11000110 | 0xc6 |
ext 8 | 11000111 | 0xc7 |
ext 16 | 11001000 | 0xc8 |
ext 32 | 11001001 | 0xc9 |
float 32 | 11001010 | 0xca |
float 64 | 11001011 | 0xcb |
uint 8 | 11001100 | 0xcc |
uint 16 | 11001101 | 0xcd |
uint 32 | 11001110 | 0xce |
uint 64 | 11001111 | 0xcf |
int 8 | 11010000 | 0xd0 |
int 16 | 11010001 | 0xd1 |
int 32 | 11010010 | 0xd2 |
int 64 | 11010011 | 0xd3 |
fixext 1 | 11010100 | 0xd4 |
fixext 2 | 11010101 | 0xd5 |
fixext 4 | 11010110 | 0xd6 |
fixext 8 | 11010111 | 0xd7 |
fixext 16 | 11011000 | 0xd8 |
str 8 | 11011001 | 0xd9 |
str 16 | 11011010 | 0xda |
str 32 | 11011011 | 0xdb |
array 16 | 11011100 | 0xdc |
array 32 | 11011101 | 0xdd |
map 16 | 11011110 | 0xde |
map 32 | 11011111 | 0xdf |
negative fixint | 111xxxxx |
2) 解析数据类型
// msg数据类型,在源码object.h里面可以直接看到
typedef enum {
MSGPACK_OBJECT_NIL = 0x00,
MSGPACK_OBJECT_BOOLEAN = 0x01,
MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02,
MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03,
MSGPACK_OBJECT_FLOAT32 = 0x0a,
MSGPACK_OBJECT_FLOAT64 = 0x04,
MSGPACK_OBJECT_FLOAT = 0x04,
#if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
MSGPACK_OBJECT_DOUBLE = MSGPACK_OBJECT_FLOAT, /* obsolete */
#endif /* MSGPACK_USE_LEGACY_NAME_AS_FLOAT */
MSGPACK_OBJECT_STR = 0x05,
MSGPACK_OBJECT_ARRAY = 0x06,
MSGPACK_OBJECT_MAP = 0x07,
MSGPACK_OBJECT_BIN = 0x08,
MSGPACK_OBJECT_EXT = 0x09
} msgpack_object_type;
struct msgpack_object; // 数据类型对象
struct msgpack_object_kv; // map数据类型的key和value的对像
// 类型为数组类型的数据结构
typedef struct {
uint32_t size;
struct msgpack_object* ptr;
} msgpack_object_array;
// 数据类型为map的数据结构
typedef struct {
uint32_t size;
struct msgpack_object_kv* ptr;
} msgpack_object_map;
// 数据类型为str
typedef struct {
uint32_t size; //对应的str长度
const char* ptr; // 指向str的数据,该数据不一定有结束符
} msgpack_object_str;
typedef struct {
uint32_t size;
const char* ptr;
} msgpack_object_bin;
typedef struct {
int8_t type;
uint32_t size;
const char* ptr;
} msgpack_object_ext;
typedef union {
bool boolean;
uint64_t u64;
int64_t i64;
#if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT)
double dec; /* obsolete*/
#endif /* MSGPACK_USE_LEGACY_NAME_AS_FLOAT */
double f64;
msgpack_object_array array;
msgpack_object_map map;
msgpack_object_str str;
msgpack_object_bin bin;
msgpack_object_ext ext;
} msgpack_object_union;
typedef struct msgpack_object {
msgpack_object_type type; // 该对象的数据类型
msgpack_object_union via; // 具体存放的数据
} msgpack_object;
typedef struct msgpack_object_kv {
msgpack_object key; // 存放map的key值
msgpack_object val; // 存放map的value值
} msgpack_object_kv;
3)简单分析msgpack例子
一个简单的例子:
json格式:{"age":14, "subject":["math", "chinese", "english"]}
msgpack格式: 82 a3 61 67 65 0e a7 73 75 62 6a 65 63 74 93 a4 6d 61 74 68 a7 63 68 69 6e 65 73 65 a7 65 6e 67 6c 69 73 68
msgpack : 82 a3 61 67 65 0e a7 73 75 62 6a 65 63 74 93 a4 6d 61 74 68 a7 63 68 69 6e 65 73 65 a7 65 6e 67 6c 69 73 68
82 :两组map,即两组key-value pairs of objects
a3 61 67 65 :第一组map的key,类型为fixstr为 "age"
0e :第一组map的value,类型为positive fixint为14
a7 73 75 62 6a 65 63 74 :第二组map的key,类型为fixstr为“subject”
93 a4 6d 61 74 68 a7 63 68 69 6e 65 73 65 a7 65 6e 67 6c 69 73 68 :第二组map的value是个array,元素内容为str
93:有三组的数据的数组
a4 6d 61 74 68:第一个数组对象类型为fixstr为"math"
a7 63 68 69 6e 65 73 65 :第二个数组对象类型为fixstr为"chinese"
a7 65 6e 67 6c 69 73 68:第三个数组对象类型为fixstr为"english"
二、Msgpack的解析存储结构
例子:
json : {"age":14, "subject":["math", "chinese", "english"]}
msgpack:82 a3 61 67 65 0e a7 73 75 62 6a 65 63 74 93 a4 6d 61 74 68 a7 63 68 69 6e 65 73 65 a7 65 6e 67 6c 69 73 68
map | 类型 | 值 |
value | .type(0x82) | MSGPACK_OBJECT_MAP |
.via.map.size | 0(如果全部加载完变为2) | |
.via.map.ptr | 指向分配的内存的大小为2*sizeof(msgpack_object_kv),用存放接下来的2个map,即map.ptr[0]、map.ptr[1] |
map.size=1; map.ptr[0] | 类型 | 值 |
key | .type(a3) | MSGPACK_OBJECT_STR |
.via.str.size | 3 | |
.via.str.ptr(61 67 65) | 指向”age” | |
value | .type(0e) | MSGPACK_OBJECT_POSITIVE_INTEGER |
.via.u64 | 14 |
map.size=2; map.ptr[1] | 类型 | 值 |
key | .type(a7) | MSGPACK_OBJECT_STR |
.via.str.size | 7 | |
.via.str.ptr(73 75 62 6a 65 63 74) | 指向”subject” | |
value | .type(93) | MSGPACK_OBJECT_ARRAY |
.via.array.size | 0(如果全部加载完变为3) | |
.via.array.ptr | 指向分配的内存的大小为3*sizeof(msgpack_object),用存放接下来的三个元素,即array.ptr[0]、array.ptr[1]、array.ptr[2] |
array | 类型 | 值 |
array.size=1 array.ptr[0] | .type(a4) | MSGPACK_OBJECT_STR |
.via.str.size | 4 | |
.via.str.ptr(6d 61 74 68) | 指向”math” | |
array.size=2 array.ptr[1] | .type(a7) | MSGPACK_OBJECT_STR |
.via.str.size | 7 | |
.via.str.ptr(63 68 69 6e 65 73 65) | 指向”chinese” | |
array.size=3 array.ptr[2] | .type(a7) | MSGPACK_OBJECT_STR |
.via.str.size | 7 | |
.via.str.ptr(65 6e 67 6c 69 73 68) | 指向”english” |
图形描述: