Data Structures

When sending and receiving in non-buffered mode, the data are passed ‘as is’. When using buffered sending/receiving, the data for multiple messages are inserted into the buffer as netio3::BufferMsg objects using the netio3::BufferFormatter. The individual messages may be retrieved from the buffer using the netio3::BufferFormatter::decode() static function. This function will call a user specified callback for each message in the buffer.

// define the callback function
auto callback = [](uint64_t tag,
                   std::span<const uint8_t> payload,
                   uint8_t status) {
  std::cout << std::format(
               "Received message for tag {:#x}, size {}, status {}\n",
               tag, payload.size(), status);
};
// Process the messages in the buffer
netio3::BufferFormatter::decode(buffer, &callback);

Format of Data Buffer

32-bit header | 8-bit status (only if non-zero) | 64-bit tag | message0 payload | 32-bit header | (8-bit status only if non-zero) | (64-bit tag only if different to message0 tag) | message1 payload…

The buffer always starts with a 32-bit header word. The header word has two one-bit flags indicating whether the current message includes a status word and a tag. The first message in a buffer will always contain a tag but subsequent messages in the buffer will only contain a tag if it is different from the tag in the previous message. The status word is only present if the status is non-zero.

Format of Header Word

bit 31

bit 30

bits 29..0

tag present flag

status present flag

message size

Format of subscription requests

Subscription requests (netio3::SubscriptionRequest) are sent as JSON formatted text.