CBOR (Concise Binary Object Representation)¶
Glaze provides comprehensive support for CBOR (RFC 8949), a binary data serialization format designed for small message size and extensibility. CBOR is an IETF standard that provides a self-describing binary format, making it ideal for interoperability with other languages and systems.
Basic Usage¶
Write CBOR
Read CBOR
[!NOTE] Reading CBOR is safe for invalid input and does not require null-terminated buffers.
Exceptions Interface¶
If you prefer exceptions over error codes:
#include "glaze/cbor/cbor_exceptions.hpp"
try {
my_struct s{};
auto buffer = glz::ex::write_cbor(s);
glz::ex::read_cbor(s, buffer);
}
catch (const std::runtime_error& e) {
// Handle error
}
Standards Compliance¶
Glaze CBOR implements the following standards:
| Standard | Description |
|---|---|
| RFC 8949 | CBOR core specification |
| RFC 8746 | Typed arrays and multi-dimensional arrays |
| IANA CBOR Tags | Registered semantic tags |
Typed Arrays (RFC 8746)¶
Glaze automatically uses RFC 8746 typed arrays for contiguous numeric containers, enabling bulk memory operations for maximum performance.
std::vector<double> values = {1.0, 2.0, 3.0, 4.0, 5.0};
std::string buffer{};
glz::write_cbor(values, buffer); // Uses typed array with bulk memcpy
Supported Typed Array Tags¶
| Type | Little-Endian Tag | Big-Endian Tag |
|---|---|---|
uint8_t |
64 | 64 |
uint16_t |
69 | 65 |
uint32_t |
70 | 66 |
uint64_t |
71 | 67 |
int8_t |
72 | 72 |
int16_t |
77 | 73 |
int32_t |
78 | 74 |
int64_t |
79 | 75 |
float |
85 | 81 |
double |
86 | 82 |
Glaze automatically selects the correct tag based on the native endianness of the system. When reading, Glaze performs automatic byte-swapping if the data was written on a system with different endianness.
Multi-Dimensional Arrays (RFC 8746)¶
Glaze supports RFC 8746 multi-dimensional arrays using semantic tags:
| Tag | Description |
|---|---|
| 40 | Row-major multi-dimensional array |
| 1040 | Column-major multi-dimensional array |
Eigen Matrix Support¶
Glaze provides native CBOR support for Eigen matrices and vectors:
#include "glaze/ext/eigen.hpp"
// Fixed-size matrix
Eigen::Matrix3d m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::string buffer{};
glz::write_cbor(m, buffer);
Eigen::Matrix3d result;
glz::read_cbor(result, buffer);
// Dynamic matrix
Eigen::MatrixXd m(3, 4);
// ... fill matrix ...
std::string buffer{};
glz::write_cbor(m, buffer);
Eigen::MatrixXd result;
glz::read_cbor(result, buffer); // Automatically resizes
The CBOR format for matrices is:
tag(40 or 1040) [
[rows, cols], // dimensions array
typed_array(data) // data as RFC 8746 typed array
]
- Tag 40 is used for row-major matrices
- Tag 1040 is used for column-major matrices (Eigen default)
This format is self-describing and interoperable with other CBOR implementations.
Complex Numbers¶
Glaze supports complex numbers using IANA-registered CBOR tags:
| Tag | Description | Format |
|---|---|---|
| 43000 | Single complex number | [real, imag] |
| 43001 | Complex array | Interleaved typed array [r0, i0, r1, i1, ...] |
Single Complex Numbers¶
std::complex<double> c{1.0, 2.0};
std::string buffer{};
glz::write_cbor(c, buffer);
std::complex<double> result;
glz::read_cbor(result, buffer);
// result.real() == 1.0, result.imag() == 2.0
The CBOR format is:
Complex Arrays¶
Complex arrays use tag 43001 with an interleaved typed array for bulk memory operations:
std::vector<std::complex<double>> values = {
{1.0, 0.5},
{2.0, 1.0},
{3.0, 1.5}
};
std::string buffer{};
glz::write_cbor(values, buffer); // Uses bulk memcpy
std::vector<std::complex<double>> result;
glz::read_cbor(result, buffer);
The CBOR format is:
This format leverages the fact that std::complex<T> stores real and imaginary parts contiguously in memory, enabling efficient bulk serialization.
Complex Eigen Matrices¶
Complex Eigen matrices are fully supported:
Eigen::MatrixXcd m(2, 2);
m << std::complex<double>(1, 1), std::complex<double>(2, 2),
std::complex<double>(3, 3), std::complex<double>(4, 4);
std::string buffer{};
glz::write_cbor(m, buffer);
Eigen::MatrixXcd result;
glz::read_cbor(result, buffer);
Bitsets¶
std::bitset is serialized as a CBOR byte string:
std::bitset<32> bits = 0b10101010'11110000'00001111'01010101;
std::string buffer{};
glz::write_cbor(bits, buffer);
std::bitset<32> result;
glz::read_cbor(result, buffer);
Floating-Point Preferred Serialization¶
Following RFC 8949 preferred serialization, Glaze automatically uses the smallest floating-point representation that exactly represents the value:
- Half-precision (16-bit) when possible
- Single-precision (32-bit) when half is insufficient
- Double-precision (64-bit) as fallback
This reduces message size while preserving exact values.