Fork of my original MQTTGateway

Dependencies:   mbed-http

Committer:
vpcola
Date:
Sat Apr 08 14:43:14 2017 +0000
Revision:
0:a1734fe1ec4b
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vpcola 0:a1734fe1ec4b 1
vpcola 0:a1734fe1ec4b 2 JSMN
vpcola 0:a1734fe1ec4b 3 ====
vpcola 0:a1734fe1ec4b 4
vpcola 0:a1734fe1ec4b 5 jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be
vpcola 0:a1734fe1ec4b 6 easily integrated into resource-limited or embedded projects.
vpcola 0:a1734fe1ec4b 7
vpcola 0:a1734fe1ec4b 8 You can find more information about JSON format at [json.org][1]
vpcola 0:a1734fe1ec4b 9
vpcola 0:a1734fe1ec4b 10 Library sources are available at https://github.com/zserge/jsmn
vpcola 0:a1734fe1ec4b 11
vpcola 0:a1734fe1ec4b 12 The web page with some information about jsmn can be found at
vpcola 0:a1734fe1ec4b 13 [http://zserge.com/jsmn.html][2]
vpcola 0:a1734fe1ec4b 14
vpcola 0:a1734fe1ec4b 15 Philosophy
vpcola 0:a1734fe1ec4b 16 ----------
vpcola 0:a1734fe1ec4b 17
vpcola 0:a1734fe1ec4b 18 Most JSON parsers offer you a bunch of functions to load JSON data, parse it
vpcola 0:a1734fe1ec4b 19 and extract any value by its name. jsmn proves that checking the correctness of
vpcola 0:a1734fe1ec4b 20 every JSON packet or allocating temporary objects to store parsed JSON fields
vpcola 0:a1734fe1ec4b 21 often is an overkill.
vpcola 0:a1734fe1ec4b 22
vpcola 0:a1734fe1ec4b 23 JSON format itself is extremely simple, so why should we complicate it?
vpcola 0:a1734fe1ec4b 24
vpcola 0:a1734fe1ec4b 25 jsmn is designed to be **robust** (it should work fine even with erroneous
vpcola 0:a1734fe1ec4b 26 data), **fast** (it should parse data on the fly), **portable** (no superfluous
vpcola 0:a1734fe1ec4b 27 dependencies or non-standard C extensions). And of course, **simplicity** is a
vpcola 0:a1734fe1ec4b 28 key feature - simple code style, simple algorithm, simple integration into
vpcola 0:a1734fe1ec4b 29 other projects.
vpcola 0:a1734fe1ec4b 30
vpcola 0:a1734fe1ec4b 31 Features
vpcola 0:a1734fe1ec4b 32 --------
vpcola 0:a1734fe1ec4b 33
vpcola 0:a1734fe1ec4b 34 * compatible with C89
vpcola 0:a1734fe1ec4b 35 * no dependencies (even libc!)
vpcola 0:a1734fe1ec4b 36 * highly portable (tested on x86/amd64, ARM, AVR)
vpcola 0:a1734fe1ec4b 37 * about 200 lines of code
vpcola 0:a1734fe1ec4b 38 * extremely small code footprint
vpcola 0:a1734fe1ec4b 39 * API contains only 2 functions
vpcola 0:a1734fe1ec4b 40 * no dynamic memory allocation
vpcola 0:a1734fe1ec4b 41 * incremental single-pass parsing
vpcola 0:a1734fe1ec4b 42 * library code is covered with unit-tests
vpcola 0:a1734fe1ec4b 43
vpcola 0:a1734fe1ec4b 44 Design
vpcola 0:a1734fe1ec4b 45 ------
vpcola 0:a1734fe1ec4b 46
vpcola 0:a1734fe1ec4b 47 The rudimentary jsmn object is a **token**. Let's consider a JSON string:
vpcola 0:a1734fe1ec4b 48
vpcola 0:a1734fe1ec4b 49 '{ "name" : "Jack", "age" : 27 }'
vpcola 0:a1734fe1ec4b 50
vpcola 0:a1734fe1ec4b 51 It holds the following tokens:
vpcola 0:a1734fe1ec4b 52
vpcola 0:a1734fe1ec4b 53 * Object: `{ "name" : "Jack", "age" : 27}` (the whole object)
vpcola 0:a1734fe1ec4b 54 * Strings: `"name"`, `"Jack"`, `"age"` (keys and some values)
vpcola 0:a1734fe1ec4b 55 * Number: `27`
vpcola 0:a1734fe1ec4b 56
vpcola 0:a1734fe1ec4b 57 In jsmn, tokens do not hold any data, but point to token boundaries in JSON
vpcola 0:a1734fe1ec4b 58 string instead. In the example above jsmn will create tokens like: Object
vpcola 0:a1734fe1ec4b 59 [0..31], String [3..7], String [12..16], String [20..23], Number [27..29].
vpcola 0:a1734fe1ec4b 60
vpcola 0:a1734fe1ec4b 61 Every jsmn token has a type, which indicates the type of corresponding JSON
vpcola 0:a1734fe1ec4b 62 token. jsmn supports the following token types:
vpcola 0:a1734fe1ec4b 63
vpcola 0:a1734fe1ec4b 64 * Object - a container of key-value pairs, e.g.:
vpcola 0:a1734fe1ec4b 65 `{ "foo":"bar", "x":0.3 }`
vpcola 0:a1734fe1ec4b 66 * Array - a sequence of values, e.g.:
vpcola 0:a1734fe1ec4b 67 `[ 1, 2, 3 ]`
vpcola 0:a1734fe1ec4b 68 * String - a quoted sequence of chars, e.g.: `"foo"`
vpcola 0:a1734fe1ec4b 69 * Primitive - a number, a boolean (`true`, `false`) or `null`
vpcola 0:a1734fe1ec4b 70
vpcola 0:a1734fe1ec4b 71 Besides start/end positions, jsmn tokens for complex types (like arrays
vpcola 0:a1734fe1ec4b 72 or objects) also contain a number of child items, so you can easily follow
vpcola 0:a1734fe1ec4b 73 object hierarchy.
vpcola 0:a1734fe1ec4b 74
vpcola 0:a1734fe1ec4b 75 This approach provides enough information for parsing any JSON data and makes
vpcola 0:a1734fe1ec4b 76 it possible to use zero-copy techniques.
vpcola 0:a1734fe1ec4b 77
vpcola 0:a1734fe1ec4b 78 Install
vpcola 0:a1734fe1ec4b 79 -------
vpcola 0:a1734fe1ec4b 80
vpcola 0:a1734fe1ec4b 81 To clone the repository you should have Git installed. Just run:
vpcola 0:a1734fe1ec4b 82
vpcola 0:a1734fe1ec4b 83 $ git clone https://github.com/zserge/jsmn
vpcola 0:a1734fe1ec4b 84
vpcola 0:a1734fe1ec4b 85 Repository layout is simple: jsmn.c and jsmn.h are library files, tests are in
vpcola 0:a1734fe1ec4b 86 the jsmn\_test.c, you will also find README, LICENSE and Makefile files inside.
vpcola 0:a1734fe1ec4b 87
vpcola 0:a1734fe1ec4b 88 To build the library, run `make`. It is also recommended to run `make test`.
vpcola 0:a1734fe1ec4b 89 Let me know, if some tests fail.
vpcola 0:a1734fe1ec4b 90
vpcola 0:a1734fe1ec4b 91 If build was successful, you should get a `libjsmn.a` library.
vpcola 0:a1734fe1ec4b 92 The header file you should include is called `"jsmn.h"`.
vpcola 0:a1734fe1ec4b 93
vpcola 0:a1734fe1ec4b 94 API
vpcola 0:a1734fe1ec4b 95 ---
vpcola 0:a1734fe1ec4b 96
vpcola 0:a1734fe1ec4b 97 Token types are described by `jsmntype_t`:
vpcola 0:a1734fe1ec4b 98
vpcola 0:a1734fe1ec4b 99 typedef enum {
vpcola 0:a1734fe1ec4b 100 JSMN_UNDEFINED = 0,
vpcola 0:a1734fe1ec4b 101 JSMN_OBJECT = 1,
vpcola 0:a1734fe1ec4b 102 JSMN_ARRAY = 2,
vpcola 0:a1734fe1ec4b 103 JSMN_STRING = 3,
vpcola 0:a1734fe1ec4b 104 JSMN_PRIMITIVE = 4
vpcola 0:a1734fe1ec4b 105 } jsmntype_t;
vpcola 0:a1734fe1ec4b 106
vpcola 0:a1734fe1ec4b 107 **Note:** Unlike JSON data types, primitive tokens are not divided into
vpcola 0:a1734fe1ec4b 108 numbers, booleans and null, because one can easily tell the type using the
vpcola 0:a1734fe1ec4b 109 first character:
vpcola 0:a1734fe1ec4b 110
vpcola 0:a1734fe1ec4b 111 * <code>'t', 'f'</code> - boolean
vpcola 0:a1734fe1ec4b 112 * <code>'n'</code> - null
vpcola 0:a1734fe1ec4b 113 * <code>'-', '0'..'9'</code> - number
vpcola 0:a1734fe1ec4b 114
vpcola 0:a1734fe1ec4b 115 Token is an object of `jsmntok_t` type:
vpcola 0:a1734fe1ec4b 116
vpcola 0:a1734fe1ec4b 117 typedef struct {
vpcola 0:a1734fe1ec4b 118 jsmntype_t type; // Token type
vpcola 0:a1734fe1ec4b 119 int start; // Token start position
vpcola 0:a1734fe1ec4b 120 int end; // Token end position
vpcola 0:a1734fe1ec4b 121 int size; // Number of child (nested) tokens
vpcola 0:a1734fe1ec4b 122 } jsmntok_t;
vpcola 0:a1734fe1ec4b 123
vpcola 0:a1734fe1ec4b 124 **Note:** string tokens point to the first character after
vpcola 0:a1734fe1ec4b 125 the opening quote and the previous symbol before final quote. This was made
vpcola 0:a1734fe1ec4b 126 to simplify string extraction from JSON data.
vpcola 0:a1734fe1ec4b 127
vpcola 0:a1734fe1ec4b 128 All job is done by `jsmn_parser` object. You can initialize a new parser using:
vpcola 0:a1734fe1ec4b 129
vpcola 0:a1734fe1ec4b 130 jsmn_parser parser;
vpcola 0:a1734fe1ec4b 131 jsmntok_t tokens[10];
vpcola 0:a1734fe1ec4b 132
vpcola 0:a1734fe1ec4b 133 jsmn_init(&parser);
vpcola 0:a1734fe1ec4b 134
vpcola 0:a1734fe1ec4b 135 // js - pointer to JSON string
vpcola 0:a1734fe1ec4b 136 // tokens - an array of tokens available
vpcola 0:a1734fe1ec4b 137 // 10 - number of tokens available
vpcola 0:a1734fe1ec4b 138 jsmn_parse(&parser, js, strlen(js), tokens, 10);
vpcola 0:a1734fe1ec4b 139
vpcola 0:a1734fe1ec4b 140 This will create a parser, and then it tries to parse up to 10 JSON tokens from
vpcola 0:a1734fe1ec4b 141 the `js` string.
vpcola 0:a1734fe1ec4b 142
vpcola 0:a1734fe1ec4b 143 A non-negative return value of `jsmn_parse` is the number of tokens actually
vpcola 0:a1734fe1ec4b 144 used by the parser.
vpcola 0:a1734fe1ec4b 145 Passing NULL instead of the tokens array would not store parsing results, but
vpcola 0:a1734fe1ec4b 146 instead the function will return the value of tokens needed to parse the given
vpcola 0:a1734fe1ec4b 147 string. This can be useful if you don't know yet how many tokens to allocate.
vpcola 0:a1734fe1ec4b 148
vpcola 0:a1734fe1ec4b 149 If something goes wrong, you will get an error. Error will be one of these:
vpcola 0:a1734fe1ec4b 150
vpcola 0:a1734fe1ec4b 151 * `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted
vpcola 0:a1734fe1ec4b 152 * `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large
vpcola 0:a1734fe1ec4b 153 * `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data
vpcola 0:a1734fe1ec4b 154
vpcola 0:a1734fe1ec4b 155 If you get `JSON_ERROR_NOMEM`, you can re-allocate more tokens and call
vpcola 0:a1734fe1ec4b 156 `jsmn_parse` once more. If you read json data from the stream, you can
vpcola 0:a1734fe1ec4b 157 periodically call `jsmn_parse` and check if return value is `JSON_ERROR_PART`.
vpcola 0:a1734fe1ec4b 158 You will get this error until you reach the end of JSON data.
vpcola 0:a1734fe1ec4b 159
vpcola 0:a1734fe1ec4b 160 Other info
vpcola 0:a1734fe1ec4b 161 ----------
vpcola 0:a1734fe1ec4b 162
vpcola 0:a1734fe1ec4b 163 This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
vpcola 0:a1734fe1ec4b 164 so feel free to integrate it in your commercial products.
vpcola 0:a1734fe1ec4b 165
vpcola 0:a1734fe1ec4b 166 [1]: http://www.json.org/
vpcola 0:a1734fe1ec4b 167 [2]: http://zserge.com/jsmn.html