zerodds-recorder-decode

Tooling. Support crate (safety class COMFORT, no runtime hot path) that decodes DDS samples for zerodds-spy, zerodds-record and zerodds-replay; it implements no specification of its own.

zerodds-recorder-decode turns received samples into typed JSON and SQLite and reads them back for replay. It builds on zerodds-wire-codec, which walks the type model in both directions, and on the DynamicType of zerodds-types. Both sinks keep the raw CDR bytes of every sample, so zerodds-replay can publish them again byte for byte from either format.

  • type_source — TypeSource::from_idl parses an out-of-band IDL file (the --type-file path) through zerodds-idl-compose with all vendor extensions admitted; resolve returns the DynamicType for a type name. A reference that resolves nowhere refuses the file. parse_topic_type_map reads topic=Type entries.
  • wire — encoding_of(type, xcdr2) derives the framing (PLAIN_CDR1, PLAIN_CDR2, DELIMITED_CDR, PL_CDR1, PL_CDR2) from the extensibility of the type and the XCDR version, per XTypes 1.3 §7.4 Table 17.
  • json_sink — DynamicData → JSON and an NDJSON sink. Each line carries topic, type, recv_ts_ns, writer, the decoded value and raw_cdr as hex. Integers outside i64/u64, fixed<P, S> and long double are written as strings; NaN and ±inf become null.
  • sqlite_sink — one table t_<T> per topic with sample_id (record marker, primary key), recv_ts_ns, writer, raw_cdr and one typed column per scalar member (1:1 nested structs and bitsets flattened to field__sub); child tables t_<T>__<member> for sequences, arrays, maps and bitmasks, joined by sample_id; _types holds the IDL per topic. A uint64 above 263, fixed<P, S> and long double are stored as exact TEXT. Members without a flat column shape are skipped and listed by skipped_members. helper_queries emits ready-to-run SQL.
  • replay_source — from_ndjson and from_sqlite (opened read-only, sorted by recv_ts_ns across topics) return RecordedSamples (topic, type_name, recv_ts_ns, raw_cdr). Reading .zddsrec stays in zerodds-recorder.

Consumers

  • zerodds-spy, zerodds-record, zerodds-replay (all in tools/).

Status

  • std; no forbid(unsafe_code) attribute, and no unsafe in src/.
  • Library only, no binaries. No cargo features. Dependencies include serde_json and rusqlite (workspace version 0.32 with bundled).
  • 28 test functions in src/, 6 in tests/decode_roundtrip.rs, which runs the pipeline IDL → encode → JSON and SQLite sinks → replay source across XCDR1/XCDR2 and both byte orders.

zerodds-recorder-decode

Werkzeuge. Unterstützendes Crate (Sicherheitsklasse COMFORT, kein zeitkritischer Pfad zur Laufzeit), das DDS-Samples für zerodds-spy, zerodds-record und zerodds-replay dekodiert; es implementiert keine eigene Spezifikation.

zerodds-recorder-decode wandelt empfangene Samples in typisiertes JSON und SQLite um und liest sie für die Wiedergabe zurück. Es baut auf zerodds-wire-codec auf, das das Typmodell in beide Richtungen durchläuft, und auf dem DynamicType aus zerodds-types. Beide Senken behalten die rohen CDR-Bytes jedes Samples, sodass zerodds-replay sie aus beiden Formaten Byte für Byte erneut veröffentlichen kann.

  • type_source — TypeSource::from_idl parst eine separat übergebene IDL-Datei (der Weg über --type-file) mit zerodds-idl-compose, wobei alle Herstellererweiterungen zugelassen sind; resolve liefert den DynamicType zu einem Typnamen. Eine Referenz, die sich nicht auflösen lässt, führt zur Ablehnung der Datei. parse_topic_type_map liest Einträge der Form topic=Type.
  • wire — encoding_of(type, xcdr2) leitet die Rahmung (PLAIN_CDR1, PLAIN_CDR2, DELIMITED_CDR, PL_CDR1, PL_CDR2) aus der Erweiterbarkeit des Typs und der XCDR-Version ab, nach XTypes 1.3 §7.4 Tabelle 17.
  • json_sink — DynamicData → JSON und eine Senke für NDJSON. Jede Zeile enthält topic, type, recv_ts_ns, writer, den dekodierten value und raw_cdr als Hex. Ganzzahlen außerhalb von i64/u64, fixed<P, S> und long double werden als Zeichenketten geschrieben; NaN und ±inf werden zu null.
  • sqlite_sink — eine Tabelle t_<T> je Topic mit sample_id (Datensatzmarke, Primärschlüssel), recv_ts_ns, writer, raw_cdr und einer typisierten Spalte je skalarem Member (1:1 geschachtelte Strukturen und Bitsets flach als field__sub); Kindtabellen t_<T>__<member> für Sequenzen, Arrays, Maps und Bitmasks, verknüpft über sample_id; _types enthält die IDL je Topic. Ein uint64 über 263, fixed<P, S> und long double werden exakt als TEXT gespeichert. Member ohne flache Spaltenform werden übersprungen und von skipped_members aufgelistet. helper_queries gibt ausführbares SQL aus.
  • replay_source — from_ndjson und from_sqlite (nur lesend geöffnet, über alle Topics nach recv_ts_ns sortiert) liefern RecordedSample-Werte (topic, type_name, recv_ts_ns, raw_cdr). Das Lesen von .zddsrec bleibt in zerodds-recorder.

Konsumenten

  • zerodds-spy, zerodds-record, zerodds-replay (alle unter tools/).

Status

  • std; kein Attribut forbid(unsafe_code), und kein unsafe in src/.
  • Nur Bibliothek, keine Binaries. Keine Cargo-Features. Zu den Abhängigkeiten gehören serde_json und rusqlite (Workspace-Version 0.32 mit bundled).
  • 28 Testfunktionen in src/, 6 in tests/decode_roundtrip.rs, das die Kette IDL → Kodierung → Senken für JSON und SQLite → Wiedergabequelle über XCDR1/XCDR2 und beide Byte-Reihenfolgen durchläuft.