AxlData – Data Structures

Core collection types: hash table, dynamic array, doubly-linked list, singly-linked list, queue, radix tree, and ring buffer.

Headers:

  • <axl/axl-hash-table.h> – Hash table with string keys (FNV-1a, chained)

  • <axl/axl-array.h> – Dynamic array (auto-growing, index access)

  • <axl/axl-list.h> – Doubly-linked list

  • <axl/axl-slist.h> – Singly-linked list

  • <axl/axl-queue.h> – FIFO queue

  • <axl/axl-radix-tree.h> – Radix tree (compact prefix tree, longest-prefix lookup)

  • <axl/axl-ring-buf.h> – Ring buffer (circular byte buffer, zero-copy, overwrite mode)

Choosing a Collection

Type

Best for

Lookup

Insert/Remove

AxlHashTable

Key-value mapping

O(1) by key

O(1) amortized

AxlArray

Indexed, sorted data

O(1) by index

O(1) append

AxlList

Frequent insert/remove

O(n) by value

O(1) at position

AxlSList

Simple linked sequences

O(n)

O(1) prepend

AxlQueue

FIFO/LIFO patterns

O(1) head/tail

O(1) push/pop

AxlRadixTree

Prefix-match routing

O(k) by key

O(k) insert

AxlRingBuf

Streaming I/O, pipes

O(1) read/write

O(1)

AxlHashTable

GLib-style hash table with FNV-1a hashing, chained collision resolution, and automatic resize at 75% load factor. Supports generic key types via user-provided hash/equal callbacks.

Convenience Constructor (string keys)

axl_hash_table_new_str() creates a table with string keys that are copied internally. Values are opaque pointers (not freed).

AXL_AUTOPTR(AxlHashTable) h = axl_hash_table_new_str();

axl_hash_table_insert(h, "name", "AXL");
axl_hash_table_insert(h, "version", "0.1.0");

const char *name = axl_hash_table_lookup(h, "name");   // "AXL"
size_t count = axl_hash_table_size(h);               // 2

axl_hash_table_remove(h, "version");
axl_hash_table_foreach(h, my_callback, user_data);

Full Constructor (generic keys, owned entries)

axl_hash_table_new_full(hash, equal, key_free, value_free) creates a table with custom hash/equal functions and optional destructors. Keys are NOT copied — the table takes ownership.

// Owned string keys and values
AxlHashTable *h = axl_hash_table_new_full(
    NULL, NULL,             // NULL = axl_str_hash/axl_str_equal
    axl_free_impl,          // key destructor
    axl_free_impl);         // value destructor

axl_hash_table_replace(h, axl_strdup("key"), axl_strdup("value"));
axl_hash_table_replace(h, axl_strdup("key"), axl_strdup("new"));  // old key+value freed
axl_hash_table_free(h);                                        // remaining entries freed

Pointer Keys

Use axl_direct_hash/axl_direct_equal for pointer or integer keys:

AxlHashTable *h = axl_hash_table_new_full(
    axl_direct_hash, axl_direct_equal, NULL, NULL);

axl_hash_table_insert(h, (void *)42, my_data);
void *data = axl_hash_table_lookup(h, (void *)42);

contains / steal / foreach_remove

// contains: distinguishes NULL-valued key from absent key
axl_hash_table_contains(h, "key");   // true even if value is NULL

// steal: remove without calling destructors (caller takes ownership)
axl_hash_table_steal(h, "key");

// foreach_remove: bulk conditional removal
size_t n = axl_hash_table_foreach_remove(h, predicate, data);

Iterator

Safe removal during iteration:

AxlHashTableIter iter;
void *key, *value;

axl_hash_table_iter_init(&iter, h);
while (axl_hash_table_iter_next(&iter, &key, &value)) {
    if (should_remove(key, value)) {
        axl_hash_table_iter_remove(&iter);   // calls destructors
    }
}

AxlArray

Dynamic array that stores elements by value (not pointers). Auto-grows on append. Supports indexed access, sorting, and removal. Matches GLib’s GArray.

AXL_AUTOPTR(AxlArray) a = axl_array_new(sizeof(int));

int values[] = {50, 20, 40, 10, 30};
for (int i = 0; i < 5; i++) {
    axl_array_append(a, &values[i]);
}

axl_array_sort(a, int_compare);
axl_array_remove_index(a, 0);        // remove first element
axl_array_remove_index_fast(a, 1);   // O(1) swap-with-last removal
axl_array_set_size(a, 10);           // grow (zero-initialized)

AxlList

GLib-style doubly-linked list. Each node has data, next, and prev pointers. Functions return the new head (which may change after prepend, remove, or sort). Matches GLib’s GList.

AxlList *list = NULL;
list = axl_list_append(list, "first");
list = axl_list_append(list, "second");
list = axl_list_prepend(list, "zeroth");

// Insert relative to a node
AxlList *node = axl_list_find(list, "first");
list = axl_list_insert_before(list, node, "half");

// Remove all matching, deep copy, context-aware sort
list = axl_list_remove_all(list, "first");
AxlList *copy = axl_list_copy_deep(list, my_copy_func, NULL);

axl_list_free(list);

AxlSList

Singly-linked list – lighter than AxlList (no prev pointer). Use when you only traverse forward. Matches GLib’s GSList. Same operations as AxlList: insert_before, remove_all, remove_link, sort_with_data, copy_deep.

