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 uint8_t buffer_storage[256];
2. Bind Buffer View
printf("Buffer init failed\n");
return rc;
}
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.
rte_status_t
Common result/status codes.
Mutable, bounds-tracked view over caller-owned storage.
3. Use Buffer
memcpy(buf.
data, input, input_len);
printf(
"Buffer contains %zu bytes\n", buf.
length);
rte_status_t rte_buffer_set_length(rte_buffer_t *buf, size_t length)
Marks length bytes of already-written storage as valid.
rte_status_t rte_buffer_clear(rte_buffer_t *buf)
Resets length to 0; capacity and data are unchanged.
Key Structures
typedef struct {
void *data;
size_t capacity;
size_t length;
typedef struct {
const void *data;
size_t length;
Read-only view of a buffer's currently valid bytes. Grants no write access to the underlying storage.
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};
receive_from_network(&buf.
data[0], 64);
msg.command_id = 1;
msg.seq_num = seq++;
send_message(&msg);
Example 2: Read-Only View
.data = mutable_buf.
data,
};
process_read_only(&view);
Buffer Operations
Initialize
- Sets buf.data = storage
- Sets buf.capacity = capacity
- Sets buf.length = 0
- Returns INVALID_PARAM if storage==NULL or capacity==0
Write Data
memcpy(buf.
data + offset, input, size);
rte_buffer_set_length() fails if new_length > capacity.
Read Data
memcpy(output, buf.
data, n);
Clear
Best Practices
- Caller owns storage lifetime
- Buffer just tracks state
- Storage must outlive buffer
- Static or stack allocation recommended
- Check capacity before writing
- Caller responsible for bounds checking
- Buffer tracks length, not write protection
- rte_buffer_set_length() validates
- Use rte_buffer_set_length() for bounds checking
- Always call after writing
- Returns error if length > capacity
- Prevents out-of-bounds bugs
- Use const_buffer_t for read-only access
- Pass to functions that should not modify
- Type-safe read-only contract
- Clear when done
- Reset length to 0 for reuse
- Resets valid-data range, not storage
See Also