3 ms·
If you want to go extremely lightweight, there’s jsmn: https://github.com/zserge/jsmn https://github.com/zserge/jsmn It does no dynamic memory allocation, whic
by msarnoff 2y ago
If you want to go extremely lightweight, there’s jsmn: https://github.com/zserge/jsmn https://github.com/zserge/jsmn
It does no dynamic memory allocation, which is a plus in constrained IoT/embedded applications. But it’s really only a tokenizer. For example, if you want to parse fields out of a map, you have to write your own wrappers to iterate over key/value pairs. Since no data is copied out of the original buffer, all the “tokens” are given as byte offsets and lengths, not null-terminated strings, so you can’t just do printf(“%s”).
If you can’t (or don’t want to) malloc, it gets the job done. Not sure I’d recommend it for other applications though.
- jdougan 2y agoIs there a reason you can't do printf("%.*s", strlen, strptr); ?
- jeffreygoesto 2y agoThe terminating character is still the closing double quote and not a null, since the library does neither copy out nor alter the input. For example tiny_json replaces the closing quotes to create C strings, but that needs the full file to be in a mutable buffer which can be prohibitive for small controllers reading some config from flash only.
- jdougan 2y agoWith the "%.*s" format you need no null at the end. It just counts out the characters: #include <stdio.h> void main() { char buff[10] = {'R', 'o', 'b', 'o', 't', 't', 'y', 'p', 'e', 's'}; printf("=>%.*s<=", 4, ((char *)&buff + 3)); } prints =>otty<=
- jeffreygoesto 2y agoAh. Ok. Scanning the length before printing is mandatory then.
- msarnoff 2y agoYes, that’s exactly what I’ve done.
- jdougan 2y agoAny other issues with it? Sibling comments mentioned potential unicode issues.
- msarnoff 2y agoI've only used it in an application where we ensure the data is ASCII-only. The only issue is that I've had to write a bunch of wrapper code around it (for looking up object properties by key, iterating over key/value pairs or array elements, etc.)
- deathanatos 2y agoA non-allocating library would be forced to return to you the unparsed string literal, since returning a parsed string can require an allocation. It might tell you that the literal is valid. E.g., take the JSON: "\"\uD83D\uDCA9\"" There's no (pointer, length) into that that you can then printf(…, ptr, len); you'd get the escapes, raw. Ofc., there might be situations like debugging where that's fine.
- rurban 2y agoI settled on this one too. Far better than nicklohmann's monster build times.
- conradev 2y agoI actually evaluated and used jsmn and almost mentioned it in my comment. It was really quite cool, but I believe I couldn’t use it due to the lack of UTF-8 validation. Because UTF-8 validation is in the state machine for libjson, I can actually ignore incomplete UTF-8 escape sequences in incomplete JSON strings when streaming.