AxlQueue

FIFO queue with push/pop at both ends and peek. Can also be used as a stack (push/pop from the same end). Matches GLib’s GQueue. Supports find, remove, and stack-allocated initialization.

AxlQueue q = AXL_QUEUE_INIT;    // stack-allocated
axl_queue_push_tail(&q, "first");
axl_queue_push_tail(&q, "second");
axl_queue_push_tail(&q, "first");  // duplicate

axl_queue_remove(&q, "first");     // removes first match
axl_queue_remove_all(&q, "first"); // removes all matches

AxlList *node = axl_queue_find(&q, "second");

AxlStr – String Utilities

String utilities operating on UTF-8 char * strings. Includes length, copy, compare, search, split, join, and case-insensitive operations (ASCII fold only). UCS-2 helpers at the bottom are for UEFI internal use.

All allocated results are freed with axl_free().

Header: <axl/axl-str.h>

Overview

AXL uses UTF-8 (char *) throughout its public API. UEFI firmware uses UCS-2 (unsigned short *) internally, but AXL handles the conversion transparently – you never need to deal with UCS-2 unless making direct UEFI protocol calls.

UTF-8 vs UCS-2

  • Use UTF-8 (char *) for all application code. All axl_str* functions operate on UTF-8.

  • UCS-2 functions (axl_wcslen, axl_wcscmp, axl_str_to_w, axl_str_from_w) exist only for UEFI interop. Consumer code should not need them.

Case-Insensitive Operations

axl_strcasecmp, axl_strcasestr, and axl_strncasecmp fold ASCII letters only (A-Z -> a-z). They do not handle full Unicode case mapping. This is sufficient for UEFI identifiers, HTTP headers, and file extensions.

Common Patterns

#include <axl.h>

// Split a string
char **parts = axl_strsplit("a,b,c", ',');
for (int i = 0; parts[i] != NULL; i++) {
    axl_printf("  %s\n", parts[i]);
}
axl_strfreev(parts);  // frees the array AND each string

// Join strings
const char *items[] = {"one", "two", "three", NULL};
char *joined = axl_strjoin(", ", items);
axl_printf("%s\n", joined);  // "one, two, three"
axl_free(joined);

// Search
if (axl_str_has_prefix(path, "fs0:")) { ... }
if (axl_str_has_suffix(name, ".efi")) { ... }
const char *found = axl_strcasestr(header, "content-type");

Memory Ownership

Functions that return char * allocate new memory. The caller must free with axl_free():

  • axl_strdup, axl_strndup

  • axl_strsplit (free with axl_strfreev)

  • axl_strjoin, axl_strstrip

  • axl_str_to_w, axl_str_from_w

Functions that return const char * or char * pointing into the input string do NOT allocate:

  • axl_strstr_len, axl_strrstr (return pointer into haystack)

  • axl_strchr (return pointer into string)

AxlString – String Builder

Mutable auto-growing string builder, like GLib’s GString. All strings are UTF-8. Supports append, prepend, insert, printf-style formatting, and truncation.

Header: <axl/axl-string.h>

Overview

Use AxlString when you need to build a string incrementally (in a loop, with formatting, from multiple sources). For simple one-shot formatting, use axl_asprintf instead.

AXL_AUTOPTR(AxlString) s = axl_string_new("Hello");
axl_string_append(s, " ");
axl_string_append_printf(s, "world #%d", 42);
axl_string_append_c(s, '!');

axl_printf("%s\n", axl_string_str(s));  // "Hello world #42!"
axl_printf("length: %zu\n", axl_string_len(s));

Stealing the Buffer

Transfer ownership of the internal buffer to avoid a copy:

AXL_AUTOPTR(AxlString) b = axl_string_new(NULL);
axl_string_append_printf(b, "key=%s", value);

char *result = axl_string_steal(b);  // b is now empty
// caller owns 'result', must free with axl_free()

The builder can be reused after stealing – it starts empty with its allocated buffer released.

Error Handling

All mutation functions (append, printf, etc.) return int: 0 on success, -1 if the internal realloc fails. This matches the convention used by axl_array_append, axl_hash_table_insert, etc.

AxlJson – JSON

JSON parser (JSMN-based) and builder (fixed buffer). Parse JSON strings into a token tree, query values by path, and build JSON documents incrementally.

Header: <axl/axl-json.h>

Overview

AXL provides two JSON APIs:

  • Parser – parse a JSON string, extract values by key or iterate arrays

  • Builder – construct JSON in a caller-provided buffer with no dynamic allocation

Parsing JSON

const char *json = "{\"name\":\"AXL\",\"version\":1,\"debug\":true}";
AxlJsonCtx ctx;

if (axl_json_parse(json, axl_strlen(json), &ctx)) {
    const char *name;
    size_t name_len;
    int64_t version;
    bool debug;

    axl_json_get_string(&ctx, "name", &name, &name_len);
    axl_json_get_int(&ctx, "version", &version);
    axl_json_get_bool(&ctx, "debug", &debug);

    axl_printf("name=%.*s version=%lld debug=%s\n",
               (int)name_len, name, version,
               debug ? "true" : "false");

    axl_json_free(&ctx);
}

Note: String values returned by axl_json_get_string point into the original JSON buffer (zero-copy). Do not free the original buffer while using extracted strings.

