|
|
|
|
|
|
|
JSMN
|
|
|
|
====
|
|
|
|
|
|
|
|
jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be
|
|
|
|
easily integrated into resource-limited or embedded projects.
|
|
|
|
|
|
|
|
You can find more information on JSON at (http://www.json.org/)
|
|
|
|
|
|
|
|
Philosophy
|
|
|
|
----------
|
|
|
|
|
|
|
|
Most JSON parsers offer you a bunch of functions to load JSON data, parse it
|
|
|
|
and extract any value by its name. jsmn proves that checking the correctness of
|
|
|
|
every JSON packet or allocating temporary objects to store parsed JSON fields
|
|
|
|
is an overkill.
|
|
|
|
|
|
|
|
JSON format itself is extremely simple, so why should we complicate it?
|
|
|
|
|
|
|
|
jsmn is designed to be **robust** (it should work fine even with erroneous
|
|
|
|
data), **fast** (it should parse data on the fly), **portable** (no unneeded
|
|
|
|
dependencies or non-standard C extensions). An of course, **simplicity** is a
|
|
|
|
key feature - simple code style, simple algorithm, simple integration.
|
|
|
|
|
|
|
|
Features
|
|
|
|
--------
|
|
|
|
|
|
|
|
* compatible with C89
|
|
|
|
* no dependencies (even libc!)
|
|
|
|
* about 200 lines of code
|
|
|
|
* extremely small code footprint
|
|
|
|
* no dynamic memory allocation
|
|
|
|
* incremental single-pass parsing
|
|
|
|
* library code is covered with unit-tests
|
|
|
|
|
|
|
|
Design
|
|
|
|
------
|
|
|
|
|
|
|
|
The rudimentary jsmn object is a **token**.
|
|
|
|
|
|
|
|
When parsing is done, token objects contain start and end positions of JSON
|
|
|
|
token inside the JSON data block. You can just copy a corresponding range of
|
|
|
|
bytes and get token value.
|
|
|
|
|
|
|
|
Another propetry of token is token type. It describes the type of the
|
|
|
|
corresponding JSON object.
|
|
|
|
|
|
|
|
jsmn supports the following token types:
|
|
|
|
|
|
|
|
* Object - a container of key-value pairs, e.g.:
|
|
|
|
`{ "foo":"bar", "x":0.3 }`
|
|
|
|
* Array - a sequence of values, e.g.:
|
|
|
|
`[ 1, 2, 3 ]`
|
|
|
|
* String - a quoted sequence of chars, e.g.: `"foo"`
|
|
|
|
* Primitive - a number, a boolean (`true`, `false`) or `null`
|
|
|
|
|
|
|
|
jsmn doesn't handle specific JSON data types. It just points to the token
|
|
|
|
boundaries - you should parse single data fields by your own if you need this.
|
|
|
|
|
|
|
|
Get sources
|
|
|
|
-----------
|
|
|
|
|
|
|
|
Clone the repository (you should have mercurial installed):
|
|
|
|
|
|
|
|
$ hg clone http://bitbucket.org/zserge/jsmn jsmn
|
|
|
|
|
|
|
|
Repository layout it simple: jsmn.c and jsmn.h are library files; demo.c is an
|
|
|
|
example of how to use jsmn (it is also used in unit testing); test.sh is a test
|
|
|
|
script. You will also find README, LICENSE and Makefile files inside.
|
|
|
|
|
|
|
|
API
|
|
|
|
---
|
|
|
|
|
|
|
|
Token types are described by `jsontype_t`:
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
JSON_OBJECT,
|
|
|
|
JSON_ARRAY,
|
|
|
|
JSON_STRING,
|
|
|
|
JSON_PRIMITIVE
|
|
|
|
} jsontype_t;
|
|
|
|
|
|
|
|
**Note:** primitive tokens are not divided into numbers, booleans and null,
|
|
|
|
because one can easily tell the type using the first character:
|
|
|
|
|
|
|
|
* <code>'t', 'f'</code> - boolean
|
|
|
|
* <code>'n'</code> - null
|
|
|
|
* <code>'-', '0'..'9'</code> - number
|
|
|
|
|
|
|
|
Tokens are described with `jsontok_t`:
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
jsontype_t type;
|
|
|
|
int start;
|
|
|
|
int end;
|
|
|
|
} jsontok_t;
|
|
|
|
|
|
|
|
**Note:** string tokens point to the first character after
|
|
|
|
the opening quote and the previous symbol before final quote. This was made
|
|
|
|
to simplify string extraction from JSON data.
|
|
|
|
|
|
|
|
All job is done by `jsmn_parser` object. You can initialize a new parser using:
|
|
|
|
|
|
|
|
struct jsmn_parser parser;
|
|
|
|
jsmntok_t tokens[10];
|
|
|
|
|
|
|
|
jsmn_init_parser(&parser, js, &tokens, 10);
|
|
|
|
|
|
|
|
This will create a parser, that can parse up to 10 JSON tokens from `js` string.
|
|
|
|
|
|
|
|
Later, you can use `jsmn_parse(&parser)` function to process JSON string with the parser.
|
|
|
|
It something goes wrong, you will return an error. Error will be one of these:
|
|
|
|
|
|
|
|
* `JSON_SUCCESS` - everything went fine. String was parsed
|
|
|
|
* `JSON_ERROR_INVAL` - bad token, JSON string is corrupted
|
|
|
|
* `JSON_ERROR_NOMEM` - not enough tokens, JSON string is too large
|
|
|
|
* `JSON_ERROR_PART` - JSON string is too short, it doesn't contain the whole JSON data
|
|
|
|
|
|
|
|
If you get `JSON_ERROR_NOMEM`, you can allocate more tokens and call `jsmn_parse` once more.
|
|
|
|
If you read json data from the stream, you can call jsmn_parse and check if
|
|
|
|
return value is `JSON_ERROR_PART` to see if you have reached the end of JSON
|
|
|
|
data.
|
|
|
|
|
|
|
|
Other info
|
|
|
|
----------
|
|
|
|
|
|
|
|
This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
|
|
|
|
so feel free to integrate it in your commercial products.
|
|
|
|
|