2017-11-30 2 views
0

나는 이것을 수행하는 방법에 대해 잘 모르기 때문에 C++에서 msgpack을 사용하여 ext 유형을 팩하는 방법을 샘플을 찾고 있습니다.Msgpack을 사용하여 C++의 Extension 유형을 포장하십시오.

내가 본 유일한 정보는이 섹션 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

.

#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을 사용할 수 있습니다

은 그들은 여기 msgpack::type::ext에 대한 예입니다 https://github.com/msgpack/msgpack-c/blob/master/include/msgpack/v1/adaptor/ext.hpp

에서 정의됩니다. 복사 작업을 피할 수 있지만 원래 버퍼를 유지해야합니다 (이 경우 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