json.h

Minimal JSON parser for lwIP-CE.

Because each cursor is always scoped to a single nesting level, there is no depth stack and no skip primitive — to skip a nested value, simply don’t call json_enter() on it.

Author

Anthony Cagliano

Author

Claude Code

Known constraints:

  • Input must be a single contiguous buffer (no streaming).

  • Unicode escape sequences (\uXXXX) are passed through uninterpreted.

Note

Cursor-based parser modelled after tls_asn1_cursor: no heap allocation, no DOM tree. json_next() advances the cursor and returns one token; for objects and arrays the token carries the full content span and the parent cursor has already advanced past the closer. Descend into a nested value by calling json_enter(), which scopes a child cursor to that span.

Defines

json_token_copy(dst, dst_len, tok)
json_token_equals(tok, expected)

Enums

enum json_err_t

Values:

enumerator JSON_OK
enumerator JSON_ERR_INVALID
enumerator JSON_ERR_TRUNCATED
enumerator JSON_ERR_DONE
enum json_token_type_t

Values:

enumerator JSON_TOK_NONE
enumerator JSON_TOK_OBJECT
enumerator JSON_TOK_ARRAY
enumerator JSON_TOK_KEY
enumerator JSON_TOK_STRING
enumerator JSON_TOK_NUMBER
enumerator JSON_TOK_BOOL
enumerator JSON_TOK_NULL

Functions

void json_init(json_parser_t *p, const char *buf, size_t len)

Initialize a cursor over a complete JSON buffer.

The buffer must remain valid for the lifetime of the cursor.

void json_enter(json_parser_t *child, const json_token_t *tok)

Scope a child cursor into the interior of an OBJECT or ARRAY token.

After json_next() returns a token with type JSON_TOK_OBJECT or JSON_TOK_ARRAY, call this to get a cursor bounded to that value’s contents. The parent cursor is already positioned past the closing brace/bracket.

json_token_t tok; json_next(&parent, &tok); // tok.type == JSON_TOK_OBJECT json_parser_t child; json_enter(&child, &tok); // child spans the object interior json_get_string(&child, “key”, …); // search within child only

json_err_t json_next(json_parser_t *p, json_token_t *tok)

Advance to the next token in the current cursor scope.

Inside an object cursor: alternates JSON_TOK_KEY / value tokens. Inside an array cursor: returns value tokens (STRING/NUMBER/BOOL/NULL/OBJECT/ARRAY). At top level: returns the single root value.

Returns JSON_OK and fills *tok on success. Returns JSON_ERR_DONE when the cursor scope is exhausted.

bool json_slice_copy(char *dst, size_t dst_len, const json_slice_t *s)

Copy a json_slice_t into a NUL-terminated buffer.

Returns false if dst is too small (dst_len includes the NUL byte).

json_err_t json_get_key_value(json_parser_t *p, const char *key_name, json_token_t *key, json_token_t *value)

Retrieve a key-value pair from the current object cursor.

If key_name is non-NULL: scan forward for that key, fill *key and *value. Returns JSON_ERR_DONE if the key is not found before the object ends.

If key_name is NULL: fill *key and *value with the next pair. Returns JSON_ERR_DONE when the object is exhausted. Use this form to iterate all pairs in an object.

The cursor must be positioned inside an object (created via json_enter on a JSON_TOK_OBJECT token, or initialized directly over object interior bytes).

*key type == JSON_TOK_KEY, value.str/len is the key name slice. *value type is any value token; if OBJECT or ARRAY, call json_enter to descend.

json_err_t json_get_string(json_parser_t *p, const char *key, char *dst, size_t dst_len)

Convenience: scan for key in the current object cursor and copy its string value into dst (NUL-terminated).

Returns JSON_ERR_INVALID if the value is not a string or dst is too small.

json_err_t json_get_number(json_parser_t *p, const char *key, long *out)

Convenience: scan for key in the current object cursor and parse its numeric value into *out as a signed long.

Returns JSON_ERR_INVALID if the value is not a number token.

struct json_slice_t
#include <json.h>

Public Members

const char *str
size_t len
struct json_token_t
#include <json.h>

Public Members

json_token_type_t type
json_slice_t value
bool bool_value
struct json_parser_t
#include <json.h>

Public Members

const char *buf
size_t len
size_t pos
bool in_object
bool expect_value