Building JSON

The builder writes into a caller-provided buffer with no heap allocation. Check overflow after building to detect truncation.

char buf[256];
AxlJsonBuilder j;

axl_json_init(&j, buf, sizeof(buf));
axl_json_object_start(&j);
axl_json_add_string(&j, "name", "AXL");
axl_json_add_uint(&j, "version", 1);
axl_json_add_bool(&j, "debug", true);
axl_json_object_end(&j);
axl_json_finish(&j);

if (!j.overflow) {
    axl_printf("%s\n", buf);
    // {"name":"AXL","version":1,"debug":true}
}

Iterating Arrays

// Parse: {"items":["a","b","c"]}
AxlJsonIter iter;
if (axl_json_array_begin(&ctx, "items", &iter)) {
    AxlJsonElement elem;
    while (axl_json_array_next(&iter, &elem)) {
        axl_printf("  %.*s\n", (int)elem.len, elem.value);
    }
}

AxlCache – TTL Cache

TTL cache with LRU eviction. Fixed-size slots, string keys, opaque fixed-size values. Designed for single-threaded UEFI use.

Header: <axl/axl-cache.h>

Overview

AxlCache is a simple key-value store with time-based expiration and least-recently-used eviction when full. Values are copied into fixed-size slots (not stored as pointers).

Use cases: DNS resolution caching, HTTP response caching, SMBIOS lookup caching.

// Cache up to 16 entries, each 4 bytes (e.g., IPv4 addresses)
AXL_AUTOPTR(AxlCache) cache = axl_cache_new(16, sizeof(uint32_t), 60000);
//                                           ^    ^                ^
//                                     slots  value size      TTL (ms)

// Store a value
uint32_t addr = 0xC0A80101;  // 192.168.1.1
axl_cache_put(cache, "gateway", &addr);

// Retrieve
uint32_t result;
if (axl_cache_get(cache, "gateway", &result) == 0) {
    // hit -- result contains the cached value
}

// Invalidate a specific entry
axl_cache_invalidate(cache, "gateway");

// Invalidate all entries
axl_cache_invalidate_all(cache);

API Reference

AxlHashTable

Typedefs

typedef struct AxlHashTable AxlHashTable
typedef size_t (*AxlHashFunc)(const void *key)

Hash function: compute a hash value from a key.

typedef bool (*AxlEqualFunc)(const void *a, const void *b)

Equality function: return true if two keys are equal.

typedef void (*AxlDestroyNotify)(void *data)

Destroy notification callback for keys or values.

typedef void (*AxlHashTableForeachFunc)(const void *key, void *value, void *data)

Callback for axl_hash_table_foreach (GLib: GHFunc).

typedef bool (*AxlHashTableForeachRemoveFunc)(const void *key, void *value, void *data)

Predicate for axl_hash_table_foreach_remove (GLib: GHRFunc). Return true to remove the entry.

Functions

size_t axl_str_hash(const void *key)

FNV-1a hash for NUL-terminated strings. (GLib: g_str_hash)

bool axl_str_equal(const void *a, const void *b)

String equality via strcmp. (GLib: g_str_equal)

size_t axl_direct_hash(const void *key)

Hash a pointer value directly. (GLib: g_direct_hash)

bool axl_direct_equal(const void *a, const void *b)

Pointer equality. (GLib: g_direct_equal)

AxlHashTable *axl_hash_table_new_str(void)

Create a hash table with string keys (convenience).

AXL extension — no GLib equivalent. Keys are copied internally via strdup and freed on removal. Values are not freed. Shorthand for string-keyed tables where the caller passes borrowed or literal key strings.

Returns:

new AxlHashTable, or NULL on allocation failure.

AxlHashTable *axl_hash_table_new(AxlHashFunc hash_func, AxlEqualFunc equal_func)

Create a hash table with custom hash and equality functions.

No key or value destructors — the caller manages lifetime. Matches g_hash_table_new().

Parameters:
  • hash_func – hash function

  • equal_func – equality function

Returns:

new AxlHashTable, or NULL on allocation failure.

AxlHashTable *axl_hash_table_new_full(AxlHashFunc hash_func, AxlEqualFunc equal_func, AxlDestroyNotify key_destroy, AxlDestroyNotify value_destroy)

Create a hash table with custom hash/equal and destructors.

Keys are NOT copied internally. The table takes ownership if key_destroy is non-NULL. Pass NULL for hash_func and equal_func to default to axl_str_hash / axl_str_equal.

Matches g_hash_table_new_full().

Parameters:
  • hash_func – hash function, or NULL for axl_str_hash

  • equal_func – equality function, or NULL for axl_str_equal

  • key_destroy – key destructor, or NULL

  • value_destroy – value destructor, or NULL

Returns:

new AxlHashTable, or NULL on allocation failure.

void axl_hash_table_free(AxlHashTable *h)

Free a hash table and all entries.

Calls key_destroy and value_destroy on each entry (if set). Equivalent to g_hash_table_destroy().

Parameters:
  • h – hash table (NULL-safe)

int axl_hash_table_insert(AxlHashTable *h, const void *key, void *value)

Insert a key-value pair, keeping the OLD key on collision.

If the key already exists: the new key is freed via key_destroy (if set), the old key is kept, and the old value is freed via value_destroy (if set). Matches g_hash_table_insert().

