zerodds-cdr

Layer 1 — Primitives. XCDR1/XCDR2 encoder/decoder + KeyHash + PL_CDR1.

zerodds-cdr fully implements the OMG XTypes 1.3 §7.4 wire-format family: alignment-tracking buffer I/O, primitive + composite type encoding, struct extensibility (final / appendable / mutable), KeyHash with MD5 fallback, and the XTypes PL_CDR1 member codec.

Pure-Rust no_std + alloc, forbid(unsafe_code).

Spec anchors

  • OMG XTypes 1.3 §7.4 (wire encoding) incl. §7.4.1.2 (PL_CDR1), §7.4.2 (Plain CDR2 / Delimited CDR2 / PL_CDR2), §7.4.4 (composite types: string/sequence/array/optional), §7.4.5 (struct extensibility).
  • OMG XTypes 1.3 §7.6.8 KeyHash (CDR_BE key holder + MD5 fallback).
  • OMG IDL 4.2 §7.4.13 — fixed<P, S> decimal type (BCD encoding).
  • DDSI-RTPS 2.5 §10 — wire encapsulation, RepresentationIdentifier bytes.

Public API (selection)

Buffer I/O:

  • BufferReader<'a> / BufferWriter — alignment-tracking byte-level I/O.
  • Endianness::{Little, Big}.

Trait family:

  • CdrEncode / CdrDecode — serializer traits for all XCDR2 wire primitives.

Composite-type impls (for str, String, Vec<T>, [T; N], Option<T>):

  • via the composite module (XTypes §7.4.4).

Struct-extensibility encoder (struct_enc module):

  • encode_final / decode_final — XCDR2 Plain CDR2 (§7.4.2.1).
  • encode_appendable / decode_appendable — XCDR2 Delimited CDR2 (§7.4.2.2).
  • MutableStructEncoder — XCDR2 parameter-list encoder with required-members validation (§7.4.2.4).
  • read_mutable_member / read_all_mutable_members — EMHEADER decode with length-code switch.

XCDR1 / PL_CDR1 (xcdr1 module):

  • encode_pl_cdr1_member / read_pl_cdr1_member — member codec with standard + extended header.
  • write_pl_cdr1_sentinelPID_LIST_END (0x3F02) terminator.

Fixed decimal:

  • Fixed<const P: u32, const S: u32> — IDL fixed<P, S> with BCD wire format.

KeyHash (key_hash module):

  • compute_key_hash(holder: &[u8], max_size: usize) -> [u8; 16] — XTypes §7.6.8.
  • PlainCdr2BeKeyHolder — CDR_BE-encoded key holder.

Serde bridge (serde_bridge module, feature serde-bridge):

  • encode_via_serde<T: Serialize> / decode_via_serde<T: DeserializeOwned> — XCDR2-string wrap of any serde type (JSON intermediate form). Spec: zerodds-xcdr2-rust-1.0 §11.3.

XCDR2 bindings conformance:

  • 16 wire-vector tests (V-1..V-12) in tests/xcdr2_wire_vectors.rs, byte-exact against zerodds-xcdr2-bindings-conformance-1.0 §6.
  • 15 cross-vendor decoder tests in tests/xcdr2_cross_vendor_fixtures.rs (14 spec-derived + V-2 recorded from Cyclone DDS 0.10.2 via tcpdump).

Quick start

use zerodds_cdr::{BufferWriter, BufferReader, Endianness, CdrEncode, CdrDecode};

// Encoder
let mut w = BufferWriter::new(Endianness::Little);
42u32.encode(&mut w).unwrap();
let bytes = w.into_bytes();

// Decoder
let mut r = BufferReader::new(&bytes, Endianness::Little);
assert_eq!(u32::decode(&mut r).unwrap(), 42);

Structs with extensibility

use zerodds_cdr::struct_enc::{encode_appendable, encode_final, MutableStructEncoder};
use zerodds_cdr::{BufferWriter, Endianness, CdrEncode};

let mut w = BufferWriter::new(Endianness::Little);

// @final: tight-packed, no header
encode_final(&mut w, |w| { 1u32.encode(w)?; 2u8.encode(w) }).unwrap();

// @appendable: 4-byte DHEADER, forward-compatible
encode_appendable(&mut w, |w| { 3u32.encode(w) }).unwrap();

// @mutable: per-member EMHEADER + required-members validation
let mut enc = MutableStructEncoder::new(&mut w, vec![1, 2]);
enc.encode_member(1, false, |w| 10u32.encode(w)).unwrap();
enc.encode_member(2, false, |w| 20u32.encode(w)).unwrap();
enc.finish().unwrap();

Feature flags

Feature Default Purpose
std std re-exports, implies alloc
alloc enables composite / fixed / key_hash / struct_enc / xcdr1
safety Reserved for safety-class hardening (Phase 2)

Tests

cargo test -p zerodds-cdr: 201 tests (170 unit + 1 compliance_xcdr2 + 7 fuzz_smoke + 7 integration_topic + 15 proptest_roundtrip + 1 doctest).

Bench suite encode_decode_hotpaths (criterion). libFuzzer targets in fuzz/ for PL_CDR1 + composite + struct_enc.

Stability

All public-API items are semver-stable from 1.0.0-rc.3.

zerodds-cdr

Layer 1 — Primitives. XCDR1/XCDR2 Encoder/Decoder + KeyHash + PL_CDR1.

