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);
}
}
API Reference
Functions
-
bool axl_json_parse(const char *json, size_t len, AxlJsonCtx *ctx)
Parse a JSON string.
Allocates a token array sized to fit the document. Call axl_json_free() when done to release the token memory.
- Parameters:
json – JSON string (not NUL-terminated required)
len – length of @json in bytes
ctx – context to fill
- Returns:
true on success, false on parse error or allocation failure.
-
void axl_json_free(AxlJsonCtx *ctx)
Free a parsed JSON context.
Releases the heap-allocated token array. Safe to call on contexts that don’t own their tokens (e.g. array elements). NULL-safe.
- Parameters:
ctx – context to free (NULL-safe)
-
bool axl_json_get_string(const AxlJsonCtx *ctx, const char *key, char *value, size_t value_size)
Extract a string value from a parsed JSON object.
- Parameters:
ctx – parsed context
key – key to look up
value – buffer for string value
value_size – size of @value buffer
- Returns:
true if found, false if not found or not a string.
-
bool axl_json_get_int(const AxlJsonCtx *ctx, const char *key, int64_t *value)
Extract an integer value from a parsed JSON object.
- Parameters:
ctx – parsed context
key – key to look up
value – receives the integer
- Returns:
true if found, false if not found or not a number.
-
bool axl_json_get_uint(const AxlJsonCtx *ctx, const char *key, uint64_t *value)
Extract an unsigned integer value from a parsed JSON object.
- Parameters:
ctx – parsed context
key – key to look up
value – receives the unsigned integer
- Returns:
true if found, false if not found or not a number.
-
bool axl_json_get_bool(const AxlJsonCtx *ctx, const char *key, bool *value)
Extract a boolean value from a parsed JSON object.
- Parameters:
ctx – parsed context
key – key to look up
value – receives the boolean
- Returns:
true if found, false if not found or not a boolean.
-
bool axl_json_extract_string(const char *json, size_t len, const char *key, char *value, size_t value_size)
One-shot: parse + extract a string in one call.
Handles allocation and cleanup internally.
- Parameters:
json – JSON string
len – length
key – key to extract
value – buffer for value
value_size – buffer size
- Returns:
true on success.
-
bool axl_json_array_begin(const AxlJsonCtx *ctx, const char *key, AxlJsonArrayIter *iter)
Begin iterating a JSON array value by key name.
- Parameters:
ctx – parsed context
key – key of the array field
iter – iterator to initialize
- Returns:
true if array found, false if not found or not an array.
-
bool axl_json_root_array_begin(const AxlJsonCtx *ctx, AxlJsonArrayIter *iter)
Begin iterating a root-level JSON array.
Use when the JSON document is a bare array:
[{...}, {...}, ...]rather than an object with a named array field.- Parameters:
ctx – parsed context
iter – iterator to initialize
- Returns:
true if root is an array, false otherwise.
-
bool axl_json_array_next(AxlJsonArrayIter *iter, AxlJsonCtx *element)
Advance to the next array element.
The element context borrows the parent’s token array — do not call axl_json_free on it. It remains valid until the parent context is freed.
- Parameters:
iter – iterator
element – context for the element
- Returns:
true if element returned, false if no more elements.
-
int axl_json_escape_string(const char *src, char *out, size_t size)
Escape a string for safe embedding in JSON.
Writes the escaped string WITH surrounding double quotes into
out. Escapes:"</tt> <tt>\\\\</tt> <tt>\\n</tt> <tt>\\r</tt> <tt>\\t</tt> and control characters (< 0x20).
Example: axl_json_escape_string("hello "world"", out, 32)
produces: "hello "world""
Useful for building JSON with axl_snprintf:
@code
char esc[64];
axl_json_escape_string(name, esc, sizeof(esc));
axl_snprintf(buf, size, "{"name":s,"size":llu}", esc, sz);
- Parameters:
src – input string (UTF-8)
out – output buffer
size – output buffer size
-
void axl_json_init(AxlJsonBuilder *j, char *buffer, size_t size)
Initialize a JSON builder with a caller-provided buffer.
- Parameters:
j – builder to initialize
buffer – caller-provided buffer
size – buffer size
-
void axl_json_object_start(AxlJsonBuilder *j)
Open a top-level JSON object (
{).- Parameters:
j – builder
-
void axl_json_object_end(AxlJsonBuilder *j)
Close the current JSON object (
}).- Parameters:
j – builder
-
void axl_json_object_start_named(AxlJsonBuilder *j, const char *key)
Open a named nested object (
"key": {).- Parameters:
j – builder
key – object key name
-
void axl_json_array_start(AxlJsonBuilder *j, const char *key)
Open a named JSON array (
"key": [).- Parameters:
j – builder
key – array key name
-
void axl_json_array_end(AxlJsonBuilder *j)
Close the current JSON array (
]).- Parameters:
j – builder
-
void axl_json_array_object_start(AxlJsonBuilder *j)
Open an object inside the current array.
- Parameters:
j – builder
-
void axl_json_array_add_string(AxlJsonBuilder *j, const char *value)
Append a string value to the current array.
- Parameters:
j – builder
value – string to add
-
void axl_json_add_string(AxlJsonBuilder *j, const char *key, const char *value)
Add a string key-value pair (
"key": "value").- Parameters:
j – builder
key – key
value – string value
-
void axl_json_add_uint(AxlJsonBuilder *j, const char *key, uint64_t value)
Add an unsigned integer key-value pair (
"key": 123).- Parameters:
j – builder
key – key
value – unsigned integer value
-
void axl_json_add_int(AxlJsonBuilder *j, const char *key, int64_t value)
Add a signed integer key-value pair (
"key": -42).- Parameters:
j – builder
key – key
value – integer value
-
void axl_json_add_bool(AxlJsonBuilder *j, const char *key, bool value)
Add a boolean key-value pair (
"key": true).- Parameters:
j – builder
key – key
value – boolean value
-
void axl_json_add_hex(AxlJsonBuilder *j, const char *key, uint64_t value)
Add a hex-formatted string key-value pair (
"key": "0x1A2B").- Parameters:
j – builder
key – key
value – value (written as hex string)
-
void axl_json_add_null(AxlJsonBuilder *j, const char *key)
Add a null key-value pair (
"key": null).- Parameters:
j – builder
key – key
-
size_t axl_json_finish(AxlJsonBuilder *j)
Finalize the builder and NUL-terminate the output.
- Parameters:
j – builder
- Returns:
number of characters written (excluding NUL). Check
j->overflowto detect truncation.
-
void axl_json_pretty_print(const char *json, size_t len)
Pretty-print JSON to the console with colors and indentation.
Colors: cyan keys, green strings, yellow numbers, magenta booleans.
- Parameters:
json – JSON string (ASCII)
len – length in bytes
-
void axl_json_print_raw(const char *json, size_t len)
Print JSON to the console without formatting.
- Parameters:
json – JSON string (ASCII)
len – length in bytes
-
struct AxlJsonCtx
- #include <axl-json.h>
Parsed JSON context. The token array is heap-allocated by axl_json_parse and freed by axl_json_free. References the original JSON buffer (do not free it while using the context).
-
struct AxlJsonArrayIter
- #include <axl-json.h>
Iterator for JSON arrays.
-
struct AxlJsonBuilder
- #include <axl-json.h>
JSON builder with fixed caller-provided buffer. No dynamic allocation. Check overflow after building to detect truncation.