AxlRingBuf – Ring Buffer
See AxlData – Data Structures for an overview of all data modules including the ring buffer (circular byte buffer).
Header: <axl/axl-ring-buf.h>
API Reference
Defines
-
AXL_RING_BUF_OVERWRITE
Overwrite oldest data when buffer is full.
Functions
-
int axl_ring_buf_init(AxlRingBuf *rb, void *buf, uint32_t size, uint32_t flags, void (*buf_free)(void*))
Initialize an embedded ring buffer with a caller-provided buffer.
No heap allocation. The caller owns both the AxlRingBuf struct and the backing buffer. Pass a
buf_freefunction to have deinit free the buffer, or NULL if the caller manages the buffer lifetime.- Parameters:
rb – caller-allocated struct
buf – backing buffer (must be power-of-2 sized)
size – buffer size in bytes (must be power of 2)
flags – AXL_RING_BUF_OVERWRITE or 0
buf_free – buffer deallocator, or NULL
- Returns:
0 on success, -1 if
sizeis not a power of 2 or args NULL.
-
void axl_ring_buf_deinit(AxlRingBuf *rb)
Release resources for an initialized ring buffer.
Calls the buf_free function (if set) to free the backing buffer. Does NOT free the AxlRingBuf struct itself (use axl_ring_buf_free for heap-allocated ring buffers).
- Parameters:
rb – ring buffer (NULL-safe)
-
AxlRingBuf *axl_ring_buf_new(uint32_t min_size)
Create a ring buffer with at least
min_sizebytes capacity.Capacity is rounded up to the next power of 2. Rejects writes when full (use axl_ring_buf_new_full for overwrite mode).
- Parameters:
min_size – minimum capacity in bytes (rounded up to power of 2)
- Returns:
new AxlRingBuf, or NULL on allocation failure.
-
AxlRingBuf *axl_ring_buf_new_full(uint32_t min_size, uint32_t flags)
Create a ring buffer with flags.
- Parameters:
min_size – minimum capacity in bytes (rounded up to power of 2)
flags – AXL_RING_BUF_OVERWRITE or 0
- Returns:
new AxlRingBuf, or NULL on allocation failure.
-
AxlRingBuf *axl_ring_buf_new_with_buffer(void *buf, uint32_t size, uint32_t flags)
Create a ring buffer using a caller-provided backing buffer.
The struct is heap-allocated but the backing buffer is owned by the caller. axl_ring_buf_free will NOT free the buffer.
- Parameters:
buf – caller-provided buffer (must be power-of-2 sized)
size – buffer size in bytes (must be power of 2)
flags – AXL_RING_BUF_OVERWRITE or 0
- Returns:
new AxlRingBuf, or NULL on failure.
-
void axl_ring_buf_free(AxlRingBuf *rb)
Free a heap-allocated ring buffer.
Frees the backing buffer if owned (new/new_full), then frees the struct. For embedded ring buffers, use axl_ring_buf_deinit instead.
- Parameters:
rb – ring buffer (NULL-safe)
-
uint32_t axl_ring_buf_write(AxlRingBuf *rb, const void *data, uint32_t len)
Write bytes to the ring buffer.
In reject mode (default), writes up to the available space and returns the number of bytes actually written (may be less than
len). In overwrite mode, always writes all bytes, advancing the read position to discard the oldest data as needed.- Parameters:
rb – ring buffer
data – source data
len – number of bytes to write
- Returns:
number of bytes written.
-
uint32_t axl_ring_buf_read(AxlRingBuf *rb, void *dest, uint32_t len)
Read and consume bytes from the ring buffer.
- Parameters:
rb – ring buffer
dest – destination buffer
len – maximum bytes to read
- Returns:
number of bytes read (may be less than
len).
-
uint32_t axl_ring_buf_peek(AxlRingBuf *rb, void *dest, uint32_t len)
Read bytes without consuming them.
- Parameters:
rb – ring buffer
dest – destination buffer
len – maximum bytes to peek
- Returns:
number of bytes copied to
dest.
-
uint32_t axl_ring_buf_discard(AxlRingBuf *rb, uint32_t len)
Discard bytes from the read side without copying.
- Parameters:
rb – ring buffer
len – maximum bytes to discard
- Returns:
number of bytes discarded.
-
uint32_t axl_ring_buf_peek_regions(AxlRingBuf *rb, AxlRingBufRegion regions[2])
Get contiguous readable regions for zero-copy access.
Returns up to 2 regions covering all readable data. After processing, call axl_ring_buf_read_advance to consume.
- Parameters:
rb – ring buffer
regions – receives up to 2 regions
- Returns:
number of regions (0, 1, or 2).
-
uint32_t axl_ring_buf_write_regions(AxlRingBuf *rb, AxlRingBufRegion regions[2])
Get contiguous writable regions for zero-copy access.
Returns up to 2 regions covering all writable space. After filling, call axl_ring_buf_write_advance to commit.
- Parameters:
rb – ring buffer
regions – receives up to 2 regions
- Returns:
number of regions (0, 1, or 2).
-
void axl_ring_buf_read_advance(AxlRingBuf *rb, uint32_t len)
Advance the read position after zero-copy access.
- Parameters:
rb – ring buffer
len – bytes consumed
-
void axl_ring_buf_write_advance(AxlRingBuf *rb, uint32_t len)
Advance the write position after zero-copy access.
- Parameters:
rb – ring buffer
len – bytes produced
-
uint32_t axl_ring_buf_readable(AxlRingBuf *rb)
Get the number of readable bytes.
- Parameters:
rb – ring buffer
- Returns:
byte count available for reading.
-
uint32_t axl_ring_buf_writable(AxlRingBuf *rb)
Get the number of writable bytes.
- Parameters:
rb – ring buffer
- Returns:
byte count available for writing.
-
uint32_t axl_ring_buf_capacity(AxlRingBuf *rb)
Get the total buffer capacity.
- Parameters:
rb – ring buffer
- Returns:
capacity in bytes (always a power of 2).
-
bool axl_ring_buf_is_empty(AxlRingBuf *rb)
Check if the ring buffer is empty.
- Parameters:
rb – ring buffer
- Returns:
true if no data is available to read.
-
bool axl_ring_buf_is_full(AxlRingBuf *rb)
Check if the ring buffer is full.
- Parameters:
rb – ring buffer
- Returns:
true if no space is available for writing.
-
void axl_ring_buf_clear(AxlRingBuf *rb)
Discard all data and reset to empty.
- Parameters:
rb – ring buffer
-
int axl_ring_buf_write_elem(AxlRingBuf *rb, const void *elem, uint32_t elem_size)
Write a fixed-size element (all-or-nothing).
In reject mode, fails if insufficient space. In overwrite mode, always succeeds by discarding the oldest data.
- Parameters:
rb – ring buffer
elem – element to push
elem_size – element size in bytes
- Returns:
0 on success, -1 if not enough space (reject mode only).
-
int axl_ring_buf_read_elem(AxlRingBuf *rb, void *elem, uint32_t elem_size)
Read a fixed-size element (all-or-nothing).
- Parameters:
rb – ring buffer
elem – receives the element
elem_size – element size in bytes
- Returns:
0 on success, -1 if not enough data.
-
int axl_ring_buf_get_element(AxlRingBuf *rb, uint32_t index, void *dest, uint32_t elem_size)
Read an element by index without consuming.
Index 0 is the oldest element, element_count - 1 is the newest.
- Parameters:
rb – ring buffer
index – element index (0 = oldest)
dest – receives the element
elem_size – element size in bytes
- Returns:
0 on success, -1 if index out of range.
-
int axl_ring_buf_set_element(AxlRingBuf *rb, uint32_t index, const void *src, uint32_t elem_size)
Overwrite an element by index.
Index 0 is the oldest element, element_count - 1 is the newest.
- Parameters:
rb – ring buffer
index – element index (0 = oldest)
src – element data to write
elem_size – element size in bytes
- Returns:
0 on success, -1 if index out of range.
-
uint32_t axl_ring_buf_element_count(AxlRingBuf *rb, uint32_t elem_size)
Get the number of complete elements.
- Parameters:
rb – ring buffer
elem_size – element size in bytes
- Returns:
readable bytes / elem_size.
-
int axl_ring_buf_write_msg(AxlRingBuf *rb, const void *data, uint32_t len)
Write a length-prefixed message atomically.
Stores [uint32_t len][data] in the ring buffer. The write is all-or-nothing in reject mode. In overwrite mode, the write always succeeds but may corrupt the oldest message framing.
- Parameters:
rb – ring buffer
data – message payload
len – payload length in bytes
- Returns:
0 on success, -1 if not enough space.
-
int axl_ring_buf_read_msg(AxlRingBuf *rb, void *dest, uint32_t max_len, uint32_t *actual_len)
Read the next length-prefixed message.
Consumes the length header and payload. If
max_lenis too small for the message, returns -1 without consuming.- Parameters:
rb – ring buffer
dest – destination buffer
max_len – destination buffer size
actual_len – receives actual message length (may be NULL)
- Returns:
0 on success, -1 if no message or buffer too small.
-
uint32_t axl_ring_buf_peek_msg_size(AxlRingBuf *rb)
Peek at the size of the next message without consuming.
- Parameters:
rb – ring buffer
- Returns:
message payload size, or 0 if no complete header available.
-
struct AxlRingBuf
- #include <axl-ring-buf.h>
Ring buffer with power-of-2 sizing and monotonic indices.
Can be heap-allocated (via axl_ring_buf_new) or embedded in another struct/stack (via axl_ring_buf_init). Fields prefixed with _ are private — use the API functions, not direct access.
Public Members
-
uint8_t *buf
backing buffer
-
uint32_t size
capacity in bytes (power of 2)
-
uint32_t mask
size - 1
-
uint32_t read_pos
monotonically increasing read index
-
uint32_t write_pos
monotonically increasing write index
-
uint32_t flags
AXL_RING_BUF_OVERWRITE etc.
-
void (*buf_free)(void*)
buffer deallocator, or NULL if caller-owned
-
uint8_t *buf
-
struct AxlRingBufRegion
- #include <axl-ring-buf.h>
Contiguous memory region for zero-copy access.
Ring buffer data may span two regions (before and after the internal wrap point). Use with peek_regions / write_regions.
Public Members
-
void *data
pointer into the ring buffer
-
uint32_t len
number of bytes in this region
-
void *data