zerodds-cdr implementiert die OMG XTypes 1.3 §7.4 Wire-Format-Familie vollständig: alignment-tracking Buffer-I/O, primitive + composite Type-Encoding, Struct-Extensibility (final / appendable / mutable), KeyHash mit MD5-Fallback und den XTypes-PL_CDR1 Member-Codec.

Pure-Rust no_std + alloc, forbid(unsafe_code).

Spec-Anker

  • OMG XTypes 1.3 §7.4 (Wire-Encoding) inkl. §7.4.1.2 (PL_CDR1), §7.4.2 (Plain CDR2 / Delimited CDR2 / PL_CDR2), §7.4.4 (Composite Types: String/Sequence/Array/Optional), §7.4.5 (Struct-Extensibility).
  • OMG XTypes 1.3 §7.6.8 KeyHash (CDR_BE Key-Holder + MD5-Fallback).
  • OMG IDL 4.2 §7.4.13 — fixed<P, S> Decimal-Type (BCD-Encoding).
  • DDSI-RTPS 2.5 §10 — Wire-Encapsulation, RepresentationIdentifier-Bytes.

Public API (Auswahl)

Buffer-I/O:

  • BufferReader<'a> / BufferWriter — alignment-tracking byte-level I/O.
  • Endianness::{Little, Big}.

Trait-Familie:

  • CdrEncode / CdrDecode — Serializer-Traits für alle XCDR2-Wire-Primitives.

Composite-Type-Impls (für str, String, Vec<T>, [T; N], Option<T>):

  • via composite-Modul (XTypes §7.4.4).

Struct-Extensibility-Encoder (struct_enc-Modul):

  • encode_final / decode_final — XCDR2 Plain CDR2 (§7.4.2.1).
  • encode_appendable / decode_appendable — XCDR2 Delimited CDR2 (§7.4.2.2).
  • MutableStructEncoder — XCDR2 Parameter-List Encoder mit Required-Members-Validierung (§7.4.2.4).
  • read_mutable_member / read_all_mutable_members — EMHEADER-Decode mit Length-Code-Switch.

XCDR1 / PL_CDR1 (xcdr1-Modul):

  • encode_pl_cdr1_member / read_pl_cdr1_member — Member-Codec mit Standard- + Extended-Header.
  • write_pl_cdr1_sentinelPID_LIST_END (0x3F02) Terminator.

Fixed-Decimal:

  • Fixed<const P: u32, const S: u32> — IDL-fixed<P, S> mit BCD-Wire-Format.

KeyHash (key_hash-Modul):

  • compute_key_hash(holder: &[u8], max_size: usize) -> [u8; 16] — XTypes §7.6.8.
  • PlainCdr2BeKeyHolder — CDR_BE-encoded Key-Holder.

Serde-Bridge (serde_bridge-Modul, Feature serde-bridge):

  • encode_via_serde<T: Serialize> / decode_via_serde<T: DeserializeOwned> — XCDR2-string-Wrap eines beliebigen serde-Types (JSON-Zwischenform). Spec: zerodds-xcdr2-rust-1.0 §11.3.

XCDR2-Bindings-Conformance:

  • 16 Wire-Vector-Tests (V-1..V-12) in tests/xcdr2_wire_vectors.rs, byte-genau gegen zerodds-xcdr2-bindings-conformance-1.0 §6.
  • 15 Cross-Vendor-Decoder-Tests in tests/xcdr2_cross_vendor_fixtures.rs (14 spec-derived + V-2 echt von Cyclone DDS 0.10.2 via tcpdump aufgezeichnet).

Quick Start

use zerodds_cdr::{BufferWriter, BufferReader, Endianness, CdrEncode, CdrDecode};

// Encoder
let mut w = BufferWriter::new(Endianness::Little);
42u32.encode(&mut w).unwrap();
let bytes = w.into_bytes();

// Decoder
let mut r = BufferReader::new(&bytes, Endianness::Little);
assert_eq!(u32::decode(&mut r).unwrap(), 42);

Strukturen mit Extensibility

use zerodds_cdr::struct_enc::{encode_appendable, encode_final, MutableStructEncoder};
use zerodds_cdr::{BufferWriter, Endianness, CdrEncode};

let mut w = BufferWriter::new(Endianness::Little);

// @final: tight-packed, kein Header
encode_final(&mut w, |w| { 1u32.encode(w)?; 2u8.encode(w) }).unwrap();

// @appendable: 4-byte DHEADER, forward-kompatibel
encode_appendable(&mut w, |w| { 3u32.encode(w) }).unwrap();

// @mutable: per-Member EMHEADER + Required-Members-Validierung
let mut enc = MutableStructEncoder::new(&mut w, vec![1, 2]);
enc.encode_member(1, false, |w| 10u32.encode(w)).unwrap();
enc.encode_member(2, false, |w| 20u32.encode(w)).unwrap();
enc.finish().unwrap();

Feature-Flags

Feature Default Zweck
std std-Re-Exports, implies alloc
alloc aktiviert composite / fixed / key_hash / struct_enc / xcdr1
safety Reserved für Safety-Class-Hardening (Phase-2)

Tests

cargo test -p zerodds-cdr: 201 Tests (170 unit + 1 compliance_xcdr2 + 7 fuzz_smoke + 7 integration_topic + 15 proptest_roundtrip + 1 doctest).

Bench-Suite encode_decode_hotpaths (criterion). libFuzzer-Targets in fuzz/ für PL_CDR1 + composite + struct_enc.

Stability

Alle Public-API-Items sind ab 1.0.0-rc.3 semver-stabil.