For tables created with axl_hash_table_new_str() (copy_keys mode), insert and replace behave identically.

Parameters:
  • h – hash table

  • key – key (copied for new() tables, owned for new_full())

  • value – value pointer

Returns:

0 on success, -1 on allocation failure.

int axl_hash_table_replace(AxlHashTable *h, const void *key, void *value)

Insert a key-value pair, keeping the NEW key on collision.

If the key already exists: the old key is freed via key_destroy (if set), the new key is kept, and the old value is freed via value_destroy (if set). Matches g_hash_table_replace().

For tables created with axl_hash_table_new_str() (copy_keys mode), insert and replace behave identically.

Parameters:
  • h – hash table

  • key – key (copied for new() tables, owned for new_full())

  • value – value pointer

Returns:

0 on success, -1 on allocation failure.

void *axl_hash_table_lookup(AxlHashTable *h, const void *key)

Look up a key.

Matches g_hash_table_lookup().

Parameters:
  • h – hash table

  • key – key to look up

Returns:

value pointer, or NULL if not found.

bool axl_hash_table_contains(AxlHashTable *h, const void *key)

Check if a key exists in the table.

Unlike lookup, this distinguishes between a key with a NULL value and a missing key. Matches g_hash_table_contains().

Parameters:
  • h – hash table

  • key – key to check

Returns:

true if the key exists, false otherwise.

bool axl_hash_table_remove(AxlHashTable *h, const void *key)

Remove an entry, calling key_destroy and value_destroy.

Matches g_hash_table_remove().

Parameters:
  • h – hash table

  • key – key to remove

Returns:

true if removed, false if not found.

bool axl_hash_table_steal(AxlHashTable *h, const void *key)

Remove an entry WITHOUT calling destructors.

The caller takes ownership of the value. For copy_keys tables, the internal key copy is freed (since the caller never had it). Matches g_hash_table_steal().

Parameters:
  • h – hash table

  • key – key to steal

Returns:

true if removed, false if not found.

size_t axl_hash_table_size(AxlHashTable *h)

Get the number of entries.

Matches g_hash_table_size().

Parameters:
  • h – hash table

Returns:

entry count.

void axl_hash_table_foreach(AxlHashTable *h, AxlHashTableForeachFunc func, void *data)

Iterate all entries. Order is undefined.

Matches g_hash_table_foreach().

Parameters:
  • h – hash table

  • func – callback

  • data – opaque data passed to callback

size_t axl_hash_table_foreach_remove(AxlHashTable *h, AxlHashTableForeachRemoveFunc func, void *data)

Remove entries matching a predicate.

Calls func for each entry. If it returns true, the entry is removed (key_destroy and value_destroy are called). Matches g_hash_table_foreach_remove().

Parameters:
  • h – hash table

  • func – predicate

  • data – opaque data

Returns:

number of entries removed.

void axl_hash_table_iter_init(AxlHashTableIter *iter, AxlHashTable *h)

Initialize an iterator over a hash table.

Matches g_hash_table_iter_init().

Parameters:
  • iter – iterator to initialize

  • h – hash table to iterate

bool axl_hash_table_iter_next(AxlHashTableIter *iter, void **key, void **value)

Advance to the next entry.

key and value are optional (pass NULL to ignore). Matches g_hash_table_iter_next().

Parameters:
  • iter – iterator

  • key – receives key pointer, or NULL

  • value – receives value pointer, or NULL

Returns:

true if an entry was returned, false if exhausted.

void axl_hash_table_iter_remove(AxlHashTableIter *iter)

Remove the current entry, calling destructors.

Must be called after a successful axl_hash_table_iter_next(). Matches g_hash_table_iter_remove().

Parameters:
  • iter – iterator

void axl_hash_table_iter_steal(AxlHashTableIter *iter)

Remove the current entry WITHOUT calling destructors.

Must be called after a successful axl_hash_table_iter_next(). Matches g_hash_table_iter_steal().

Parameters:
  • iter – iterator

struct AxlHashTableIter
#include <axl-hash-table.h>

AxlHashTableIter:

Stack-allocated iterator. Matches GHashTableIter. Fields prefixed with _ are private.

Public Members

AxlHashTable *table
size_t _bucket
size_t _cur_bucket
void *_current
void *_next

AxlArray

Typedefs

typedef struct AxlArray AxlArray
typedef int (*AxlCompareFunc)(const void *a, const void *b)

Comparison function for axl_array_sort. Same signature as qsort.

Return:

< 0 if a < b, 0 if equal, > 0 if a > b.

typedef int (*AxlCompareDataFunc)(const void *a, const void *b, void *user_data)

Context-aware comparison function for axl_array_sort_with_data.

Return:

< 0 if a < b, 0 if equal, > 0 if a > b.

Functions

AxlArray *axl_array_new(size_t element_size)

Create a new dynamic array for value-mode storage.

Parameters:
  • element_size – size of each element in bytes

Returns:

new AxlArray, or NULL on failure. Free with axl_array_free().

void axl_array_free(AxlArray *a)

Free a dynamic array and its internal buffer.

Parameters:
  • a – array (NULL-safe)

int axl_array_append(AxlArray *a, const void *element)

Append an element (value mode).

Parameters:
  • a – array

  • element – pointer to element data to copy (element_size bytes)

Returns:

0 on success, -1 on allocation failure.

