序列化庫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
相關文章
相關標籤/搜索