MessagePack
Join provides high-performance MessagePack serialization and deserialization built on the same SAX API used for JSON. The implementation follows the official MessagePack specification, producing compact and efficient binary output.
MessagePack features:
- compact binary format — smaller and faster than JSON
- stream-based I/O — no intermediate buffering
- automatic encoding — optimal representation selected transparently
- multiple input sources — memory buffers, strings, and streams
- SAX integration — consistent API with JSON and XML
Serialization
PackWriter
Serialize Value objects to MessagePack format:
// libjoin.
#include <join/pack.hpp>
using namespace join;
Value data;
data["name"] = "Alice";
data["age"] = 30;
data["active"] = true;
std::ostringstream out;
PackWriter writer(out);
writer.serialize(data);The output is a binary MessagePack document written directly to the stream.
Deserialization
PackReader
Parse MessagePack data into a Value:
// libjoin.
#include <join/pack.hpp>
using namespace join;
Value root;
PackReader reader(root);
reader.deserialize(buffer, length);Input sources
PackReader accepts multiple input types:
// C-string with length
reader.deserialize(cstr, length);
// Pointer range
reader.deserialize(first, last);
// std::string
reader.deserialize(str);
// String stream
std::stringstream ss(binaryData);
reader.deserialize(ss);
// File stream
std::ifstream file("data.msgpack");
reader.deserialize(file);
// Generic input stream
std::istream& stream = ...;
reader.deserialize(stream);Parsing behavior
- Exactly one root value is parsed
- Trailing data after the root value is reported as an error
- All parsing errors are reported via
join::lastError
if (reader.deserialize(doc) == -1)
{
std::cerr << lastError.message() << "\n";
}Supported data types
| Type | Supported |
|---|---|
| Null | ✅ |
| Boolean | ✅ |
| Signed integers | ✅ |
| Unsigned ints | ✅ |
| 64-bit integers | ✅ |
| Floating point | ✅ |
| Strings | ✅ |
| Binary data | ✅ |
| Arrays | ✅ |
| Objects | ✅ |
Binary values are exposed as strings containing raw bytes.
Object keys
MessagePack supports any scalar type as object key:
Value obj;
PackReader reader(obj);
// String key
reader.deserialize(data); // {"name": "Alice"}
// Integer key
reader.deserialize(data); // {1: "one"}
// Boolean key
reader.deserialize(data); // {true: "yes"}
Array and object keys are not supported and will produce an InvalidKey error during serialization.
Error handling
MessagePack parsing errors are reported through the SAX error system.
Common error conditions include:
| Error Condition | Description |
|---|---|
InvalidKey | Invalid key type (array or object) |
InvalidValue | Invalid or unsupported MessagePack value |
ExtraData | Trailing data after root value |
RangeError | Truncated or incomplete input |
if (reader.deserialize(data) == -1)
{
if (lastError == SaxErrc::ExtraData)
{
std::cerr << "Extra data after document\n";
}
}Performance characteristics
Streaming parser
PackReader uses on-the-fly parsing:
- no intermediate DOM representation
- constant memory overhead
- suitable for large files and network streams
Binary efficiency
- Compact encoding of numbers and containers
- Minimal overhead compared to text-based formats
- No string escaping or UTF-8 validation cost
Best practices
- Use MessagePack for network protocols and IPC
- Prefer MessagePack over JSON for large or frequent payloads
- Validate input when parsing untrusted data
- Reuse
PackReaderandPackWriterinstances - Stream large documents instead of loading them fully in memory
Example usage
Complete round-trip
// libjoin.
#include <join/value.hpp>
#include <join/pack.hpp>
using namespace join;
// Create data
Value data = Object{
{"users", Array{
Object{{"name", "Alice"}, {"id", 1}},
Object{{"name", "Bob"}, {"id", 2}}
}},
{"count", 2}
};
// Serialize to MessagePack
std::ostringstream out;
PackWriter writer(out);
writer.serialize(data);
std::string binary = out.str();
// Parse back
Value parsed;
PackReader reader(parsed);
if (reader.deserialize(binary) == 0)
{
std::cout << parsed["count"].getInt() << "\n";
}Summary
| Feature | Supported |
|---|---|
| MessagePack serialization | ✅ |
| MessagePack deserialization | ✅ |
| Streaming I/O | ✅ |
| Compact binary format | ✅ |
| Multiple input sources | ✅ |
| SAX-style API | ✅ |
| High performance | ✅ |