Skip to main content

Module size

Module size 

Source
Expand description

Phase 380 W1 — a message’s serialized size, computed instead of guessed.

NROS_SUBSCRIPTION_BUFFER_SIZE defaults to 1024 bytes and is a GUESS. Nothing checks it against the messages an image actually subscribes to, so a sample that does not fit is dropped AFTER the transport ACKed it, and report_dropped_take can only say “raise the knob” because the runtime does not know what value would have worked. On a target that knob is static RAM nobody can spare. Issue 0776 is the gap; this module is the calculator.

§Why this is not a vtable slot

Settled in phase-376 W4: nothing about a size bound varies by backend, and upstream proves it by not varying at all — both librmw_cyclonedds_cpp.so and librmw_fastrtps_cpp.so answer rmw_get_serialized_message_size with RMW_RET_UNSUPPORTED, and nothing in a Humble install calls it. Upstream can afford that because its serialized buffer RESIZES; the bound is a hint that saves a realloc. Ours cannot resize, so the same number is load-bearing here.

§Thread the offset — do not sum the maxima

Padding is a function of WHERE a field starts, so a calculation that sums per-field maxima is wrong the moment a variable-length field shifts what follows. size_bound therefore takes current_alignment in and returns the size from there, which is also what makes nested structs compose with no special case — the same signature rosidl’s generated Fast-RTPS support uses (max_serialized_size_T(full_bounded, is_plain, current_alignment)).

§Agreement with the writer is the only thing that matters

Every rule below was read out of CdrWriter, not out of the CDR spec: align() caps alignment at 4 under XCDR2 and honours 8 under XCDR1; begin_dheader() aligns to 4 and reserves 4 bytes for EVERY struct under XCDR2 (a generated serialize opens with it, so nested structs get one too); write_string writes len + 1 and then the NUL. A bound that merely looks right is worthless — see size_tests.rs, which checks it against the bytes the writer actually produced.

Structs§

SizeBound
What one walk of a schema can say about size.
UnboundedField
The first member that makes a type unbounded, named.

Enums§

UnboundedKind
Which unbounded member kind was reached.

Constants§

ENCAPSULATION_HEADER_BYTES
The encapsulation header the payload crossing our vtable carries: 2 bytes of representation id + 2 of options.
MAX_FIELD_PATH_DEPTH
How deep a field path first_unbounded will name before it stops.

Functions§

bound_fits
Phase 380 W4 — the BUILD-ASSERTION predicate: false only when the type is provably too large for rx_buf.
buffer_fits
Phase 380 W4 — does a receive buffer of rx_buf bytes fit every message of this type?
first_unbounded
Find the first member that makes fields unbounded, if any.
is_loan_eligible
Phase 380 W5 — is this type loan-eligible?
max_serialized_bound
Phase 392 W3a — the type’s own receive-buffer bound, or None when it has none.
max_serialized_size
The whole payload a publisher hands the transport: encapsulation header plus the struct’s body, starting from offset 0.
serialized_size
Phase 380 W3 — the EXACT serialized size of THIS message.
size_bound
Walk fields from current_alignment, returning the size bound of the struct they describe.
visit_unbounded
Report EVERY member that makes fields unbounded, in declaration order.