And some other funky character conversion stuff, like Base-64 and Latin-1 to/from UTF-8
Resource optimized for small 8-bit and 32-bit microcontrollers
Authors:
- D. Taylor 2018 (gmail: senseitg)
License:
- Ask and thou shalt receive
Features:
- Parses and validates JSON very fast
- Fully compliant and well tested against https://github.com/nst/JSONTestSuite
- No dynamic memory allocation
- Delivers tokens via callback
- Handles JSON in RAM as well as streaming JSON
- Designed for UTF-8
Options (*.h):
- Configurable max nesting depth
- Configurable standards-breaking optimizations
- Configurable data sizes for number representation
Resource requirements:
- Minimal memory requirements (not even 32 bytes of RAM)
- Minimal stack use (non-recursive, few local variables)
- Minimal program space (lean, compact code)
- No heap use
Notes:
- Designed for high speed, low footprint - not a rich feature set.
Caveats:
- No UTF-8 error checking - strings delivered as is
- No UTF-16
- Requires C99 to compile (-std=c99 for GCC)
Performance:
- Pretty darn good. You do the comparisons!
WhatDoesItDo™:
It takes JSON data in RAM:
char json[] = "{\"JSON\":\"We haz it\"}";
result = json_parse(json, strlen(json), print_json, NULL);Or it takes a stream of JSON data:
char jsbuf[32]; // String extraction buffer
json_parser_ctx ctx = json_stream(jsbuf, sizeof(jsbuf), print_json, NULL);
while(!your_stream_eof()) {
result = json_octet(&ctx, your_stream_read());
if(result) break;
}And delivers the contents to a custom callback function (example):
uint8_t print_json(uint32_t depth, uint8_t type, void * value, void * user) {
uint8_t n;
for(n = 0; n < depth; n++) printf(" ");
switch(type) {
case JSON_OBJECT: printf("{"); break;
case JSON_OBJECT_END: printf("}"); break;
case JSON_ARRAY: printf("["); break;
case JSON_ARRAY_END: printf("]"); break;
case JSON_KEY: printf("\"%s\" : ", json_to_string(value));
case JSON_STRING: printf("\"%s\"", json_to_string(value)); break;
case JSON_NUMBER: printf("%0.10g", json_to_double(value)); break;
default: printf("%s", json_const_str(type));
}
printf("\n");
return JSON_OK;
}Thus, converting this JSON string:
[null, -1.23000456789e+2, false, "Sing ♪ a \u266B song", {"var" : [0.0, 1.500, 2, {}]}]Into this result (printed by the callback example as shown above):
[
null
-123.0004567
false
"Sing ♪ a ♫ song"
{
"var" : [
0
1.5
2
{
}
]
}
]
Of course, the callback function can be anything you desire.
I mostly use it to parse configuration files by implementing a small state machine that extracts all fields of interest.