void *axl_array_get(AxlArray *a, size_t index)

Get a pointer to the element at index (value mode).

Parameters:
  • a – array

  • index – element index

Returns:

pointer into internal buffer, or NULL if out of range.

size_t axl_array_len(AxlArray *a)

Get the number of elements in the array.

Parameters:
  • a – array

Returns:

number of elements.

void axl_array_clear(AxlArray *a)

Remove all elements. Does not free the internal buffer.

Parameters:
  • a – array

int axl_array_append_ptr(AxlArray *a, void *ptr)

Append a pointer (pointer mode).

Parameters:
  • a – array

  • ptr – pointer to store

Returns:

0 on success, -1 on allocation failure.

void *axl_array_get_ptr(AxlArray *a, size_t index)

Get stored pointer at index (pointer mode).

Parameters:
  • a – array

  • index – element index

Returns:

stored pointer, or NULL if out of range.

void axl_array_sort(AxlArray *a, AxlCompareFunc compare)

Sort array elements in place using insertion sort.

Parameters:
  • a – array

  • compare – comparison function (qsort-compatible)

int axl_array_remove_index(AxlArray *a, size_t index)

Remove the element at index, shifting remaining elements left.

Parameters:
  • a – array

  • index – element index to remove

Returns:

0 on success, -1 if index is out of range.

int axl_array_remove_index_fast(AxlArray *a, size_t index)

Remove the element at index by swapping with the last element.

O(1) but does not preserve order.

Parameters:
  • a – array

  • index – element index to remove

Returns:

0 on success, -1 if index is out of range.

int axl_array_remove_range(AxlArray *a, size_t index, size_t len)

Remove len elements starting at index, shifting remaining left.

Parameters:
  • a – array

  • index – first element to remove

  • len – number of elements to remove

Returns:

0 on success, -1 if the range is out of bounds.

int axl_array_set_size(AxlArray *a, size_t len)

Resize the array to exactly len elements.

If growing, new elements are zero-initialized. If growing beyond capacity, the internal buffer is reallocated. If shrinking, length is reduced without reallocating.

Parameters:
  • a – array

  • len – desired number of elements

Returns:

0 on success, -1 on allocation failure.

void axl_array_sort_with_data(AxlArray *a, AxlCompareDataFunc compare, void *user_data)

Sort array elements in place with a context-aware comparator.

Parameters:
  • a – array

  • compare – comparison function with user_data

  • user_data – passed to every compare call

AxlList

Typedefs

typedef void (*AxlFunc)(void *data, void *user_data)

AxlFunc:

Generic per-element callback (GFunc equivalent).

typedef void (*AxlDestroyNotify)(void *data)

AxlDestroyNotify:

Callback to free element data (GDestroyNotify equivalent).

typedef void *(*AxlCopyFunc)(const void *src, void *user_data)

AxlCopyFunc:

Deep copy function (GCopyFunc equivalent). Returns a newly allocated copy of src.

Functions

AxlList *axl_list_append(AxlList *list, void *data)

Append data to the end of the list. O(n).

Parameters:
  • list – current head (NULL for empty list)

  • data – data pointer to store

Returns:

new head of the list.

AxlList *axl_list_prepend(AxlList *list, void *data)

Prepend data to the front of the list. O(1).

Parameters:
  • list – current head (NULL for empty list)

  • data – data pointer to store

Returns:

new head of the list.

AxlList *axl_list_insert(AxlList *list, void *data, int position)

Insert data at the given position. O(n).

Negative or out-of-range position appends to the end.

Parameters:
  • list – current head

  • data – data pointer to store

  • position – 0-based insert position

Returns:

new head of the list.

AxlList *axl_list_insert_sorted(AxlList *list, void *data, AxlCompareFunc func)

Insert data in sorted order. O(n).

The list must already be sorted by the same comparator.

Parameters:
  • list – current head (sorted)

  • data – data pointer to insert

  • func – comparison function

Returns:

new head of the list.

AxlList *axl_list_remove(AxlList *list, const void *data)

Remove the first element matching data. O(n).

Compares by pointer equality. Frees the node, not the data.

Parameters:
  • list – current head

  • data – data pointer to find and remove

Returns:

new head of the list.

AxlList *axl_list_reverse(AxlList *list)

Reverse the list in place. O(n).

Parameters:
  • list – current head

Returns:

new head (was the tail).

AxlList *axl_list_concat(AxlList *list1, AxlList *list2)

Concatenate two lists. O(n) in length of list1.

list2 is appended to list1. Both must be distinct lists.

Parameters:
  • list1 – first list

  • list2 – second list (appended)

Returns:

head of the combined list.

AxlList *axl_list_sort(AxlList *list, AxlCompareFunc func)

Sort the list using merge sort. O(n log n), stable.

Parameters:
  • list – current head

  • func – comparison function

Returns:

new head of the sorted list.

AxlList *axl_list_copy(AxlList *list)

Shallow copy of the list. O(n).

Copies node structure; data pointers are shared, not duplicated.

Parameters:
  • list – list to copy

Returns:

head of the new list, or NULL on failure.

void axl_list_free(AxlList *list)

Free all nodes. Does not free element data.

Parameters:
  • list – head (NULL-safe)

void axl_list_free_full(AxlList *list, AxlDestroyNotify free_func)

Free all nodes, calling free_func on each element’s data.

