### Msgpack-C: Non-Intrusive Class Serialization Example Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Provides a complete example of how to serialize and deserialize a custom class `my_class` without modifying its definition. It includes specializations for `convert`, `pack`, and `object_with_zone`, demonstrating how to handle class members during msgpack operations. ```C++ #include class my_class { public: my_class() {} // Default constructor for msgpack::object::as my_class(std::string const& name, int age):name_(name), age_(age) {} std::string const& get_name() const { return name_; } int get_age() const { return age_; } private: std::string name_; int age_; }; namespace msgpack { MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { namespace adaptor { template<> struct convert { msgpack::object const& operator()(msgpack::object const& o, my_class& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); if (o.via.array.size != 2) throw msgpack::type_error(); v = my_class( o.via.array.ptr[0].as(), o.via.array.ptr[1].as()); return o; } }; template<> struct pack { template packer& operator()(msgpack::packer& o, my_class const& v) const { o.pack_array(2); o.pack(v.get_name()); o.pack(v.get_age()); return o; } }; template <> struct object_with_zone { void operator()(msgpack::object::with_zone& o, my_class const& v) const { o.type = type::ARRAY; o.via.array.size = 2; o.via.array.ptr = static_cast( o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone); o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone); } }; } // namespace adaptor } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) } // namespace msgpack ``` -------------------------------- ### Manual Packing Example Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_packer Demonstrates how to manually pack binary data using msgpack::packer and msgpack::sbuffer. ```APIDOC ## POST /msgpack/manual_pack ### Description Manually pack binary data using `msgpack::packer` and `msgpack::sbuffer`. ### Method POST ### Endpoint /msgpack/manual_pack ### Parameters #### Request Body - **data** (string) - The binary data to pack. ### Request Example ```json { "data": "AQIDBAUGOg==" } ``` ### Response #### Success Response (200) - **packed_data** (string) - The packed binary data in msgpack format. #### Response Example ```json { "packed_data": "cgECAwQFBg==" } ``` ``` -------------------------------- ### Example unpack_reference_func Implementation Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker Provides an example implementation of the unpack_reference_func callback. This function demonstrates conditional logic for referencing or copying data based on type and length, illustrating how to manage memory for different msgpack data types. ```C++ bool my_reference_func(type::object_type type, std::size_t length, void* user_data) { switch (type) { case: type::STR: // Small strings are copied. if (length < 32) return false; break; case: type::BIN: // BIN is always copied. return false; case: type::EXT: // fixext's are copied. switch (length) { case 1+1: case 2+1: case 4+1: case 8+1: case 16+1: return false; } break; default: assert(false); } // otherwise referenced. return true; } ``` -------------------------------- ### Build Msgpack-C Examples with CMake Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_configure Control whether example programs are built when compiling msgpack-c using CMake. Set MSGPACK_BUILD_EXAMPLES to ON to include examples, or OFF to exclude them. Default is ON. ```cmake cmake -DMSGPACK_BUILD_EXAMPLES=ON .. # or cmake -DMSGPACK_BUILD_EXAMPLES=OFF .. ``` -------------------------------- ### Msgpack Serialization Example (Array and Map) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Illustrates how a C++ class adapted with MSGPACK_DEFINE is serialized into msgpack format. The output can be either a msgpack array or a map, depending on the MSGPACK_USE_DEFINE_MAP setting. ```Javascript // array [42,"ABC"] // map (MSGPACK_USE_DEFINE_MAP is defined) {"a":42,"b":"ABC"} ``` -------------------------------- ### Perform Unpacking with msgpack_unpacker_next (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Illustrates the core unpacking logic using msgpack_unpacker_next. It shows how to handle successful unpacking, incomplete data requiring more input, and parsing errors. ```C { msgpack_unpacked und; msgpack_unpack_return ret; msgpack_unpacked_init(&und); ret = msgpack_unpacker_next(&unp, &und); switch(ret) { case MSGPACK_UNPACK_SUCCESS: { msgpack_object obj = und.data; /* Extract msgpack_object and use it. */ } break; case MSGPACK_UNPACK_CONTINUE: /* cheking capacity, reserve buffer, copy additional data to the buffer, */ /* notify consumed buffer size, then call msgpack_unpacker_next(&unp, &und) again */ break; case MSGPACK_UNPACK_PARSE_ERROR: /* Error process */ break; } } ``` -------------------------------- ### Msgpack Serialization with Custom Map Keys Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Demonstrates the msgpack output when using MSGPACK_NVP to define custom map keys. The example shows 'a' as a standard key and '#b' as a custom key for the string member. ```Javascript {"a":42,"#b":"ABC"} ``` -------------------------------- ### Initialize and Free msgpack_unpacker on Heap (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Shows how to create and free a msgpack_unpacker when allocated on the heap. It checks for successful allocation before proceeding with unpacking operations. ```C /* unpacker on the heap */ msgpack_unpacker* unp = msgpack_unpacker_new(100); if (unp) { /* Do unpacking */ } msgpack_unpacker_free(unp); ``` -------------------------------- ### Stream Parse/Unpack Example Source: https://github.com/msgpack/msgpack-c/wiki/v_2_0_cpp_x3_parse Demonstrates how to use the iterator-based parse/unpack functions for stream processing. ```APIDOC ## Stream Parse/Unpack ### Description The iterator-based `parse` and `unpack` functions can be effectively used for stream parsing and unpacking scenarios. This example illustrates how to handle data arriving in chunks. ### Usage When dealing with a data source that provides data incrementally (e.g., network socket, file stream), you can wrap the source with a `buffered_iterator` and then use `msgpack::unpack` with iterators. The `buffered_iterator` manages fetching data from the source as needed. ### Code Snippet ```cpp // Assume 'source' is an object that provides data, e.g., a network stream reader. // 'buffered_iterator' is a custom iterator that pulls data from 'source'. auto b = boost::spirit::make_default_multi_pass(buffered_iterator(source)); auto e = boost::spirit::make_default_multi_pass(buffered_iterator()); // Represents end-of-stream or end of current buffer // Process a fixed number of msgpack data items for demonstration for (int i = 0; i != 2; ++i) { // msgpack::unpack will internally call the buffered_iterator's increment // operator to fetch more data if the current buffer is exhausted. auto oh = msgpack::unpack(b, e); std::cout << oh.get() << std::endl; } ``` ### Explanation * `buffered_iterator(source)`: Creates an iterator that reads data from the `source`. This iterator typically uses coroutines (like Boost.Coroutine2) to suspend and resume, fetching data only when required by the unpacker. * `boost::spirit::make_default_multi_pass()`: Adapts the `buffered_iterator` for use with Spirit parsers, ensuring proper multi-pass iterator behavior. * `msgpack::unpack(b, e)`: Calls the unpack function. When `b` reaches the end of its current data chunk, it will signal the `buffered_iterator` to fetch the next chunk from the `source` via its `pull` mechanism. * The context switching between `do_read()` (in the `buffered_iterator`) and `msgpack::unpack()` allows for seamless processing of data streams without needing to load the entire stream into memory. ``` -------------------------------- ### Pack Single String Value Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_tutorial Example of packing a single string value ('compact') into MessagePack format using msgpack::pack. The output is then displayed in hexadecimal format. ```cpp #include #include #include // hex_dump is not a part of msgpack-c. inline std::ostream& hex_dump(std::ostream& o, std::string const& v) { std::ios::fmtflags f(o.flags()); o << std::hex; for (auto c : v) { o << "0x" << std::setw(2) << std::setfill('0') << (static_cast(c) & 0xff) << ' '; } o.flags(f); return o; } int main() { std::stringstream ss; msgpack::pack(ss, "compact"); hex_dump(std::cout, ss.str()) << std::endl; } ``` -------------------------------- ### MessagePack C API: Packing Data Source: https://context7.com/msgpack/msgpack-c/llms.txt Demonstrates how to pack MessagePack data using the C API, providing low-level control over buffer management. This example shows packing a map with nested array elements. ```c #include #include int main() { msgpack_sbuffer sbuf; msgpack_packer pk; // Initialize buffer and packer msgpack_sbuffer_init(&sbuf); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); // Pack a map with nested array msgpack_pack_map(&pk, 2); // Key-value pair 1 msgpack_pack_str(&pk, 4); msgpack_pack_str_body(&pk, "name", 4); msgpack_pack_str(&pk, 5); msgpack_pack_str_body(&pk, "Alice", 5); // Key-value pair 2 msgpack_pack_str(&pk, 6); msgpack_pack_str_body(&pk, "scores", 6); msgpack_pack_array(&pk, 3); msgpack_pack_int(&pk, 95); msgpack_pack_int(&pk, 87); msgpack_pack_int(&pk, 92); printf("Packed %zu bytes\n", sbuf.size); // Cleanup msgpack_sbuffer_destroy(&sbuf); return 0; } ``` -------------------------------- ### MessagePack C API: Unpacking Data Source: https://context7.com/msgpack/msgpack-c/llms.txt Shows how to unpack MessagePack data using the C API, involving unpacker and object structures for deserialization. This example unpacks a simple array of integers. ```c #include #include #include int main() { // Create sample packed data msgpack_sbuffer sbuf; msgpack_packer pk; msgpack_sbuffer_init(&sbuf); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); msgpack_pack_array(&pk, 3); msgpack_pack_int(&pk, 1); msgpack_pack_int(&pk, 2); msgpack_pack_int(&pk, 3); // Unpack using unpacker msgpack_unpacker unp; msgpack_unpacker_init(&unp, 100); if (msgpack_unpacker_buffer_capacity(&unp) < sbuf.size) { msgpack_unpacker_reserve_buffer(&unp, sbuf.size); } memcpy(msgpack_unpacker_buffer(&unp), sbuf.data, sbuf.size); msgpack_unpacker_buffer_consumed(&unp, sbuf.size); msgpack_unpacked result; msgpack_unpacked_init(&result); if (msgpack_unpacker_next(&unp, &result) == MSGPACK_UNPACK_SUCCESS) { msgpack_object obj = result.data; if (obj.type == MSGPACK_OBJECT_ARRAY) { printf("Array with %u elements:\n", obj.via.array.size); for (uint32_t i = 0; i < obj.via.array.size; i++) { msgpack_object elem = obj.via.array.ptr[i]; if (elem.type == MSGPACK_OBJECT_POSITIVE_INTEGER) { printf(" [%u] = %llu\n", i, elem.via.u64); } } } } // Cleanup msgpack_unpacked_destroy(&result); msgpack_unpacker_destroy(&unp); msgpack_sbuffer_destroy(&sbuf); return 0; } ``` -------------------------------- ### Zone Management Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Information on initializing, destroying, and using memory zones for msgpack object allocation. ```APIDOC ## Zone Management ### Description A zone is a memory pool used for allocating `msgpack_object` instances. It is managed automatically when using `msgpack_unpacker` or `msgpack_unpack_next`, but requires manual management when using the obsolete `msgpack_unpack` function. ### Functions #### On Stack - **`bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)`**: Initializes a zone on the stack. - **`void msgpack_zone_destroy(msgpack_zone* zone)`**: Destroys a zone initialized on the stack. #### On Heap - **`msgpack_zone* msgpack_zone_new(size_t chunk_size)`**: Creates and initializes a new zone on the heap. - **`void msgpack_zone_free(msgpack_zone* zone)`**: Frees a zone created on the heap. ### Parameters - **`zone`** (*msgpack_zone* *) - Pointer to the `msgpack_zone` structure. - **`chunk_size`** (*size_t*) - The size of memory chunks to allocate for the zone. ``` -------------------------------- ### Initialize and Destroy msgpack_unpacker on Stack (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Demonstrates how to initialize and destroy a msgpack_unpacker when allocated on the stack. It includes error checking for initialization and ensures proper cleanup. ```C /* unpacker on the stack */ msgpack_unpacker unp; /* Initialize the unpacker. 100 means initial buffer size. */ /* It can expand later. */ bool result = msgpack_unpacker_init(&unp, 100); /* If memory allocation is failed, result is false, else result is true. */ if (result) { /* Do unpacking */ } msgpack_unpacker_destroy(&unp); ``` -------------------------------- ### Unpacking Functions Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Details on the `msgpack_unpack_next` and the obsolete `msgpack_unpack` functions for parsing msgpack data. Includes information on managing data buffers and zones. ```APIDOC ## Unpacking Functions ### Description Provides functions for unpacking msgpack data. `msgpack_unpack_next` is the recommended function, while `msgpack_unpack` is obsolete. ### Method N/A (C functions) ### Endpoint N/A (C functions) ### Parameters #### `msgpack_unpack_next` - **`result`** (*msgpack_unpacked* *) - Output - Structure to hold the unpacked result. - **`data`** (*const char* *) - Input - Pointer to the msgpack data buffer. - **`len`** (*size_t*) - Input - Length of the msgpack data buffer. - **`off`** (*size_t* *) - Output - Offset in the data buffer after unpacking. #### `msgpack_unpack` (Obsolete) - **`data`** (*const char* *) - Input - Pointer to the msgpack data buffer. - **`len`** (*size_t*) - Input - Length of the msgpack data buffer. - **`off`** (*size_t* *) - Output - Offset in the data buffer after unpacking. - **`result_zone`** (*msgpack_zone* *) - Input/Output - The memory zone to allocate the unpacked object from. - **`result`** (*msgpack_object* *) - Output - The unpacked msgpack object. ### Return Values Both functions return `msgpack_unpack_return` with the following meanings: - **MSGPACK_UNPACK_SUCCESS**: Successfully unpacked. No extra bytes. - **MSGPACK_UNPACK_EXTRA_BYTES**: Successfully unpacked. There are extra bytes. - **MSGPACK_UNPACK_CONTINUE**: msgpack format data is incomplete. More bytes are needed. - **MSGPACK_UNPACK_PARSE_ERROR**: msgpack format data is invalid. - **MSGPACK_UNPACK_NOMEM_ERROR**: Memory allocation failed. ### Notes - When using `msgpack_unpack_next` or `msgpack_unpacker`, the library manages the zone. - When using the obsolete `msgpack_unpack`, manual zone management (initialization and destruction) is required. - For STR, BIN, or EXT types, the unpacked `msgpack_object` refers to the original data buffer. Ensure the buffer's lifetime is managed. ``` -------------------------------- ### Support for Non-Default Constructible Classes (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Enables conversion of `msgpack::object` to classes that do not have a default constructor using `as` class template specialization. This is useful for classes requiring specific initialization parameters. The example shows defining the specialization for a `no_def_con` struct and then performing the conversion. ```cpp struct no_def_con { no_def_con() = delete; no_def_con(int i):i(i) {} int i; MSGPACK_DEFINE(i); }; namespace msgpack { MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { namespace adaptor { template <> struct as { no_def_con operator()(msgpack::object const& o) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); if (o.via.array.size != 1) throw msgpack::type_error(); return no_def_con(o.via.array.ptr[0].as()); } }; } // adaptor } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) } // msgpack // Usage: // msgpack::object o = /* ... */; // no_def_con ndc = o.as(); ``` -------------------------------- ### Enable Boost Adaptors in Msgpack-C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_configure Define the MSGPACK_USE_BOOST preprocessor macro to enable support for Boost container adaptors. This requires the Boost Libraries to be installed and available. Available from version 1.2.0 up to 4.0.0. ```c++ #define MSGPACK_USE_BOOST // ... rest of your code ``` -------------------------------- ### Msgpack-C: Stream Unpacking Example (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v_2_0_cpp_x3_parse Demonstrates stream unpacking using `boost::spirit::make_default_multi_pass` with a `buffered_iterator`. This code snippet shows how to process msgpack data incrementally from a source, where the iterator fetches data as needed via coroutines. ```cpp // use buffered_iterator here // b is incremented in msgpack::unpack() and fetch data from sink // via coroutine2 mechanism auto b = boost::spirit::make_default_multi_pass(buffered_iterator(source)); auto e = boost::spirit::make_default_multi_pass(buffered_iterator()); // This is usually an infinity look, but for test, loop is finished when // two message pack data is processed. for (int i = 0; i != 2; ++i) { auto oh = msgpack::unpack(b, e); std::cout << oh.get() << std::endl; } ``` -------------------------------- ### Manage Unpacker Buffer Capacity (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Explains how to check the current buffer capacity of a msgpack_unpacker and reserve additional space if needed. This is crucial for handling data that exceeds the initial buffer size. ```C if (msgpack_unpacker_buffer_capacity(&unp) < request_size) { bool result = msgpack_unpacker_reserve_buffer(&unp, request_size); if (!result) { /* Memory allocation error. */ } } ``` -------------------------------- ### Initialize MsgPack Packer and Buffer in C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Initializes a MsgPack buffer and packer for serializing data. Requires a `msgpack_sbuffer` for storage and a `msgpack_packer` to perform the packing operations. The `msgpack_sbuffer_init` function prepares the buffer, and `msgpack_packer_init` associates the packer with the buffer and a write function. ```C int main() { msgpack_sbuffer sbuf; msgpack_packer pk; msgpack_sbuffer_init(&sbuf); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); // ... packing operations ... msgpack_sbuffer_destroy(&sbuf); return 0; } ``` -------------------------------- ### Initialize msgpack Buffer and Packer in C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Demonstrates the initialization of a msgpack buffer and packer in C. The sbuffer is a simple memory buffer, and the packer is used to serialize data into this buffer. Proper initialization is crucial before packing data. ```C msgpack_sbuffer sbuf; msgpack_packer pk; msgpack_sbuffer_init(&sbuf); msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); ``` -------------------------------- ### Msgpack Zone Initialization and Destruction (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Provides functions for initializing and destroying msgpack zones. Zones act as memory pools used by the unpacker and `msgpack_unpack_next()`. The code shows how to manage zones either on the stack or on the heap, with heap management requiring explicit allocation and deallocation. ```C /* On stack */ bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size); void msgpack_zone_destroy(msgpack_zone* zone); /* On heap */ msgpack_zone* msgpack_zone_new(size_t chunk_size); void msgpack_zone_free(msgpack_zone* zone); ``` -------------------------------- ### Pack Data Using std::stringstream with msgpack Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_packer This C++ example shows how to pack a std::tuple into a msgpack format using std::stringstream as the buffer. The std::stringstream must provide a `write(const char*, std::size_t)` member function. The `msgpack::pack` function handles the serialization and writing to the stream. ```C++ #include #include #include #include int main() { std::tuple src(1, true, "example"); std::stringstream buffer; msgpack::pack(buffer, src); // calls std::stringstream::write internally. return 0; } ``` -------------------------------- ### Pack various data types using MsgPack-C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Provides functions to pack different primitive data types into a MsgPack buffer. These functions include packing signed and unsigned integers of various sizes, floats, doubles, booleans, and nil. Each function takes a pointer to the packer and the value to be packed. ```C int msgpack_pack_char(msgpack_packer* pk, char d); int msgpack_pack_signed_char(msgpack_packer* pk, signed char d); int msgpack_pack_short(msgpack_packer* pk, short d); int msgpack_pack_int(msgpack_packer* pk, int d); int msgpack_pack_long(msgpack_packer* pk, long d); int msgpack_pack_long_long(msgpack_packer* pk, long long d); int msgpack_pack_unsigned_char(msgpack_packer* pk, unsigned char d); int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d); int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d); int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d); int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d); int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d); int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d); int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d); int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d); int msgpack_pack_int8(msgpack_packer* pk, int8_t d); int msgpack_pack_int16(msgpack_packer* pk, int16_t d); int msgpack_pack_int32(msgpack_packer* pk, int32_t d); int msgpack_pack_int64(msgpack_packer* pk, int64_t d); int msgpack_pack_float(msgpack_packer* pk, float d); int msgpack_pack_double(msgpack_packer* pk, double d); int msgpack_pack_nil(msgpack_packer* pk); int msgpack_pack_true(msgpack_packer* pk); int msgpack_pack_false(msgpack_packer* pk); ``` -------------------------------- ### Pack complex structures (Array, Map, String, Binary, Ext) with MsgPack-C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Functions for packing complex data structures like arrays, maps, strings, binary data, and extended types. For arrays and maps, first specify the number of elements, then pack the elements sequentially. For strings, binary, and extended types, provide the size first, followed by the data body. ```C int msgpack_pack_array(msgpack_packer* pk, size_t n); int msgpack_pack_map(msgpack_packer* pk, size_t n); int msgpack_pack_str(msgpack_packer* pk, size_t l); int msgpack_pack_str_body(msgpack_packer* pk, const void* b, size_t l); int msgpack_pack_v4raw(msgpack_packer* pk, size_t l); int msgpack_pack_v4raw_body(msgpack_packer* pk, const void* b, size_t l); int msgpack_pack_bin(msgpack_packer* pk, size_t l); int msgpack_pack_bin_body(msgpack_packer* pk, const void* b, size_t l); int msgpack_pack_ext(msgpack_packer* pk, size_t l, int8_t type); int msgpack_pack_ext_body(msgpack_packer* pk, const void* b, size_t l); int msgpack_pack_object(msgpack_packer* pk, msgpack_object d); ``` -------------------------------- ### Basic Usage Pattern for msgpack::unpacker (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker Demonstrates a typical pattern for using msgpack::unpacker in a streaming application. It shows how to reserve buffer space, read data from an input source, notify the unpacker of consumed data, and process complete messages. ```C++ // The size may decided by receive performance, transmit layer's protocol and so on. std::size_t const try_read_size = 100; msgpack::unpacker unp; // Message receive loop while (/* block until input becomes readable */) { unp.reserve_buffer(try_read_size); // unp has at least try_read_size buffer on this point. // input is a kind of I/O library object. // read message to msgpack::unpacker's internal buffer directly. std::size_t actual_read_size = input.readsome(unp.buffer(), try_read_size); // tell msgpack::unpacker actual consumed size. unp.buffer_consumed(actual_read_size); msgpack::object_handle result; // Message pack data loop while(unp.next(result)) { msgpack::object obj(result.get()); // Use obj } // All complete msgpack message is proccessed at this point, // then continue to read addtional message. } ``` -------------------------------- ### Msgpack Object Structure Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Defines the structure of a `msgpack_object`, including its type and union for data storage. ```APIDOC ## Msgpack Object Structure ### Description Represents an unpacked msgpack data element. It contains a type identifier and a union to hold the actual data based on the type. ### Structure Definition ```c typedef struct { msgpack_object_type type; msgpack_object_union via; } msgpack_object; ``` ### `msgpack_object_type` Enum Defines the type of the msgpack object: - **`MSGPACK_OBJECT_NIL`** - **`MSGPACK_OBJECT_BOOLEAN`** - **`MSGPACK_OBJECT_POSITIVE_INTEGER`** - **`MSGPACK_OBJECT_NEGATIVE_INTEGER`** - **`MSGPACK_OBJECT_FLOAT`** - **`MSGPACK_OBJECT_STR`** - **`MSGPACK_OBJECT_ARRAY`** - **`MSGPACK_OBJECT_MAP`** - **`MSGPACK_OBJECT_BIN`** - **`MSGPACK_OBJECT_EXT`** ### `msgpack_object_union` Union Contains the data for the msgpack object, with fields corresponding to the `msgpack_object_type`: - **`bool boolean`** - **`uint64_t u64`** - **`int64_t i64`** - **`double f64`** - **`msgpack_object_array array`** - **`msgpack_object_map map`** - **`msgpack_object_str str`** - **`msgpack_object_bin bin`** - **`msgpack_object_ext ext`** ### Related Structures - **`msgpack_object_array`**: `{ uint32_t size; struct msgpack_object* ptr; }` - **`msgpack_object_map`**: `{ uint32_t size; struct msgpack_object_kv* ptr; }` - **`msgpack_object_kv`**: `{ msgpack_object key; msgpack_object val; }` - **`msgpack_object_str`**: `{ uint32_t size; const char* ptr; }` - **`msgpack_object_bin`**: `{ uint32_t size; const char* ptr; }` - **`msgpack_object_ext`**: `{ int8_t type; uint32_t size; const char* ptr; }` ``` -------------------------------- ### Manual Binary Packing in C++ Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_packer Demonstrates manual packing of binary data using msgpack::packer. It involves creating a buffer, a packer instance, and then packing the binary header and its body separately. This method is useful for custom type support. ```cpp msgpack::sbuffer sbuf; msgpack::packer packer(sbuf); char c[] = { 1, 2, 3, 4, 5, 6 }; packer.pack_bin(sizeof(c)); // pack header and size packer.pack_bin_body(c, sizeof(c)); // pack payload ``` -------------------------------- ### Msgpack-C: Optimizing Type Conversion with Direct Member Access Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Illustrates an optimization technique for the `convert` template specialization in msgpack-c. By directly accessing member variables (if they are public or accessible via getters that allow direct assignment), temporary object creation during conversion can be avoided, potentially improving performance. ```C++ class my_class { public: /* ... */ std::string name_; int age_; }; template<> struct convert { msgpack::object const& operator()(msgpack::object const& o, my_class& v) const { if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); if (o.via.array.size != 2) throw msgpack::type_error(); o.via.array.ptr[0] >> v.name_; // no temporary object creation o.via.array.ptr[1] >> v.age_; return o; } }; ``` -------------------------------- ### Check msgpack-C Version Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_tutorial Demonstrates how to check the version of the msgpack-C library by including the 'msgpack.hpp' header and accessing the MSGPACK_VERSION macro. This is useful to avoid confusion with older system-installed versions. ```cpp #include #include int main() { std::cout << MSGPACK_VERSION << std::endl; } ``` -------------------------------- ### Adapt Class with Base Classes for Msgpack (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Demonstrates how to adapt a C++ class that inherits from other classes using MSGPACK_BASE. This allows serialization of both the derived class members and its base class members. The order specified in MSGPACK_DEFINE determines the msgpack array/map structure. ```C++ #include struct base1 { int a; MSGPACK_DEFINE(a); }; struct base2 { int a; MSGPACK_DEFINE(a); }; struct your_class : base1, base2 { int a; std::string b; // You can choose any order. It is represented to the msgpack array elements order. MSGPACK_DEFINE(b, MSGPACK_BASE(base2), a, MSGPACK_BASE(base1)); }; // ... ``` -------------------------------- ### Stream Unpacking with msgpack::unpacker in C++ Source: https://context7.com/msgpack/msgpack-c/llms.txt Demonstrates how to use msgpack::unpacker for handling data in chunks, suitable for streaming scenarios like network communication. It shows reserving buffer space, copying data, and extracting complete messages. ```cpp #include #include int main() { msgpack::unpacker unp; // Simulate receiving data in chunks std::stringstream ss; msgpack::pack(ss, std::vector{1, 2, 3}); msgpack::pack(ss, std::map{{"a", 1}, {"b", 2}}); std::string all_data = ss.str(); // Process data in chunks (simulating network receive) std::size_t chunk_size = 5; std::size_t pos = 0; while (pos < all_data.size()) { std::size_t to_read = std::min(chunk_size, all_data.size() - pos); // Reserve buffer space unp.reserve_buffer(to_read); // Copy data to unpacker's internal buffer memcpy(unp.buffer(), all_data.data() + pos, to_read); unp.buffer_consumed(to_read); pos += to_read; // Try to extract complete messages msgpack::object_handle result; while (unp.next(result)) { std::cout << "Received: " << result.get() << std::endl; } } return 0; } ``` -------------------------------- ### Destroy msgpack_unpacked Object (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Shows the necessary step to destroy a msgpack_unpacked object after its data has been processed. It also mentions that explicit destruction can be skipped if the same object is reused. ```C msgpack_unpacked_destroy(&und); ``` -------------------------------- ### Pack std::map as Map Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_tutorial Shows how to pack a std::map with string keys and integer values into MessagePack format, representing it as a map. The resulting packed data is displayed in hexadecimal. ```cpp #include #include #include #include #include // hex_dump function assumed to be defined elsewhere or included inline std::ostream& hex_dump(std::ostream& o, std::string const& v) { std::ios::fmtflags f(o.flags()); o << std::hex; for (auto c : v) { o << "0x" << std::setw(2) << std::setfill('0') << (static_cast(c) & 0xff) << ' '; } o.flags(f); return o; } int main() { std::stringstream ss; std::map v { { "ABC", 5 }, { "DEFG", 2 } }; msgpack::pack(ss, v); hex_dump(std::cout, ss.str()) << std::endl; } ``` -------------------------------- ### Compile msgpack-C Library Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_tutorial Instructions on how to compile the msgpack-C library, which is a header-only library. It requires adding the library's include path to the compiler's include path. ```bash g++ -Ipath_to_msgpack-c/include your_source.cpp ``` -------------------------------- ### Pack std::vector as Array Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_tutorial Demonstrates how to pack a std::vector of integers into MessagePack format, representing it as an array. The packed data is then displayed in hexadecimal. ```cpp #include #include #include #include // hex_dump function assumed to be defined elsewhere or included inline std::ostream& hex_dump(std::ostream& o, std::string const& v) { std::ios::fmtflags f(o.flags()); o << std::hex; for (auto c : v) { o << "0x" << std::setw(2) << std::setfill('0') << (static_cast(c) & 0xff) << ' '; } o.flags(f); return o; } int main() { std::stringstream ss; std::vector v { 1, 5, 8, 2, 6 }; msgpack::pack(ss, v); hex_dump(std::cout, ss.str()) << std::endl; } ``` -------------------------------- ### Customize Map Key Names with MSGPACK_NVP (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Introduces MSGPACK_NVP for customizing map key names during msgpack serialization, starting from version 2.1.0. This is useful for cross-language compatibility, allowing non-standard C++ variable names as keys. ```C++ #include struct your_class { int a; std::string b; MSGPACK_DEFINE_MAP(a, MSGPACK_NVP("#b", b)); }; ``` -------------------------------- ### Implement Null Visitor for Msgpack Unpacking (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpack_visit This C++ code provides a 'null_visitor' implementation, a base class that inherits from the abstract visitor interface. It offers default 'true' return values for most visit functions, allowing users to selectively override only the necessary functions for custom unpacking logic, simplifying implementation. ```C++ struct null_visitor { bool visit_nil() { return true; } bool visit_boolean(bool /*v*/) { return true; } bool visit_positive_integer(uint64_t /*v*/) { return true; } bool visit_negative_integer(int64_t /*v*/) { return true; } bool visit_float(double /*v*/) { return true; } bool visit_str(const char* /*v*/, uint32_t /*size*/) { return true; } bool visit_bin(const char* /*v*/, uint32_t /*size*/) { return true; } bool visit_ext(const char* /*v*/, uint32_t /*size*/) { return true; } bool start_array(uint32_t /*num_elements*/) { return true; } bool start_array_item() { return true; } bool end_array_item() { return true; } bool end_array() { return true; } bool start_map(uint32_t /*num_kv_pairs*/) { return true; } bool start_map_key() { return true; } bool end_map_key() { return true; } bool start_map_value() { return true; } bool end_map_value() { return true; } bool end_map() { return true; } void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) { } void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) { } }; ``` -------------------------------- ### Write Data to Unpacker Buffer (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Details the process of writing data into the msgpack_unpacker's buffer using memcpy after ensuring sufficient capacity. It highlights the need to consume the buffer after writing. ```C memcpy(msgpack_unpacker_buffer(&unp), data, request_size); msgpack_unpacker_buffer_consumed(&unp, request_size); ``` -------------------------------- ### Msgpack-C: Specializing Templates for Custom Types Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor Demonstrates the template specializations required to enable msgpack-c to serialize and deserialize custom C++ types. This includes `convert` for deserialization, `pack` for serialization, `object` for msgpack object representation, and `object_with_zone` for managing memory during object creation. ```C++ template <> struct convert { msgpack::object const& operator()(msgpack::object const&, your_type&) const { // your implementation } }; template <> struct pack { template msgpack::packer& operator()(msgpack::packer&, your_type const&) const { // your implementation } }; template <> struct object { void operator()(msgpack::object&, your_type const&) const { // your implementation } }; template <> struct object_with_zone { void operator()(msgpack::object::with_zone&, your_type const&) const { // your implementation } }; ``` -------------------------------- ### Include msgpack.h Header File in C Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview This snippet shows how to include the necessary header file for using the msgpack-c library in your C projects. Ensure the msgpack library is correctly linked during compilation. ```C #include ``` -------------------------------- ### Msgpack-C Null Visitor Implementation (C++) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor Provides a default implementation of the visitor interface where all member functions return true or do nothing. This is useful for creating custom visitors that only need to handle a subset of msgpack elements, by inheriting from this class and overriding specific methods. ```C++ struct null_visitor { bool visit_nil() { return true; } bool visit_boolean(bool /*v*/) { return true; } bool visit_positive_integer(uint64_t /*v*/) { return true; } bool visit_negative_integer(int64_t /*v*/) { return true; } bool visit_float32(float /*v*/) { return true; } bool visit_float64(double /*v*/) { return true; } bool visit_str(const char* /*v*/, uint32_t /*size*/) { return true; } bool visit_bin(const char* /*v*/, uint32_t /*size*/) { return true; } bool visit_ext(const char* /*v*/, uint32_t /*size*/) { return true; } bool start_array(uint32_t /*num_elements*/) { return true; } bool start_array_item() { return true; } bool end_array_item() { return true; } bool end_array() { return true; } bool start_map(uint32_t /*num_kv_pairs*/) { return true; } bool start_map_key() { return true; } bool end_map_key() { return true; } bool start_map_value() { return true; } bool end_map_value() { return true; } bool end_map() { return true; } void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) { } void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) { } }; ``` -------------------------------- ### Msgpack Object Array Structure (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Defines the `msgpack_object_array` structure, used for msgpack array types. It contains a `size` member indicating the number of elements and a `ptr` member pointing to an array of `msgpack_object` structures. ```C typedef struct { uint32_t size; struct msgpack_object* ptr; } msgpack_object_array; ``` -------------------------------- ### Define Default API Version for msgpack-c Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_versioning This macro defines the default API version for msgpack-c. It is typically set to 2. You can override this by defining MSGPACK_API_VERSION during compilation, for example, using `g++ -DMSGPACK_API_VERSION=1` to ensure compatibility with older versions. ```C++ #if !defined(MSGPACK_DEFAULT_API_VERSION) #define MSGPACK_DEFAULT_API_VERSION 2 #endif ``` -------------------------------- ### Msgpack Object Type Enumeration (C) Source: https://github.com/msgpack/msgpack-c/wiki/v2_0_c_overview Lists the possible types for a `msgpack_object`, corresponding to the msgpack specification. These types include NIL, BOOLEAN, integers (positive and negative), FLOAT, STR, ARRAY, MAP, BIN, and EXT. ```C typedef enum { MSGPACK_OBJECT_NIL = 0x00, MSGPACK_OBJECT_BOOLEAN = 0x01, MSGPACK_OBJECT_POSITIVE_INTEGER = 0x02, MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x03, MSGPACK_OBJECT_FLOAT = 0x04, #if defined(MSGPACK_USE_LEGACY_NAME_AS_FLOAT) MSGPACK_OBJECT_DOUBLE = MSGPACK_OBJECT_FLOAT, /* obsolete */ #endif /* MSGPACK_USE_LEGACY_NAME_AS_FLOAT */ MSGPACK_OBJECT_STR = 0x05, MSGPACK_OBJECT_ARRAY = 0x06, MSGPACK_OBJECT_MAP = 0x07, MSGPACK_OBJECT_BIN = 0x08, MSGPACK_OBJECT_EXT = 0x09 } msgpack_object_type; ```