序列化库MessagePack应用(C++)

介绍

MessagePack(简称msgpack)是一个小巧而高效的序列化/反序列化库,支持多种开发语言。官方网站:http://msgpack.org/ios

下面是官方的一个简介:数据结构

It's like JSON.
but fast and small.

MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages 
like JSON. But it's faster and smaller. Small integers are encoded into a single byte
, and typical short
strings require only one extra byte in addition to the strings themselves.

 

msgpack支持很是多的开发语言,这篇随笔只讨论在C++代码中的调用。网站

 

序列化键值对数据

一个常常遇到的应用场景是,咱们须要序列化一组键值对。这组键值对的大小是可变的,值类型也不肯定,例如:ui

key name  key type value type
type string int
ratio string double
msg string string

 

示例代码以下:spa

 1 /*
 2  * msgpack C++试验:序列化/反序列化大小可变的非标准map.
 3  * Author: 赵子清
 4  * Blog: http://www.cnblogs.com/zzqcn
 5  *
 6  * */
 7 
 8 
 9 #include <msgpack.hpp>
10 #include <string>
11 #include <cstring>
12 #include <iostream>
13 using namespace std;
14 
15 int main(int argc, char** argv)
16 {
17 
18     msgpack::sbuffer  sbuf;
19     msgpack::packer<msgpack::sbuffer>   pker(&sbuf);
20 
21     // 序列化
22     pker.pack_map(3);
23     pker.pack(string("type"));
24     pker.pack(3);
25     pker.pack(string("ratio"));
26     pker.pack(2.15);
27     pker.pack(string("msg"));
28     pker.pack(string("hello world"));
29 
30     // 反序列化
31     msgpack::unpacked  unpack;
32     msgpack::unpack(&unpack, sbuf.data(), sbuf.size());
33 
34     // 直接输出结果
35     msgpack::object  obj = unpack.get();
36     cout << obj << endl;
37 
38     // 访问具体键值对
39     msgpack::object_kv*  pkv;
40     msgpack::object_kv*  pkv_end;
41     msgpack::object      pk, pv;
42     if(obj.via.map.size > 0)
43     {
44         pkv = obj.via.map.ptr;
45         pkv_end = obj.via.map.ptr + obj.via.map.size;
46 
47         do
48         {
49             pk = pkv->key;
50             pv = pkv->val;
51             
52             cout << pk << ", " << pv << endl;
53 
54             ++pkv;
55         }
56         while (pkv < pkv_end);
57     }
58 
59     return 0;
60 }

输出结果:指针

{"type"=>3, "ratio"=>2.15, "msg"=>"hello world"}
"type", 3
"ratio", 2.15
"msg", "hello world"


 

序列化自定义类型

msgpack已支持了不少的标准类型,但有时咱们会本身定义新的类型,这时,咱们必须对新类型作某些修改,以使msgpack能够操做它。code

另外,若是你的类型中含有低层指针,则还须要进行一些处理,不然,msgpack只会进行浅拷贝,没法序列化指针所指向的内存数据。orm

假设咱们本来的类型以下:blog

struct Foo
{
    int  i;
    string  str;
    char*  data;
};

那么要让msgpack操做它,应修改成以下结构:ip

struct Foo
{
    int     i;
    string  str;
    // 原始指针类型,内部封装了pack_raw和pack_raw_body方法
    msgpack::type::raw_ref  data;

    MSGPACK_DEFINE(i, str, data); 
};


下面是完整示例代码:

 1 /*
 2  * msgpack C++试验:序列化/反序列化自定义数据结构.
 3  * Author: 赵子清
 4  * Blog: http://www.cnblogs.com/zzqcn
 5  * */
 6 
 7 
 8 #include <msgpack.hpp>
 9 #include <string>
10 #include <cstring>
11 #include <iostream>
12 using namespace std;
13 
14 
15 struct Foo
16 {
17     int     i;
18     string  str;
19     // 原始指针类型,内部封装了pack_raw和pack_raw_body方法
20     msgpack::type::raw_ref  data;
21 
22     MSGPACK_DEFINE(i, str, data); 
23 };
24 
25 
26 int main(int argc, char** argv)
27 {
28     Foo  f;
29     f.i = 4;
30     f.str = "hello world";
31     const char* tmp = "msgpack";
32     f.data.ptr = tmp;
33     f.data.size = strlen(tmp) + 1;
34 
35     msgpack::sbuffer  sbuf;
36     msgpack::pack(sbuf, f);
37 
38     msgpack::unpacked  unpack;
39     msgpack::unpack(&unpack, sbuf.data(), sbuf.size());
40 
41     msgpack::object  obj = unpack.get();
42 
43     Foo f2;
44     obj.convert(&f2);
45 
46     cout << f2.i << ", " << f2.str << ", ";
47     cout << f2.data.ptr << endl;
48 
49     return 0;
50 }

 输出结果:

4, hello world, msgpack
相关文章
相关标签/搜索