The common testing workflow sends typed holders and recipes through MulticastFeed. Use the lower-level facilities on this page when messages are selected at runtime, a test already owns a complete datagram, or another transport must deliver packets built by the testing API.
All collection overloads require data() to return exactly ByteSpan* or const ByteSpan* and size() to return a non-boolean integral type. Vectors, arrays, and, in C++20 builds, mutable or const std::span views satisfy this contract. The collection, its span descriptors, and the referenced bytes must remain valid and unchanged until the send call returns.
| API | Packet header | Permitted collection size | Empty collection |
|---|---|---|---|
| MulticastFeed or another DataFeed | Prepended by the feed | 1 through MaxSpansCount - 1 messages | Rejected; send a heartbeat holder or PacketHolder<> |
| MulticastTarget or MulticastSender | Not added | 0 through MulticastTarget::MaxSpansCount spans | Accepted by collection validation |
Negative or excessive counts throw std::runtime_error before the span descriptors are accessed or delivery is attempted. Aggregate packet-size limits and ordinary delivery failures still apply. The sending implementation consumes or copies the bytes before returning, so the collection and referenced storage may be destroyed while a returned completion event is still pending.
Pass a contiguous collection of ByteSpan objects to MulticastFeed when encoded messages are selected at runtime. The feed constructs the PacketHeader and sends the referenced messages in collection order.
Each message holder must be committed before its span is added to the collection. Calling toNetworkBytes or the free asSpan helper performs that commit.
Use MulticastSender or MulticastTarget when a test already owns a complete datagram. ByteSpan is a non-owning, read-only view; its referenced storage must remain valid for the duration of the send call.
The returned completion event follows the same synchronous-primary and optional asynchronous-secondary contract as MulticastFeed.
When a complete datagram is split across buffers, pass a collection of ByteSpan objects. The referenced bytes are concatenated in collection order.
Collection sends do not construct a PacketHeader; include one explicitly when sending a complete CME packet. The header consumes one of the permitted spans. A nonempty collection must point to at least its reported number of contiguous ByteSpan objects; a null pointer is permitted when the reported size is zero. Each nonempty ByteSpan must also have a non-null data pointer. Invalid collection storage or span data is rejected with std::runtime_error before delivery begins.
DataFeed<Delivery> separates packet construction from delivery. Include <OnixS/CME/MDH/testing/DataFeed.h> when defining another delivery policy. DataFeed materializes holders and recipes, prepends the packet header, enforces the delivery policy's span limit, and forwards the completed spans to its delivery policy.
The privately inherited policy can keep its constructor, destructor, and hooks protected. It must provide send, sendPrimary, and sendSecondary hooks accepting an array of complete ByteSpan packet spans; primaryFeed, secondaryFeed, and hasSecondary queries; and a MaxSpansCount constant that includes the packet-header span. send returns Threading::Event; the targeted send hooks return void. Constructor arguments supplied to DataFeed are forwarded to the policy.
The span array and all referenced bytes remain valid only until the delivery hook returns. A policy must consume or copy them before returning, even when send returns an event representing asynchronous work. See the DataFeed API reference for the complete policy contract and exception behavior.