C-based memory friendly JSON parser based on Serge Zaitsev's JSMN (https://bitbucket.org/zserge/jsmn/wiki/Home)

Dependents:   _library_jsmn _library_jsmn _library_jsmn

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 about JSON format at json.org

Library sources are available at https://bitbucket.org/zserge/jsmn

The web page with some information about jsmn can be found at http://zserge.com/jsmn.html

Committer:
yoonghm
Date:
Mon Nov 17 15:54:28 2014 +0000
Revision:
1:70061827a9c8
Parent:
0:46575249ef23
Child:
2:5167da2fcc4e
Update based on bug fixes at https://bitbucket.org/zserge/jsmn/overview as at 17-Nov-2014.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yoonghm 0:46575249ef23 1 /* C-based low-memory footprint JSON parser for mbed
yoonghm 0:46575249ef23 2 * Based on Serge Zaitsev's JSMN https://bitbucket.org/zserge/jsmn/wiki/Home
yoonghm 0:46575249ef23 3 * JSMN is distributed under MIT license.
yoonghm 0:46575249ef23 4 *
yoonghm 0:46575249ef23 5 * Copyright (c) 2014 YoongHM
yoonghm 0:46575249ef23 6 *
yoonghm 0:46575249ef23 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
yoonghm 0:46575249ef23 8 * of this software and associated documentation files (the "Software"), to deal
yoonghm 0:46575249ef23 9 * in the Software without restriction, including without limitation the rights
yoonghm 0:46575249ef23 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
yoonghm 0:46575249ef23 11 * copies of the Software, and to permit persons to whom the Software is
yoonghm 0:46575249ef23 12 * furnished to do so, subject to the following conditions:
yoonghm 0:46575249ef23 13 *
yoonghm 0:46575249ef23 14 * The above copyright notice and this permission notice shall be included in
yoonghm 0:46575249ef23 15 * all copies or substantial portions of the Software.
yoonghm 0:46575249ef23 16 *
yoonghm 0:46575249ef23 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
yoonghm 0:46575249ef23 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
yoonghm 0:46575249ef23 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
yoonghm 0:46575249ef23 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
yoonghm 0:46575249ef23 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
yoonghm 0:46575249ef23 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
yoonghm 0:46575249ef23 23 * THE SOFTWARE.
yoonghm 0:46575249ef23 24 */
yoonghm 0:46575249ef23 25
yoonghm 0:46575249ef23 26 #ifndef MBED_JSMN_H
yoonghm 0:46575249ef23 27 #define MBED_JSMN_H
yoonghm 0:46575249ef23 28
yoonghm 0:46575249ef23 29 /**
yoonghm 0:46575249ef23 30 * A c-based low-memory low-memory footprint JSON parser for mbed.
yoonghm 0:46575249ef23 31 *
yoonghm 0:46575249ef23 32 * The code is based on Serge Zaitsev's JSMN on
yoonghm 0:46575249ef23 33 * https://bitbucket.org/zserge/jsmn/wiki/Home
yoonghm 0:46575249ef23 34 *
yoonghm 0:46575249ef23 35 * @code
yoonghm 0:46575249ef23 36 *#include "mbed.h"
yoonghm 0:46575249ef23 37 *
yoonghm 0:46575249ef23 38 *#include "jsmn.h"
yoonghm 0:46575249ef23 39 *
yoonghm 0:46575249ef23 40 *#define MAXTOKEN 64
yoonghm 0:46575249ef23 41 *
yoonghm 0:46575249ef23 42 *const char *jsmn_type_str[] = {
yoonghm 0:46575249ef23 43 * "PRIMITIVE",
yoonghm 0:46575249ef23 44 * "OBJECT",
yoonghm 1:70061827a9c8 45 * "ARRAY",
yoonghm 0:46575249ef23 46 * "STRING"
yoonghm 0:46575249ef23 47 *};
yoonghm 0:46575249ef23 48 *
yoonghm 0:46575249ef23 49 *int main()
yoonghm 0:46575249ef23 50 *{
yoonghm 0:46575249ef23 51 * const char *js; // Pointer to json string
yoonghm 0:46575249ef23 52 * int r; // Number of token parsed
yoonghm 0:46575249ef23 53 * jsmn_parser p; // jsmn parser
yoonghm 0:46575249ef23 54 * jsmntok_t t[MAXTOKEN]; // Parsed token
yoonghm 0:46575249ef23 55 *
yoonghm 0:46575249ef23 56 * // JSON may contain multibyte characters or encoded unicode in
yoonghm 0:46575249ef23 57 * // \uXXXX format.
yoonghm 0:46575249ef23 58 * // mbed compiler may complain "invalid multibyte characters ...".
yoonghm 0:46575249ef23 59 * js =
yoonghm 0:46575249ef23 60 *"{"
yoonghm 0:46575249ef23 61 *" \"menu\":"
yoonghm 0:46575249ef23 62 *" {"
yoonghm 0:46575249ef23 63 *" \"id\": 1234,"
yoonghm 0:46575249ef23 64 *" \"group\": \"File\","
yoonghm 0:46575249ef23 65 *" \"popup\":"
yoonghm 0:46575249ef23 66 *" {"
yoonghm 0:46575249ef23 67 *" \"menuitem\":"
yoonghm 0:46575249ef23 68 *" ["
yoonghm 0:46575249ef23 69 *" {\"value\": true, \"onclick\" : \"বিশাল\"},"
yoonghm 0:46575249ef23 70 *" {\"value\": false, 0x1328 : \"groß\"},"
yoonghm 0:46575249ef23 71 *" {\"value\": null, \"15\u00f8C\": \"3\u0111\"},"
yoonghm 0:46575249ef23 72 *" {\"value\": \"測試\", -12.34 : 99}"
yoonghm 0:46575249ef23 73 *" ]"
yoonghm 0:46575249ef23 74 *" }"
yoonghm 0:46575249ef23 75 *" }"
yoonghm 0:46575249ef23 76 *"}";
yoonghm 0:46575249ef23 77 *
yoonghm 0:46575249ef23 78 * jsmn_init(&p);
yoonghm 0:46575249ef23 79 * r = jsmn_parse(&p, js, strlen(js), t, MAXTOKEN);
yoonghm 0:46575249ef23 80 *
yoonghm 0:46575249ef23 81 * printf("Parsed %d tokens\n", r);
yoonghm 0:46575249ef23 82 *
yoonghm 0:46575249ef23 83 * printf(" TYPE START END SIZE PAR\n");
yoonghm 0:46575249ef23 84 * printf(" ---------- ----- ---- ---- ---\n");
yoonghm 0:46575249ef23 85 *
yoonghm 0:46575249ef23 86 * char ch;
yoonghm 0:46575249ef23 87 * jsmntok_t at; // A token for general use
yoonghm 0:46575249ef23 88 * for (int i = 0; i < r; i++)
yoonghm 0:46575249ef23 89 * {
yoonghm 0:46575249ef23 90 * at = t[i];
yoonghm 0:46575249ef23 91 * printf("Token %2d = %-10.10s (%4d - %4d, %3d, %2d) --> ",
yoonghm 0:46575249ef23 92 * i, jsmn_type_str[at.type],
yoonghm 0:46575249ef23 93 * at.start, at.end,
yoonghm 0:46575249ef23 94 * at.size, at.parent);
yoonghm 0:46575249ef23 95 *
yoonghm 0:46575249ef23 96 * switch (at.type)
yoonghm 0:46575249ef23 97 * {
yoonghm 0:46575249ef23 98 * case JSMN_STRING:
yoonghm 0:46575249ef23 99 * printf("%-10.*s\n", at.end - at.start + 2, js + at.start - 1);
yoonghm 0:46575249ef23 100 * break;
yoonghm 0:46575249ef23 101 *
yoonghm 0:46575249ef23 102 * case JSMN_PRIMITIVE:
yoonghm 0:46575249ef23 103 * ch = *(js + at.start);
yoonghm 0:46575249ef23 104 *
yoonghm 0:46575249ef23 105 * if (isdigit(ch) || ch == '-')
yoonghm 0:46575249ef23 106 * printf("%-10.*s\n", at.end - at.start, js + at.start);
yoonghm 0:46575249ef23 107 * else if (tolower(ch) == 'n')
yoonghm 0:46575249ef23 108 * printf("null\n");
yoonghm 0:46575249ef23 109 * else if (tolower(ch) == 't')
yoonghm 0:46575249ef23 110 * printf("true\n");
yoonghm 0:46575249ef23 111 * else if (tolower(ch) == 'f')
yoonghm 0:46575249ef23 112 * printf("false\n");
yoonghm 0:46575249ef23 113 * break;
yoonghm 0:46575249ef23 114 *
yoonghm 0:46575249ef23 115 * default:
yoonghm 0:46575249ef23 116 * printf("\n");
yoonghm 0:46575249ef23 117 * break;
yoonghm 0:46575249ef23 118 * }
yoonghm 0:46575249ef23 119 * }
yoonghm 0:46575249ef23 120 *
yoonghm 0:46575249ef23 121 * while (1)
yoonghm 0:46575249ef23 122 * ;
yoonghm 0:46575249ef23 123 *}
yoonghm 0:46575249ef23 124 * @endcode
yoonghm 0:46575249ef23 125 */
yoonghm 0:46575249ef23 126
yoonghm 0:46575249ef23 127 /** jsmntype_t - JSON type recongized by JSMN.
yoonghm 0:46575249ef23 128 * There are
yoonghm 0:46575249ef23 129 * - Primitive: number, boolean (true/false) or null
yoonghm 0:46575249ef23 130 * - Object
yoonghm 0:46575249ef23 131 * - Array
yoonghm 0:46575249ef23 132 * - String
yoonghm 0:46575249ef23 133 */
yoonghm 0:46575249ef23 134 typedef enum {
yoonghm 0:46575249ef23 135 JSMN_PRIMITIVE = 0,
yoonghm 0:46575249ef23 136 JSMN_OBJECT = 1,
yoonghm 0:46575249ef23 137 JSMN_ARRAY = 2,
yoonghm 0:46575249ef23 138 JSMN_STRING = 3,
yoonghm 0:46575249ef23 139 JSMN_INVALID = 4
yoonghm 0:46575249ef23 140 } jsmntype_t;
yoonghm 0:46575249ef23 141
yoonghm 0:46575249ef23 142
yoonghm 0:46575249ef23 143 /** Error message return by JSMN API
yoonghm 0:46575249ef23 144 *
yoonghm 0:46575249ef23 145 */
yoonghm 0:46575249ef23 146 #define JSMN_ERR_OKAY 0 /* No problem */
yoonghm 0:46575249ef23 147 #define JSMN_ERR_NOMEM -1 /* Not enough tokens were provided */
yoonghm 0:46575249ef23 148 #define JSMN_ERR_INVAL -2 /* Invalid character inside JSON string */
yoonghm 0:46575249ef23 149 #define JSMN_ERR_PART -3 /* Incomplete JSON packet */
yoonghm 0:46575249ef23 150
yoonghm 0:46575249ef23 151
yoonghm 0:46575249ef23 152 /** jsmntok_t - JSON token structure.
yoonghm 0:46575249ef23 153 *
yoonghm 0:46575249ef23 154 * It is a c structure that contained parsed JSON token.
yoonghm 0:46575249ef23 155 *
yoonghm 0:46575249ef23 156 * @param type type (primitive, object, array, string)
yoonghm 0:46575249ef23 157 * @param start start position in JSON data string, excl " if is a string
yoonghm 0:46575249ef23 158 * @param end end position in JSON data string, incl " if is a string
yoonghm 0:46575249ef23 159 * @param size number of token directly under it
yoonghm 0:46575249ef23 160 * @param parent link to its direct parent token number
yoonghm 0:46575249ef23 161 */
yoonghm 0:46575249ef23 162 typedef struct {
yoonghm 0:46575249ef23 163 jsmntype_t type;
yoonghm 0:46575249ef23 164 int start; /* Token's start pos;excl " if is a str */
yoonghm 0:46575249ef23 165 int end; /* Token's last pos;incl " if is a str */
yoonghm 0:46575249ef23 166 int size; /* Number of token directly under it */
yoonghm 0:46575249ef23 167 int parent; /* Nth-token which is its direct parent */
yoonghm 0:46575249ef23 168 } jsmntok_t;
yoonghm 0:46575249ef23 169
yoonghm 0:46575249ef23 170
yoonghm 0:46575249ef23 171 /** JSON parser - JSON parser structure.
yoonghm 0:46575249ef23 172 *
yoonghm 0:46575249ef23 173 * Contains an array of token blocks available. Also stores
yoonghm 0:46575249ef23 174 * the string being parsed now and current position in that string
yoonghm 0:46575249ef23 175 */
yoonghm 0:46575249ef23 176 typedef struct {
yoonghm 0:46575249ef23 177 unsigned int pos; /* offset in the JSON string */
yoonghm 0:46575249ef23 178 unsigned int toknext; /* next token to allocate */
yoonghm 0:46575249ef23 179 int toksuper; /* superior token node, (parent or array)*/
yoonghm 0:46575249ef23 180 } jsmn_parser;
yoonghm 0:46575249ef23 181
yoonghm 0:46575249ef23 182
yoonghm 0:46575249ef23 183 /** Initialize jsmn_parser structure for a new JSON parsing
yoonghm 0:46575249ef23 184 *
yoonghm 0:46575249ef23 185 * @param *parser jsmn_parser structure
yoonghm 0:46575249ef23 186 */
yoonghm 0:46575249ef23 187 void
yoonghm 0:46575249ef23 188 jsmn_init
yoonghm 0:46575249ef23 189 (jsmn_parser *parser
yoonghm 0:46575249ef23 190 );
yoonghm 0:46575249ef23 191
yoonghm 0:46575249ef23 192 /** Parse a given JSON data string into array of jsmntok_t tokens.
yoonghm 0:46575249ef23 193 *
yoonghm 0:46575249ef23 194 * @param *parser jsmn_parser structure
yoonghm 0:46575249ef23 195 * @param *js JSON data string
yoonghm 0:46575249ef23 196 * @param len string length of *js
yoonghm 0:46575249ef23 197 * @param *tokens tokens to hold the parsed data
yoonghm 0:46575249ef23 198 */
yoonghm 0:46575249ef23 199 int
yoonghm 0:46575249ef23 200 jsmn_parse
yoonghm 0:46575249ef23 201 (jsmn_parser *parser
yoonghm 0:46575249ef23 202 ,const char *js
yoonghm 0:46575249ef23 203 ,size_t len
yoonghm 0:46575249ef23 204 ,jsmntok_t *tokens
yoonghm 0:46575249ef23 205 ,unsigned int num_tokens
yoonghm 0:46575249ef23 206 );
yoonghm 0:46575249ef23 207
yoonghm 0:46575249ef23 208
yoonghm 0:46575249ef23 209 #endif // JSMN_H