Parameters:
  • list – head (NULL-safe)

  • free_func – called on each node’s data

size_t axl_list_length(AxlList *list)

Count elements. O(n).

Parameters:
  • list – head

Returns:

number of elements.

AxlList *axl_list_nth(AxlList *list, size_t n)

Get the nth node. O(n).

Parameters:
  • list – head

  • n – 0-based index

Returns:

node at position n, or NULL if out of range.

void *axl_list_nth_data(AxlList *list, size_t n)

Get data from the nth node. O(n).

Parameters:
  • list – head

  • n – 0-based index

Returns:

data pointer, or NULL if out of range.

AxlList *axl_list_first(AxlList *list)

Get the first node (rewind to head). O(n).

Useful when you have a pointer to a middle node.

Parameters:
  • list – any node in the list

Returns:

the first node, or NULL if list is empty.

AxlList *axl_list_last(AxlList *list)

Get the last node. O(n).

Parameters:
  • list – head

Returns:

the last node, or NULL if list is empty.

AxlList *axl_list_find(AxlList *list, const void *data)

Find the first node with matching data (pointer equality). O(n).

Parameters:
  • list – head

  • data – data pointer to find

Returns:

matching node, or NULL.

AxlList *axl_list_find_custom(AxlList *list, const void *data, AxlCompareFunc func)

Find using a custom comparator. O(n).

Calls func(node->data, data) for each node. Returns the first node where func returns 0.

Parameters:
  • list – head

  • data – data to compare against

  • func – comparison function

Returns:

matching node, or NULL.

void axl_list_foreach(AxlList *list, AxlFunc func, void *user_data)

Call func for each element. O(n).

Parameters:
  • list – head

  • func – callback

  • user_data – passed to callback

AxlList *axl_list_insert_before(AxlList *list, AxlList *sibling, void *data)

Insert data before the given sibling node. O(1).

If sibling is NULL, appends to the end.

Parameters:
  • list – current head

  • sibling – node to insert before (NULL = append)

  • data – data pointer to store

Returns:

new head of the list.

AxlList *axl_list_insert_after(AxlList *list, AxlList *sibling, void *data)

Insert data after the given sibling node. O(1).

If sibling is NULL, prepends to the front.

Parameters:
  • list – current head

  • sibling – node to insert after (NULL = prepend)

  • data – data pointer to store

Returns:

new head of the list.

AxlList *axl_list_remove_all(AxlList *list, const void *data)

Remove ALL nodes matching data (pointer equality). O(n).

Frees the nodes, not the data.

Parameters:
  • list – current head

  • data – data pointer to match

Returns:

new head of the list.

Unlink a specific node without freeing it. O(1).

The caller is responsible for freeing the unlinked node. The node’s prev/next pointers are set to NULL after unlinking.

Parameters:
  • list – current head

  • link – node to unlink

Returns:

new head of the list.

AxlList *axl_list_sort_with_data(AxlList *list, AxlCompareDataFunc func, void *user_data)

Sort with context-aware comparator. O(n log n), stable.

Parameters:
  • list – current head

  • func – comparison function with user_data

  • user_data – passed to every compare call

Returns:

new head of the sorted list.

AxlList *axl_list_copy_deep(AxlList *list, AxlCopyFunc func, void *user_data)

Deep copy using a copy function. O(n).

Calls func(node->data, user_data) for each node to produce the data pointer for the new list.

Parameters:
  • list – list to copy

  • func – copy function for each element

  • user_data – passed to func

Returns:

head of the new list, or NULL on failure.

struct AxlList

Public Members

void *data
struct AxlList *next
struct AxlList *prev

AxlSList

Functions

AxlSList *axl_slist_append(AxlSList *list, void *data)

Append data to the end. O(n).

Parameters:
  • list – current head (NULL for empty)

  • data – data pointer

Returns:

new head.

AxlSList *axl_slist_prepend(AxlSList *list, void *data)

Prepend data to the front. O(1).

Parameters:
  • list – current head (NULL for empty)

  • data – data pointer

Returns:

new head.

AxlSList *axl_slist_insert(AxlSList *list, void *data, int position)

Insert at position. O(n).

Parameters:
  • list – current head

  • data – data pointer

  • position – 0-based position

Returns:

new head.

AxlSList *axl_slist_insert_sorted(AxlSList *list, void *data, AxlCompareFunc func)

Insert in sorted order. O(n).

Parameters:
  • list – current head (sorted)

  • data – data to insert

  • func – comparison function

Returns:

new head.

AxlSList *axl_slist_remove(AxlSList *list, const void *data)

Remove first match by pointer equality. O(n).

Parameters:
  • list – current head

  • data – data to find and remove

Returns:

new head.

AxlSList *axl_slist_reverse(AxlSList *list)

Reverse in place. O(n).

Parameters:
  • list – current head

Returns:

new head (was tail).

AxlSList *axl_slist_concat(AxlSList *list1, AxlSList *list2)

Concatenate two lists. O(n) in list1.

Parameters:
  • list1 – first list

  • list2 – appended to list1

Returns:

head of combined list.

AxlSList *axl_slist_sort(AxlSList *list, AxlCompareFunc func)

Sort using merge sort. O(n log n), stable.

Parameters:
  • list – current head

  • func – comparison function

Returns:

new head.

AxlSList *axl_slist_copy(AxlSList *list)

