| # MessagePack |
| |
| MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves. |
| |
| References |
| |
| - [MessagePack website](https://msgpack.org) |
| - [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md) |
| |
| ## Serialization |
| |
| The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification: |
| |
| | JSON value type | value/range | MessagePack type | first byte | |
| | --------------- | ---------------------------------------- | ---------------- | ---------- | |
| | null | `null` | nil | 0xC0 | |
| | boolean | `true` | true | 0xC3 | |
| | boolean | `false` | false | 0xC2 | |
| | number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 | |
| | number_integer | -2147483648..-32769 | int32 | 0xD2 | |
| | number_integer | -32768..-129 | int16 | 0xD1 | |
| | number_integer | -128..-33 | int8 | 0xD0 | |
| | number_integer | -32..-1 | negative fixint | 0xE0..0xFF | |
| | number_integer | 0..127 | positive fixint | 0x00..0x7F | |
| | number_integer | 128..255 | uint 8 | 0xCC | |
| | number_integer | 256..65535 | uint 16 | 0xCD | |
| | number_integer | 65536..4294967295 | uint 32 | 0xCE | |
| | number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF | |
| | number_unsigned | 0..127 | positive fixint | 0x00..0x7F | |
| | number_unsigned | 128..255 | uint 8 | 0xCC | |
| | number_unsigned | 256..65535 | uint 16 | 0xCD | |
| | number_unsigned | 65536..4294967295 | uint 32 | 0xCE | |
| | number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF | |
| | number_float | *any value representable by a float* | float 32 | 0xCA | |
| | number_float | *any value NOT representable by a float* | float 64 | 0xCB | |
| | string | *length*: 0..31 | fixstr | 0xA0..0xBF | |
| | string | *length*: 32..255 | str 8 | 0xD9 | |
| | string | *length*: 256..65535 | str 16 | 0xDA | |
| | string | *length*: 65536..4294967295 | str 32 | 0xDB | |
| | array | *size*: 0..15 | fixarray | 0x90..0x9F | |
| | array | *size*: 16..65535 | array 16 | 0xDC | |
| | array | *size*: 65536..4294967295 | array 32 | 0xDD | |
| | object | *size*: 0..15 | fix map | 0x80..0x8F | |
| | object | *size*: 16..65535 | map 16 | 0xDE | |
| | object | *size*: 65536..4294967295 | map 32 | 0xDF | |
| | binary | *size*: 0..255 | bin 8 | 0xC4 | |
| | binary | *size*: 256..65535 | bin 16 | 0xC5 | |
| | binary | *size*: 65536..4294967295 | bin 32 | 0xC6 | |
| |
| Complete mapping |
| |
| The mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value. |
| |
| Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. |
| |
| Size constraints |
| |
| The following values can **not** be converted to a MessagePack value: |
| |
| - strings with more than 4294967295 bytes |
| - byte strings with more than 4294967295 bytes |
| - arrays with more than 4294967295 elements |
| - objects with more than 4294967295 elements |
| |
| NaN/infinity handling |
| |
| `NaN`, `Infinity`, and `-Infinity` are serialized as a MessagePack float 32 (type 0xCA, 5 bytes total), regardless of magnitude, in contrast to the [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) function which serializes NaN or Infinity to `null`. |
| |
| Note |
| |
| Prior to version 3.13.0, NaN and Infinity were instead serialized as a MessagePack float 64 (type 0xCB, 9 bytes total), because the check used to select the smaller float 32 encoding compared magnitudes with NaN, which is always `false` and caused the float 32 path to be skipped. |
| |
| Example |
| |
| ``` |
| #include <iostream> |
| #include <iomanip> |
| #include <nlohmann/json.hpp> |
| |
| using json = nlohmann::json; |
| using namespace nlohmann::literals; |
| |
| int main() |
| { |
| // create a JSON value |
| json j = R"({"compact": true, "schema": 0})"_json; |
| |
| // serialize it to MessagePack |
| std::vector<std::uint8_t> v = json::to_msgpack(j); |
| |
| // print the vector content |
| for (auto& byte : v) |
| { |
| std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; |
| } |
| std::cout << std::endl; |
| } |
| ``` |
| |
| Output: |
| |
| ``` |
| 0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 |
| ``` |
| |
| ## Deserialization |
| |
| The library maps MessagePack types to JSON value types as follows: |
| |
| | MessagePack type | JSON value type | first byte | |
| | ---------------- | --------------- | ---------- | |
| | positive fixint | number_unsigned | 0x00..0x7F | |
| | fixmap | object | 0x80..0x8F | |
| | fixarray | array | 0x90..0x9F | |
| | fixstr | string | 0xA0..0xBF | |
| | nil | `null` | 0xC0 | |
| | false | `false` | 0xC2 | |
| | true | `true` | 0xC3 | |
| | float 32 | number_float | 0xCA | |
| | float 64 | number_float | 0xCB | |
| | uint 8 | number_unsigned | 0xCC | |
| | uint 16 | number_unsigned | 0xCD | |
| | uint 32 | number_unsigned | 0xCE | |
| | uint 64 | number_unsigned | 0xCF | |
| | int 8 | number_integer | 0xD0 | |
| | int 16 | number_integer | 0xD1 | |
| | int 32 | number_integer | 0xD2 | |
| | int 64 | number_integer | 0xD3 | |
| | str 8 | string | 0xD9 | |
| | str 16 | string | 0xDA | |
| | str 32 | string | 0xDB | |
| | array 16 | array | 0xDC | |
| | array 32 | array | 0xDD | |
| | map 16 | object | 0xDE | |
| | map 32 | object | 0xDF | |
| | bin 8 | binary | 0xC4 | |
| | bin 16 | binary | 0xC5 | |
| | bin 32 | binary | 0xC6 | |
| | ext 8 | binary | 0xC7 | |
| | ext 16 | binary | 0xC8 | |
| | ext 32 | binary | 0xC9 | |
| | fixext 1 | binary | 0xD4 | |
| | fixext 2 | binary | 0xD5 | |
| | fixext 4 | binary | 0xD6 | |
| | fixext 8 | binary | 0xD7 | |
| | fixext 16 | binary | 0xD8 | |
| | negative fixint | number_integer | 0xE0-0xFF | |
| |
| Info |
| |
| Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. |
| |
| Example |
| |
| ``` |
| #include <iostream> |
| #include <iomanip> |
| #include <nlohmann/json.hpp> |
| |
| using json = nlohmann::json; |
| |
| int main() |
| { |
| // create byte vector |
| std::vector<std::uint8_t> v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, |
| 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, |
| 0x61, 0x00 |
| }; |
| |
| // deserialize it with MessagePack |
| json j = json::from_msgpack(v); |
| |
| // print the deserialized JSON value |
| std::cout << std::setw(2) << j << std::endl; |
| } |
| ``` |
| |
| Output: |
| |
| ``` |
| { |
| "compact": true, |
| "schema": 0 |
| } |
| ``` |