Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
Buffer Module - User Guide

What is a Buffer?

A Buffer is a lightweight, bounds-tracked view over caller-owned storage. You provide the backing storage (static array, stack buffer), and the buffer tracks how much data is currently valid. No allocation, no freeing - just state tracking.

Key concept: Buffer is a VIEW, not the owner of storage.

Quick Start

1. Allocate Backing Storage

// Static buffer for 256 bytes
static uint8_t buffer_storage[256];

2. Bind Buffer View

rte_status_t rc = rte_buffer_init(&buf, buffer_storage, sizeof(buffer_storage));
if (rc != RTE_STATUS_OK) {
printf("Buffer init failed\n");
return rc;
}
// buf now has: data=buffer_storage, capacity=256, length=0
rte_status_t rte_buffer_init(rte_buffer_t *buf, void *storage, size_t capacity)
Binds a buffer view to caller-owned storage. Initial length is 0.
Definition rte_buffer.c:9
rte_status_t
Common result/status codes.
Definition rte_status.h:27
@ RTE_STATUS_OK
Definition rte_status.h:28
Mutable, bounds-tracked view over caller-owned storage.
Definition rte_buffer.h:36

3. Use Buffer

// Write data into storage (caller manages writes to data pointer)
memcpy(buf.data, input, input_len);
// Mark data as valid
rte_buffer_set_length(&buf, input_len);
// Read data
printf("Buffer contains %zu bytes\n", buf.length);
// Clear for reuse
rte_buffer_clear(&buf); // Sets length=0, keeps data/capacity
rte_status_t rte_buffer_set_length(rte_buffer_t *buf, size_t length)
Marks length bytes of already-written storage as valid.
Definition rte_buffer.c:31
rte_status_t rte_buffer_clear(rte_buffer_t *buf)
Resets length to 0; capacity and data are unchanged.
Definition rte_buffer.c:21
void * data
Definition rte_buffer.h:37
size_t length
Definition rte_buffer.h:39

Key Structures

typedef struct {
void *data; // Pointer to backing storage (caller-owned)
size_t capacity; // Total bytes available in storage
size_t length; // Bytes currently holding valid data
typedef struct {
const void *data; // Read-only view of data
size_t length; // Bytes of valid data
Read-only view of a buffer's currently valid bytes. Grants no write access to the underlying storage.
Definition rte_buffer.h:47

Invariant: length <= capacity

Practical Examples

Example 1: Fixed-Size Message Buffer

typedef struct {
uint32_t command_id;
uint32_t seq_num;
uint8_t payload[128];
} message_t;
message_t msg = {0};
// Bind buffer to message payload
rte_buffer_init(&buf, msg.payload, sizeof(msg.payload));
// Receive data into payload
receive_from_network(&buf.data[0], 64);
// Send message
msg.command_id = 1;
msg.seq_num = seq++;
send_message(&msg);
// Clear for next use

Example 2: Read-Only View

rte_buffer_t mutable_buf = {...};
// Create read-only view
.data = mutable_buf.data,
.length = mutable_buf.length
};
// Pass to function that should not modify
process_read_only(&view);

Buffer Operations

Initialize

rte_buffer_init(&buf, storage, capacity);
  • Sets buf.data = storage
  • Sets buf.capacity = capacity
  • Sets buf.length = 0
  • Returns INVALID_PARAM if storage==NULL or capacity==0

Write Data

// Caller writes to buf.data
memcpy(buf.data + offset, input, size);
// Mark data as valid
rte_buffer_set_length(&buf, new_length);

rte_buffer_set_length() fails if new_length > capacity.

Read Data

// Caller reads from buf.data
size_t n = buf.length; // How much valid data
memcpy(output, buf.data, n);

Clear

rte_buffer_clear(&buf); // Sets length=0, keeps capacity/data

Best Practices

  1. Caller owns storage lifetime
    • Buffer just tracks state
    • Storage must outlive buffer
    • Static or stack allocation recommended
  2. Check capacity before writing
    • Caller responsible for bounds checking
    • Buffer tracks length, not write protection
    • rte_buffer_set_length() validates
  3. Use rte_buffer_set_length() for bounds checking
    • Always call after writing
    • Returns error if length > capacity
    • Prevents out-of-bounds bugs
  4. Use const_buffer_t for read-only access
    • Pass to functions that should not modify
    • Type-safe read-only contract
  5. Clear when done
    • Reset length to 0 for reuse
    • Resets valid-data range, not storage

See Also