Shallow copy. O(n).

Parameters:
  • list – list to copy

Returns:

new list head, or NULL on failure.

void axl_slist_free(AxlSList *list)

Free all nodes. Does not free element data.

Parameters:
  • list – head (NULL-safe)

void axl_slist_free_full(AxlSList *list, AxlDestroyNotify free_func)

Free all nodes, calling free_func on each element’s data.

Parameters:
  • list – head (NULL-safe)

  • free_func – called on each data

size_t axl_slist_length(AxlSList *list)

Count elements. O(n).

Parameters:
  • list – head

Returns:

number of elements.

AxlSList *axl_slist_nth(AxlSList *list, size_t n)

Get nth node. O(n).

Parameters:
  • list – head

  • n – 0-based index

Returns:

node, or NULL if out of range.

void *axl_slist_nth_data(AxlSList *list, size_t n)

Get data from nth node. O(n).

Parameters:
  • list – head

  • n – 0-based index

Returns:

data pointer, or NULL if out of range.

AxlSList *axl_slist_last(AxlSList *list)

Get last node. O(n).

Parameters:
  • list – head

Returns:

last node, or NULL.

AxlSList *axl_slist_find(AxlSList *list, const void *data)

Find by pointer equality. O(n).

Parameters:
  • list – head

  • data – data to find

Returns:

matching node, or NULL.

AxlSList *axl_slist_find_custom(AxlSList *list, const void *data, AxlCompareFunc func)

Find with custom comparator. O(n).

Parameters:
  • list – head

  • data – data to compare against

  • func – comparison function

Returns:

first node where func(node->data, data) == 0, or NULL.

void axl_slist_foreach(AxlSList *list, AxlFunc func, void *user_data)

Call func for each element. O(n).

Parameters:
  • list – head

  • func – callback

  • user_data – passed to callback

AxlSList *axl_slist_insert_before(AxlSList *list, AxlSList *sibling, void *data)

Insert data before the given sibling node. O(n).

If sibling is NULL, appends to the end.

Parameters:
  • list – current head

  • sibling – node to insert before (NULL = append)

  • data – data pointer to store

Returns:

new head of the list.

AxlSList *axl_slist_remove_all(AxlSList *list, const void *data)

Remove ALL nodes matching data (pointer equality). O(n).

Frees the nodes, not the data.

Parameters:
  • list – current head

  • data – data pointer to match

Returns:

new head of the list.

Unlink a specific node without freeing it. O(n).

The caller is responsible for freeing the unlinked node. The node’s next pointer is set to NULL after unlinking.

Parameters:
  • list – current head

  • link – node to unlink

Returns:

new head of the list.

AxlSList *axl_slist_sort_with_data(AxlSList *list, AxlCompareDataFunc func, void *user_data)

Sort with context-aware comparator. O(n log n), stable.

Parameters:
  • list – current head

  • func – comparison function with user_data

  • user_data – passed to every compare call

Returns:

new head of the sorted list.

AxlSList *axl_slist_copy_deep(AxlSList *list, AxlCopyFunc func, void *user_data)

Deep copy using a copy function. O(n).

Calls func(node->data, user_data) for each node to produce the data pointer for the new list.

Parameters:
  • list – list to copy

  • func – copy function for each element

  • user_data – passed to func

Returns:

head of the new list, or NULL on failure.

struct AxlSList

Public Members

void *data
struct AxlSList *next

AxlQueue

Defines

AXL_QUEUE_INIT

Static initializer for stack-allocated queues.

Functions

AxlQueue *axl_queue_new(void)

Allocate a new empty queue.

Returns:

new queue, or NULL on failure. Free with axl_queue_free().

void axl_queue_init(AxlQueue *queue)

Initialize a stack-allocated queue.

Parameters:
  • queue – queue to initialize

void axl_queue_free(AxlQueue *queue)

Free queue and all nodes. Does not free element data.

Parameters:
  • queue – queue (NULL-safe)

void axl_queue_free_full(AxlQueue *queue, AxlDestroyNotify free_func)

Free queue, calling free_func on each element’s data.

Parameters:
  • queue – queue (NULL-safe)

  • free_func – called on each data

void axl_queue_clear(AxlQueue *queue)

Remove all elements. Queue itself is not freed.

Parameters:
  • queue – queue

bool axl_queue_is_empty(AxlQueue *queue)

Check if the queue is empty.

Parameters:
  • queue – queue

Returns:

true if empty.

size_t axl_queue_get_length(AxlQueue *queue)

Get the number of elements. O(1).

Parameters:
  • queue – queue

Returns:

element count.

int axl_queue_push_head(AxlQueue *queue, void *data)

Push data to the front. O(1).

Parameters:
  • queue – queue

  • data – data pointer

Returns:

0 on success, -1 on allocation failure.

int axl_queue_push_tail(AxlQueue *queue, void *data)

Push data to the back. O(1).

Parameters:
  • queue – queue

  • data – data pointer

Returns:

0 on success, -1 on allocation failure.

void *axl_queue_pop_head(AxlQueue *queue)

Remove and return the front element. O(1).

Parameters:
  • queue – queue

Returns:

data pointer, or NULL if empty.

void *axl_queue_pop_tail(AxlQueue *queue)

Remove and return the back element. O(1).

Parameters:
  • queue – queue

