CDR (Common Data Representation)
The cdr component provides reflection-driven CDR/XCDR serialization for
plain C++ structs — the compiler generates the serialization code from the
struct definition itself. There is no IDL compiler and no hand-written
read/write call sequence; defining an aggregate struct is all it takes:
struct ImuSample {
uint64_t stamp_us;
std::array<float, 3> accel;
std::array<float, 3> gyro;
float temperature;
};
auto bytes = cdr::serialize(sample); // XCDR2, appendable (default)
auto ros2 = cdr::serialize<cdr::xcdr1>(sample); // ROS 2 / classic-CDR peers
auto back = cdr::deserialize<ImuSample>(*bytes); // std::expected<ImuSample, cdr::error>
The implementation is the finger563/cdr
library, vendored as a git submodule under detail/, with the
reflect_cpp component as its reflection backend. See the
library’s README for the
supported type mapping and its
design document
for the architecture and wire-format rules.
Feature highlights:
XCDR1 (plain CDR — what ROS 2 and CycloneDDS speak by default) and XCDR2 (plain + delimited/appendable with DHEADER — what Fast DDS and OpenDDS speak by default), in both endiannesses
appendable schema evolution in both directions: newer peers’ extra members are skipped, missing members keep their defaults
wire format byte-verified against
pycdr2(CycloneDDS’s codec); the Python side of a message is a plainpycdr2dataclass — no bindingsstd::expectederror handling carrying an error code, payload offset, and the field name that failed; bounds-checked, fuzz-tested deserializerscdr::bounded_string<N>/cdr::bounded_vector<T, N>for IDL bounded typescdr::param_list_writer/cdr::param_list_readerfor the PL_CDR parameter lists used by RTPS discovery (SPDP/SEDP)zero-allocation
cdr::serialize_intoand body-only variants for composing RTPS submessages
Everything lives in the cdr namespace (not espp), matching the
standalone library. Requires C++23 (std::expected), the default C++
standard on ESP-IDF 5.2+ toolchains.
Note
This component replaces the earlier manual espp::CdrWriter /
espp::CdrReader API. The rtps component and examples have been
migrated; payloads previously built with hand-written write/read call
sequences are now plain structs.