Last active
November 27, 2023 19:11
-
-
Save redboltz/66bc25b8df2cde853732 to your computer and use it in GitHub Desktop.
msgpack bin/str pack/unpack example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This program requires the C++11 compiler, | |
// e.g.) g++ -std=c++11 ... | |
// clang++ -std=c++11 ... | |
#include <iostream> | |
#include <iomanip> | |
#include <string> | |
#include <msgpack.hpp> | |
void print(char const* buf, std::size_t size) { | |
for (std::size_t idx = 0; idx < size; ++idx) { | |
std::cout | |
<< std::hex | |
<< std::setfill('0') | |
<< std::setw(2) | |
<< (static_cast<unsigned int>(buf[idx]) & 0xff) | |
<< " "; | |
} | |
std::cout << std::endl; | |
} | |
void test_str() { | |
// std::string is mapped to str. | |
// See https://github.com/redboltz/msgpack-c/blob/temp/str_bin_support2/include/msgpack/adaptor/string.hpp#L44 | |
std::string str("Hello"); | |
msgpack::sbuffer sbuf; | |
msgpack::pack(sbuf, str); | |
print(sbuf.data(), sbuf.size()); | |
msgpack::unpacker unp; | |
unp.reserve_buffer(sbuf.size()); | |
std::memcpy(unp.buffer(), sbuf.data(), sbuf.size()); | |
unp.buffer_consumed(sbuf.size()); | |
msgpack::unpacked result; | |
while(bool ret = unp.next(&result)) { | |
std::cout << "ret:" << std::boolalpha << ret << std::endl; | |
msgpack::object const& obj = result.get(); | |
std::cout << obj << std::endl; | |
} | |
} | |
void test_bin() { | |
// msgpack::type::raw is mapped to bin. | |
// See https://github.com/redboltz/msgpack-c/blob/temp/str_bin_support2/include/msgpack/adaptor/raw.hpp#L73 | |
std::string str("Hello"); | |
msgpack::sbuffer sbuf; | |
msgpack::pack(sbuf, msgpack::type::raw_ref(str.data(), str.size())); | |
print(sbuf.data(), sbuf.size()); | |
msgpack::unpacker unp; | |
unp.reserve_buffer(sbuf.size()); | |
std::memcpy(unp.buffer(), sbuf.data(), sbuf.size()); | |
unp.buffer_consumed(sbuf.size()); | |
msgpack::unpacked result; | |
while(bool ret = unp.next(&result)) { | |
std::cout << "ret:" << std::boolalpha << ret << std::endl; | |
msgpack::object const& obj = result.get(); | |
std::cout << obj << std::endl; | |
} | |
} | |
void test_vector() { | |
// std::vector is mapped to array. | |
// See https://github.com/redboltz/msgpack-c/blob/temp/str_bin_support2/include/msgpack/adaptor/vector.hpp#L46 | |
std::vector<char> v { 'H', 'e', 'l', 'l', 'o' }; | |
msgpack::sbuffer sbuf; | |
msgpack::pack(sbuf, v); | |
print(sbuf.data(), sbuf.size()); | |
msgpack::unpacker unp; | |
unp.reserve_buffer(sbuf.size()); | |
std::memcpy(unp.buffer(), sbuf.data(), sbuf.size()); | |
unp.buffer_consumed(sbuf.size()); | |
msgpack::unpacked result; | |
while(bool ret = unp.next(&result)) { | |
std::cout << "ret:" << std::boolalpha << ret << std::endl; | |
msgpack::object const& obj = result.get(); | |
std::cout << obj << std::endl; | |
} | |
} | |
// You can add your custom conversion rules. | |
// These overloaded functions introduce the following mappings. | |
// | |
// pack | |
// std::vector<std::uint8_t> -> msgpack::type::BIN | |
// unpack | |
// msgpack::type::BIN => std::vector<std::uint8_t> | |
namespace msgpack { | |
inline std::vector<std::uint8_t>& operator>> (object const& o, std::vector<std::uint8_t>& v) | |
{ | |
if (o.type != type::BIN) { throw type_error(); } | |
v.resize(o.via.bin.size); | |
for (std::size_t idx = 0; idx < o.via.array.size; ++idx) { | |
v.push_back(o.via.bin.ptr[idx]); | |
} | |
return v; | |
} | |
template <typename Stream> | |
inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<std::uint8_t>& v) | |
{ | |
o.pack_bin(v.size()); | |
o.pack_bin_body(reinterpret_cast<char const*>(v.data()), v.size()); | |
return o; | |
} | |
} // namespace msgpack | |
void test_custom() { | |
// std::vector<std::uint8_t> is mapped to bin by overloaded functions above. | |
std::vector<std::uint8_t> v { 'H', 'e', 'l', 'l', 'o' }; | |
msgpack::sbuffer sbuf; | |
msgpack::pack(sbuf, v); | |
print(sbuf.data(), sbuf.size()); | |
msgpack::unpacker unp; | |
unp.reserve_buffer(sbuf.size()); | |
std::memcpy(unp.buffer(), sbuf.data(), sbuf.size()); | |
unp.buffer_consumed(sbuf.size()); | |
msgpack::unpacked result; | |
while(bool ret = unp.next(&result)) { | |
std::cout << "ret:" << std::boolalpha << ret << std::endl; | |
msgpack::object const& obj = result.get(); | |
std::cout << obj << std::endl; | |
} | |
} | |
int main() { | |
std::cout << "test_str" << std::endl; | |
test_str(); | |
std::cout << "test_bin" << std::endl; | |
test_bin(); | |
std::cout << "test_vector" << std::endl; | |
test_vector(); | |
std::cout << "test_custom" << std::endl; | |
test_custom(); | |
} |
EXT(type:1,size:8)
could you help me to unpack EXT object ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output is:
test_str
a5 48 65 6c 6c 6f
ret:true
"Hello"
test_bin
c4 05 48 65 6c 6c 6f
ret:true
"Hello"
test_vector
95 48 65 6c 6c 6f
ret:true
[48, 65, 6c, 6c, 6f]
test_custom
c4 05 48 65 6c 6c 6f
ret:true
"Hello"