2017-11-30 6 views
0

私はこれを行う方法がわからないので、C++でmsgpackを使ってext型をパックする方法のサンプルを探しています。Msgpackを使用したC++でのエクステンションタイプのパック

私が見つけた唯一の情報は、このセクションhttps://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_packer#pack-manuallyにあります。

と仮定します。Foo型のオブジェクトをアダプタクラステンプレートを持つmsgpack ext型としてパックしたいとします。 pack_extpack_ext_bodyの使い方は?テンプレート内に「サブパッカー」を作成し、Fooデータを手動でパックしてから、バイナリデータのサイズとデータ自体をpack_extpack_ext_bodyに渡す必要がありますか? C++の専門家が私に最小限の例を与えることができれば、それは創造的なものになるでしょう。事前に

MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { 
    namespace adaptor { 
     template<> 
     struct pack<Foo> { 
      template <typename Stream> 
      packer<Stream>& operator()(msgpack::packer<Stream>& o, Foo const& v) const { 
       // how to use ? 
       o.pack_ext(size_t l, int8_t type); 
       o.pack_ext_body(const char* b, size_t l); 
      } 
     } 
} 

}

ありがとう!

答えて

0

私は「サブパッカー」のアイデアを使用するようにしました。それが良いとエレガントなソリューションであるかどうかは知らないが、少なくとも、それが働いている:あなたはmsgpack::type::extまたはmsgpack::type::ext_refを使用することができます

MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { 
    namespace adaptor { 
     template<> 
     struct pack<Foo> { 
      template <typename Stream> 
      packer<Stream>& operator()(msgpack::packer<Stream>& o, Foo const& v) const { 
       msgpack::sbuffer sbuf; 
       msgpack::packer<msgpack::sbuffer> sub_packer(sbuf); 

       sub_packer.pack_map(2); 

       sub_packer.pack("name"); 
       sub_packer.pack(v.name); 

       sub_packer.pack("bar"); 
       sub_packer.pack(v.bar); 

       // get binary data from sub_packer's sbuffer 
       size_t l = sbuf.size(); 
       const char* b = sbuf.data(); 

       // pass ext type and binary data to originally packer 
       o.pack_ext(l, 1); 
       o.pack_ext_body(b, l); 

       return o; 
      } 
     } 
    } 
} 
0

彼らはここでhttps://github.com/msgpack/msgpack-c/blob/master/include/msgpack/v1/adaptor/ext.hpp

で定義されているがmsgpack::type::extの例です:

#include <sstream> 
#include <cassert> 

#include <msgpack.hpp> 

int main() { 
    std::string val = "ABC"; 
    msgpack::type::ext e1(42, val.data(), val.size()); 

    assert(e1.type() == 42); 
    assert(e1.size() == 3); 
    assert(e1.data()[0] == 'A'); 
    assert(e1.data()[1] == 'B'); 
    assert(e1.data()[2] == 'C'); 

    std::stringstream ss; 
    msgpack::pack(ss, e1); 

    auto oh = msgpack::unpack(ss.str().data(), ss.str().size()); 
    auto e2 = oh.get().as<msgpack::type::ext>(); 
    assert(e1 == e2); 
} 

ライブデモ: https://wandbox.org/permlink/ESmreWNBqDdXbKSf

ます。またmsgpack::type::ext_refを使用することができます。 コピー操作を避けることができますが、元のバッファー(この場合はvaloh)を保持する必要があります。

#include <sstream> 
#include <cassert> 

#include <msgpack.hpp> 

int main() { 
    std::string val = "\x2a"; // type 42 
    val += "ABC"; 
    msgpack::type::ext_ref e1(val.data(), val.size()); 

    assert(e1.type() == 42); 
    assert(e1.size() == 3); 
    assert(e1.data()[0] == 'A'); 
    assert(e1.data()[1] == 'B'); 
    assert(e1.data()[2] == 'C'); 

    std::stringstream ss; 
    msgpack::pack(ss, e1); 

    auto oh = msgpack::unpack(ss.str().data(), ss.str().size()); 
    auto e2 = oh.get().as<msgpack::type::ext_ref>(); 
    assert(e1 == e2); 
} 

ライブデモ: https://wandbox.org/permlink/uYr5MFjLJqPHQgj6

関連する問題