Returns:

data pointer, or NULL if empty.

void *axl_queue_peek_head(AxlQueue *queue)

Peek at the front element without removing. O(1).

Parameters:
  • queue – queue

Returns:

data pointer, or NULL if empty.

void *axl_queue_peek_tail(AxlQueue *queue)

Peek at the back element without removing. O(1).

Parameters:
  • queue – queue

Returns:

data pointer, or NULL if empty.

void *axl_queue_peek_nth(AxlQueue *queue, size_t n)

Peek at the nth element. O(n).

Parameters:
  • queue – queue

  • n – 0-based index from head

Returns:

data pointer, or NULL if out of range.

void axl_queue_foreach(AxlQueue *queue, AxlFunc func, void *user_data)

Call func for each element, head to tail. O(n).

Parameters:
  • queue – queue

  • func – callback

  • user_data – passed to callback

AxlQueue *axl_queue_copy(AxlQueue *queue)

Shallow copy. O(n).

Parameters:
  • queue – queue to copy

Returns:

new queue, or NULL on failure.

void axl_queue_reverse(AxlQueue *queue)

Reverse the queue in place. O(n).

Parameters:
  • queue – queue

void axl_queue_sort(AxlQueue *queue, AxlCompareFunc func)

Sort the queue using merge sort. O(n log n).

Parameters:
  • queue – queue

  • func – comparison function

AxlList *axl_queue_find(AxlQueue *queue, const void *data)

Find the first node matching data (pointer equality). O(n).

Parameters:
  • queue – queue

  • data – data pointer to find

Returns:

matching AxlList node, or NULL.

AxlList *axl_queue_find_custom(AxlQueue *queue, const void *data, AxlCompareFunc func)

Find using a custom comparator. O(n).

Returns the first node where func(node->data, data) == 0.

Parameters:
  • queue – queue

  • data – data to compare against

  • func – comparison function

Returns:

matching AxlList node, or NULL.

bool axl_queue_remove(AxlQueue *queue, const void *data)

Remove the first node matching data (pointer equality). O(n).

Frees the node, not the data. Updates head/tail/length.

Parameters:
  • queue – queue

  • data – data pointer to find and remove

Returns:

true if a match was found and removed.

size_t axl_queue_remove_all(AxlQueue *queue, const void *data)

Remove ALL nodes matching data (pointer equality). O(n).

Frees the nodes, not the data. Updates head/tail/length.

Parameters:
  • queue – queue

  • data – data pointer to match

Returns:

number of nodes removed.

struct AxlQueue

Public Members

AxlList *head
AxlList *tail
size_t length

AxlRadixTree

Typedefs

typedef struct AxlRadixTree AxlRadixTree

Functions

AxlRadixTree *axl_radix_tree_new(void)

Create a new radix tree.

Values are not freed on removal or tree destruction.

Returns:

new AxlRadixTree, or NULL on allocation failure.

AxlRadixTree *axl_radix_tree_new_full(AxlDestroyNotify value_free)

Create a new radix tree with a value destructor.

Parameters:
  • value_free – value destructor, or NULL

Returns:

new AxlRadixTree, or NULL on allocation failure.

void axl_radix_tree_free(AxlRadixTree *tree)

Free a radix tree and all entries.

Calls value_free on each entry’s value (if set).

Parameters:
  • tree – radix tree (NULL-safe)

int axl_radix_tree_insert(AxlRadixTree *tree, const char *key, void *value)

Insert or replace a key-value pair.

If the key already exists, the old value is freed via value_free (if set) and replaced with the new value.

Parameters:
  • tree – radix tree

  • key – string key (copied internally)

  • value – value pointer

Returns:

0 on success, -1 on allocation failure.

void *axl_radix_tree_lookup(AxlRadixTree *tree, const char *key)

Exact lookup of a key.

Parameters:
  • tree – radix tree

  • key – key to look up

Returns:

value pointer, or NULL if not found.

void *axl_radix_tree_lookup_prefix(AxlRadixTree *tree, const char *key, const char **suffix)

Longest-prefix lookup.

Finds the longest inserted key that is a prefix of key and returns its value. Sets *suffix to point into key at the first character after the matched prefix. The caller can compute the prefix length as *suffix - key.

On no match, *suffix is not modified. Pass NULL for suffix if the suffix pointer is not needed.

Parameters:
  • tree – radix tree

  • key – key to match against

  • suffix – receives pointer into key after matched prefix

Returns:

value pointer, or NULL if no prefix matches.

bool axl_radix_tree_remove(AxlRadixTree *tree, const char *key)

Remove a key.

Calls value_free on the value (if set). Collapses intermediate nodes with a single child.

Parameters:
  • tree – radix tree

  • key – key to remove

Returns:

true if removed, false if not found.

size_t axl_radix_tree_size(AxlRadixTree *tree)

Get the number of entries.

Parameters:
  • tree – radix tree

Returns:

entry count.

void axl_radix_tree_foreach(AxlRadixTree *tree, AxlHashTableForeachFunc func, void *data)

Iterate all entries in depth-first order.

The key passed to func is a reconstructed NUL-terminated string valid only for the duration of the callback.

Parameters:
  • tree – radix tree

  • func – callback(key, value, data)

  • data – opaque data passed to callback

AxlRingBuf

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_free function 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 size is 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_size bytes 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_len is 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

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