Skip to content

Instantly share code, notes, and snippets.

@luxcupitor
Forked from redboltz/msgpack_bin_str.cpp
Created November 27, 2023 19:11
Show Gist options
  • Save luxcupitor/0b5643605ddd24bd243b729c2aa6aeb9 to your computer and use it in GitHub Desktop.
Save luxcupitor/0b5643605ddd24bd243b729c2aa6aeb9 to your computer and use it in GitHub Desktop.
msgpack bin/str pack/unpack example.
// 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();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment