OK_JSON is a compact JSON tokenizer/parser library in C99 that parses an input JSON string into a fixed array of tokens stored inside OkJsonParser. It is designed for environments where predictability and low complexity are more important than complete JSON feature coverage.
Core files:
- Public API and types:
include/ok_json.h - Implementation:
src/ok_json.c - Tests:
test/ok_json_tests.c - Fuzzer:
test/fuzz_target.c - Compliance harness:
test/compliance_harness.c - Build/test automation:
Makefile,.github/workflows/ci.yml
- Parse JSON containing object, array, string, number, boolean, and null token types.
- Store parser output in fixed-size token memory (
OKJ_MAX_TOKENS) with no heap allocation. - Retrieve values by key from parsed objects via typed getters:
okj_get_stringokj_get_numberokj_get_booleanokj_get_array/okj_get_array_rawokj_get_object/okj_get_object_rawokj_get_token
- Copy parsed string values into null-terminated buffers via
okj_copy_string. - Count objects, arrays, and total tokens with helper functions.
OK_JSON is token-centric, not tree-centric:
okj_init()binds parser state to a mutable JSON buffer.okj_parse()walks the input and appends tokens intoparser->tokens.- Getter functions scan token stream for key/value pairs and expose slices (
start,length) into the original JSON string.
Because tokens point into input memory, the input buffer must remain valid for as long as retrieved values are used.
The parser intentionally relies on fixed limits for deterministic memory usage:
OKJ_MAX_TOKENS(128) — maximum number of tokensOKJ_MAX_DEPTH(16) — maximum container nesting depthOKJ_MAX_STRING_LEN(64) — maximum key/string byte lengthOKJ_MAX_ARRAY_SIZE(64) — maximum array elements (non-raw getter)OKJ_MAX_OBJECT_SIZE(32) — maximum object members (non-raw getter)OKJ_MAX_JSON_LEN(4096) — maximum input length in bytes
These controls are documented in the header and enforced by parsing/getter behavior.
A common flow is:
- parse a small telemetry or config object,
- extract a few known keys,
- avoid dynamic allocation and external library dependencies.
Example (simplified):
OkJsonParser parser;
char json[] = "{\"temp\":42,\"ok\":true}";
okj_init(&parser, json, (uint16_t)(sizeof(json) - 1U));
if (okj_parse(&parser) == OKJ_SUCCESS) {
OkJsonNumber temp;
OkJsonBoolean ok;
if (okj_get_number (&parser, "temp", 4U, &temp) == OKJ_SUCCESS) {
/* Use temp.start / temp.length */
}
if (okj_get_boolean(&parser, "ok", 2U, &ok) == OKJ_SUCCESS) {
/* Use ok.start / ok.length */
}
}