prometheus-client-mmap 0.20.3-arm64-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/README.md +253 -0
 - data/ext/fast_mmaped_file/extconf.rb +30 -0
 - data/ext/fast_mmaped_file/fast_mmaped_file.c +122 -0
 - data/ext/fast_mmaped_file/file_format.c +5 -0
 - data/ext/fast_mmaped_file/file_format.h +11 -0
 - data/ext/fast_mmaped_file/file_parsing.c +195 -0
 - data/ext/fast_mmaped_file/file_parsing.h +27 -0
 - data/ext/fast_mmaped_file/file_reading.c +102 -0
 - data/ext/fast_mmaped_file/file_reading.h +30 -0
 - data/ext/fast_mmaped_file/globals.h +14 -0
 - data/ext/fast_mmaped_file/mmap.c +427 -0
 - data/ext/fast_mmaped_file/mmap.h +61 -0
 - data/ext/fast_mmaped_file/rendering.c +199 -0
 - data/ext/fast_mmaped_file/rendering.h +8 -0
 - data/ext/fast_mmaped_file/utils.c +56 -0
 - data/ext/fast_mmaped_file/utils.h +22 -0
 - data/ext/fast_mmaped_file/value_access.c +242 -0
 - data/ext/fast_mmaped_file/value_access.h +15 -0
 - data/ext/fast_mmaped_file_rs/.cargo/config.toml +23 -0
 - data/ext/fast_mmaped_file_rs/Cargo.lock +790 -0
 - data/ext/fast_mmaped_file_rs/Cargo.toml +30 -0
 - data/ext/fast_mmaped_file_rs/README.md +52 -0
 - data/ext/fast_mmaped_file_rs/extconf.rb +30 -0
 - data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
 - data/ext/fast_mmaped_file_rs/src/file_entry.rs +579 -0
 - data/ext/fast_mmaped_file_rs/src/file_info.rs +190 -0
 - data/ext/fast_mmaped_file_rs/src/lib.rs +79 -0
 - data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
 - data/ext/fast_mmaped_file_rs/src/map.rs +492 -0
 - data/ext/fast_mmaped_file_rs/src/mmap.rs +151 -0
 - data/ext/fast_mmaped_file_rs/src/parser.rs +346 -0
 - data/ext/fast_mmaped_file_rs/src/raw_entry.rs +473 -0
 - data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
 - data/ext/fast_mmaped_file_rs/src/util.rs +121 -0
 - data/lib/2.7/fast_mmaped_file.bundle +0 -0
 - data/lib/2.7/fast_mmaped_file_rs.bundle +0 -0
 - data/lib/3.0/fast_mmaped_file.bundle +0 -0
 - data/lib/3.0/fast_mmaped_file_rs.bundle +0 -0
 - data/lib/3.1/fast_mmaped_file.bundle +0 -0
 - data/lib/3.1/fast_mmaped_file_rs.bundle +0 -0
 - data/lib/3.2/fast_mmaped_file.bundle +0 -0
 - data/lib/3.2/fast_mmaped_file_rs.bundle +0 -0
 - data/lib/prometheus/client/configuration.rb +23 -0
 - data/lib/prometheus/client/counter.rb +27 -0
 - data/lib/prometheus/client/formats/text.rb +118 -0
 - data/lib/prometheus/client/gauge.rb +40 -0
 - data/lib/prometheus/client/helper/entry_parser.rb +132 -0
 - data/lib/prometheus/client/helper/file_locker.rb +50 -0
 - data/lib/prometheus/client/helper/json_parser.rb +23 -0
 - data/lib/prometheus/client/helper/metrics_processing.rb +45 -0
 - data/lib/prometheus/client/helper/metrics_representation.rb +51 -0
 - data/lib/prometheus/client/helper/mmaped_file.rb +64 -0
 - data/lib/prometheus/client/helper/plain_file.rb +29 -0
 - data/lib/prometheus/client/histogram.rb +80 -0
 - data/lib/prometheus/client/label_set_validator.rb +86 -0
 - data/lib/prometheus/client/metric.rb +80 -0
 - data/lib/prometheus/client/mmaped_dict.rb +79 -0
 - data/lib/prometheus/client/mmaped_value.rb +154 -0
 - data/lib/prometheus/client/page_size.rb +17 -0
 - data/lib/prometheus/client/push.rb +203 -0
 - data/lib/prometheus/client/rack/collector.rb +88 -0
 - data/lib/prometheus/client/rack/exporter.rb +96 -0
 - data/lib/prometheus/client/registry.rb +65 -0
 - data/lib/prometheus/client/simple_value.rb +31 -0
 - data/lib/prometheus/client/summary.rb +69 -0
 - data/lib/prometheus/client/support/unicorn.rb +35 -0
 - data/lib/prometheus/client/uses_value_type.rb +20 -0
 - data/lib/prometheus/client/version.rb +5 -0
 - data/lib/prometheus/client.rb +58 -0
 - data/lib/prometheus.rb +3 -0
 - data/vendor/c/hashmap/.gitignore +52 -0
 - data/vendor/c/hashmap/LICENSE +21 -0
 - data/vendor/c/hashmap/README.md +90 -0
 - data/vendor/c/hashmap/_config.yml +1 -0
 - data/vendor/c/hashmap/src/hashmap.c +692 -0
 - data/vendor/c/hashmap/src/hashmap.h +267 -0
 - data/vendor/c/hashmap/test/Makefile +22 -0
 - data/vendor/c/hashmap/test/hashmap_test.c +608 -0
 - data/vendor/c/jsmn/.travis.yml +4 -0
 - data/vendor/c/jsmn/LICENSE +20 -0
 - data/vendor/c/jsmn/Makefile +41 -0
 - data/vendor/c/jsmn/README.md +168 -0
 - data/vendor/c/jsmn/example/jsondump.c +126 -0
 - data/vendor/c/jsmn/example/simple.c +76 -0
 - data/vendor/c/jsmn/jsmn.c +314 -0
 - data/vendor/c/jsmn/jsmn.h +76 -0
 - data/vendor/c/jsmn/library.json +16 -0
 - data/vendor/c/jsmn/test/test.h +27 -0
 - data/vendor/c/jsmn/test/tests.c +407 -0
 - data/vendor/c/jsmn/test/testutil.h +94 -0
 - metadata +243 -0
 
| 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            JSMN
         
     | 
| 
      
 2 
     | 
    
         
            +
            ====
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            [](https://travis-ci.org/zserge/jsmn)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C.  It can be
         
     | 
| 
      
 7 
     | 
    
         
            +
            easily integrated into resource-limited or embedded projects.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            You can find more information about JSON format at [json.org][1]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Library sources are available at https://github.com/zserge/jsmn
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            The web page with some information about jsmn can be found at
         
     | 
| 
      
 14 
     | 
    
         
            +
            [http://zserge.com/jsmn.html][2]
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            Philosophy
         
     | 
| 
      
 17 
     | 
    
         
            +
            ----------
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Most JSON parsers offer you a bunch of functions to load JSON data, parse it
         
     | 
| 
      
 20 
     | 
    
         
            +
            and extract any value by its name. jsmn proves that checking the correctness of
         
     | 
| 
      
 21 
     | 
    
         
            +
            every JSON packet or allocating temporary objects to store parsed JSON fields
         
     | 
| 
      
 22 
     | 
    
         
            +
            often is an overkill. 
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            JSON format itself is extremely simple, so why should we complicate it?
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            jsmn is designed to be	**robust** (it should work fine even with erroneous
         
     | 
| 
      
 27 
     | 
    
         
            +
            data), **fast** (it should parse data on the fly), **portable** (no superfluous
         
     | 
| 
      
 28 
     | 
    
         
            +
            dependencies or non-standard C extensions). And of course, **simplicity** is a
         
     | 
| 
      
 29 
     | 
    
         
            +
            key feature - simple code style, simple algorithm, simple integration into
         
     | 
| 
      
 30 
     | 
    
         
            +
            other projects.
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            Features
         
     | 
| 
      
 33 
     | 
    
         
            +
            --------
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            * compatible with C89
         
     | 
| 
      
 36 
     | 
    
         
            +
            * no dependencies (even libc!)
         
     | 
| 
      
 37 
     | 
    
         
            +
            * highly portable (tested on x86/amd64, ARM, AVR)
         
     | 
| 
      
 38 
     | 
    
         
            +
            * about 200 lines of code
         
     | 
| 
      
 39 
     | 
    
         
            +
            * extremely small code footprint
         
     | 
| 
      
 40 
     | 
    
         
            +
            * API contains only 2 functions
         
     | 
| 
      
 41 
     | 
    
         
            +
            * no dynamic memory allocation
         
     | 
| 
      
 42 
     | 
    
         
            +
            * incremental single-pass parsing
         
     | 
| 
      
 43 
     | 
    
         
            +
            * library code is covered with unit-tests
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            Design
         
     | 
| 
      
 46 
     | 
    
         
            +
            ------
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            The rudimentary jsmn object is a **token**. Let's consider a JSON string:
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            	'{ "name" : "Jack", "age" : 27 }'
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            It holds the following tokens:
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            * Object: `{ "name" : "Jack", "age" : 27}` (the whole object)
         
     | 
| 
      
 55 
     | 
    
         
            +
            * Strings: `"name"`, `"Jack"`, `"age"` (keys and some values)
         
     | 
| 
      
 56 
     | 
    
         
            +
            * Number: `27`
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            In jsmn, tokens do not hold any data, but point to token boundaries in JSON
         
     | 
| 
      
 59 
     | 
    
         
            +
            string instead. In the example above jsmn will create tokens like: Object
         
     | 
| 
      
 60 
     | 
    
         
            +
            [0..31], String [3..7], String [12..16], String [20..23], Number [27..29].
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            Every jsmn token has a type, which indicates the type of corresponding JSON
         
     | 
| 
      
 63 
     | 
    
         
            +
            token. jsmn supports the following token types:
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            * Object - a container of key-value pairs, e.g.:
         
     | 
| 
      
 66 
     | 
    
         
            +
            	`{ "foo":"bar", "x":0.3 }`
         
     | 
| 
      
 67 
     | 
    
         
            +
            * Array - a sequence of values, e.g.:
         
     | 
| 
      
 68 
     | 
    
         
            +
            	`[ 1, 2, 3 ]`
         
     | 
| 
      
 69 
     | 
    
         
            +
            * String - a quoted sequence of chars, e.g.: `"foo"`
         
     | 
| 
      
 70 
     | 
    
         
            +
            * Primitive - a number, a boolean (`true`, `false`) or `null`
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            Besides start/end positions, jsmn tokens for complex types (like arrays
         
     | 
| 
      
 73 
     | 
    
         
            +
            or objects) also contain a number of child items, so you can easily follow
         
     | 
| 
      
 74 
     | 
    
         
            +
            object hierarchy.
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            This approach provides enough information for parsing any JSON data and makes
         
     | 
| 
      
 77 
     | 
    
         
            +
            it possible to use zero-copy techniques.
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            Install
         
     | 
| 
      
 80 
     | 
    
         
            +
            -------
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            To clone the repository you should have Git installed. Just run:
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            	$ git clone https://github.com/zserge/jsmn
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            Repository layout is simple: jsmn.c and jsmn.h are library files, tests are in
         
     | 
| 
      
 87 
     | 
    
         
            +
            the jsmn\_test.c, you will also find README, LICENSE and Makefile files inside.
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            To build the library, run `make`. It is also recommended to run `make test`.
         
     | 
| 
      
 90 
     | 
    
         
            +
            Let me know, if some tests fail.
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            If build was successful, you should get a `libjsmn.a` library.
         
     | 
| 
      
 93 
     | 
    
         
            +
            The header file you should include is called `"jsmn.h"`.
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            API
         
     | 
| 
      
 96 
     | 
    
         
            +
            ---
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            Token types are described by `jsmntype_t`:
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            	typedef enum {
         
     | 
| 
      
 101 
     | 
    
         
            +
            		JSMN_UNDEFINED = 0,
         
     | 
| 
      
 102 
     | 
    
         
            +
            		JSMN_OBJECT = 1,
         
     | 
| 
      
 103 
     | 
    
         
            +
            		JSMN_ARRAY = 2,
         
     | 
| 
      
 104 
     | 
    
         
            +
            		JSMN_STRING = 3,
         
     | 
| 
      
 105 
     | 
    
         
            +
            		JSMN_PRIMITIVE = 4
         
     | 
| 
      
 106 
     | 
    
         
            +
            	} jsmntype_t;
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            **Note:** Unlike JSON data types, primitive tokens are not divided into
         
     | 
| 
      
 109 
     | 
    
         
            +
            numbers, booleans and null, because one can easily tell the type using the
         
     | 
| 
      
 110 
     | 
    
         
            +
            first character:
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            * <code>'t', 'f'</code> - boolean 
         
     | 
| 
      
 113 
     | 
    
         
            +
            * <code>'n'</code> - null
         
     | 
| 
      
 114 
     | 
    
         
            +
            * <code>'-', '0'..'9'</code> - number
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            Token is an object of `jsmntok_t` type:
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            	typedef struct {
         
     | 
| 
      
 119 
     | 
    
         
            +
            		jsmntype_t type; // Token type
         
     | 
| 
      
 120 
     | 
    
         
            +
            		int start;       // Token start position
         
     | 
| 
      
 121 
     | 
    
         
            +
            		int end;         // Token end position
         
     | 
| 
      
 122 
     | 
    
         
            +
            		int size;        // Number of child (nested) tokens
         
     | 
| 
      
 123 
     | 
    
         
            +
            	} jsmntok_t;
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            **Note:** string tokens point to the first character after
         
     | 
| 
      
 126 
     | 
    
         
            +
            the opening quote and the previous symbol before final quote. This was made 
         
     | 
| 
      
 127 
     | 
    
         
            +
            to simplify string extraction from JSON data.
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            All job is done by `jsmn_parser` object. You can initialize a new parser using:
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            	jsmn_parser parser;
         
     | 
| 
      
 132 
     | 
    
         
            +
            	jsmntok_t tokens[10];
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            	jsmn_init(&parser);
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            	// js - pointer to JSON string
         
     | 
| 
      
 137 
     | 
    
         
            +
            	// tokens - an array of tokens available
         
     | 
| 
      
 138 
     | 
    
         
            +
            	// 10 - number of tokens available
         
     | 
| 
      
 139 
     | 
    
         
            +
            	jsmn_parse(&parser, js, strlen(js), tokens, 10);
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            This will create a parser, and then it tries to parse up to 10 JSON tokens from
         
     | 
| 
      
 142 
     | 
    
         
            +
            the `js` string.
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            A non-negative return value of `jsmn_parse` is the number of tokens actually
         
     | 
| 
      
 145 
     | 
    
         
            +
            used by the parser.
         
     | 
| 
      
 146 
     | 
    
         
            +
            Passing NULL instead of the tokens array would not store parsing results, but
         
     | 
| 
      
 147 
     | 
    
         
            +
            instead the function will return the value of tokens needed to parse the given
         
     | 
| 
      
 148 
     | 
    
         
            +
            string. This can be useful if you don't know yet how many tokens to allocate.
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            If something goes wrong, you will get an error. Error will be one of these:
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            * `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted
         
     | 
| 
      
 153 
     | 
    
         
            +
            * `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large
         
     | 
| 
      
 154 
     | 
    
         
            +
            * `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
            If you get `JSON_ERROR_NOMEM`, you can re-allocate more tokens and call
         
     | 
| 
      
 157 
     | 
    
         
            +
            `jsmn_parse` once more.  If you read json data from the stream, you can
         
     | 
| 
      
 158 
     | 
    
         
            +
            periodically call `jsmn_parse` and check if return value is `JSON_ERROR_PART`.
         
     | 
| 
      
 159 
     | 
    
         
            +
            You will get this error until you reach the end of JSON data.
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            Other info
         
     | 
| 
      
 162 
     | 
    
         
            +
            ----------
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
         
     | 
| 
      
 165 
     | 
    
         
            +
             so feel free to integrate it in your commercial products.
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            [1]: http://www.json.org/
         
     | 
| 
      
 168 
     | 
    
         
            +
            [2]: http://zserge.com/jsmn.html
         
     | 
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <unistd.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <errno.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include "../jsmn.h"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            /* Function realloc_it() is a wrapper function for standart realloc()
         
     | 
| 
      
 9 
     | 
    
         
            +
             * with one difference - it frees old memory pointer in case of realloc
         
     | 
| 
      
 10 
     | 
    
         
            +
             * failure. Thus, DO NOT use old data pointer in anyway after call to
         
     | 
| 
      
 11 
     | 
    
         
            +
             * realloc_it(). If your code has some kind of fallback algorithm if
         
     | 
| 
      
 12 
     | 
    
         
            +
             * memory can't be re-allocated - use standart realloc() instead.
         
     | 
| 
      
 13 
     | 
    
         
            +
             */
         
     | 
| 
      
 14 
     | 
    
         
            +
            static inline void *realloc_it(void *ptrmem, size_t size) {
         
     | 
| 
      
 15 
     | 
    
         
            +
            	void *p = realloc(ptrmem, size);
         
     | 
| 
      
 16 
     | 
    
         
            +
            	if (!p)  {
         
     | 
| 
      
 17 
     | 
    
         
            +
            		free (ptrmem);
         
     | 
| 
      
 18 
     | 
    
         
            +
            		fprintf(stderr, "realloc(): errno=%d\n", errno);
         
     | 
| 
      
 19 
     | 
    
         
            +
            	}
         
     | 
| 
      
 20 
     | 
    
         
            +
            	return p;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            /*
         
     | 
| 
      
 24 
     | 
    
         
            +
             * An example of reading JSON from stdin and printing its content to stdout.
         
     | 
| 
      
 25 
     | 
    
         
            +
             * The output looks like YAML, but I'm not sure if it's really compatible.
         
     | 
| 
      
 26 
     | 
    
         
            +
             */
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
         
     | 
| 
      
 29 
     | 
    
         
            +
            	int i, j, k;
         
     | 
| 
      
 30 
     | 
    
         
            +
            	if (count == 0) {
         
     | 
| 
      
 31 
     | 
    
         
            +
            		return 0;
         
     | 
| 
      
 32 
     | 
    
         
            +
            	}
         
     | 
| 
      
 33 
     | 
    
         
            +
            	if (t->type == JSMN_PRIMITIVE) {
         
     | 
| 
      
 34 
     | 
    
         
            +
            		printf("%.*s", t->end - t->start, js+t->start);
         
     | 
| 
      
 35 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 36 
     | 
    
         
            +
            	} else if (t->type == JSMN_STRING) {
         
     | 
| 
      
 37 
     | 
    
         
            +
            		printf("'%.*s'", t->end - t->start, js+t->start);
         
     | 
| 
      
 38 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 39 
     | 
    
         
            +
            	} else if (t->type == JSMN_OBJECT) {
         
     | 
| 
      
 40 
     | 
    
         
            +
            		printf("\n");
         
     | 
| 
      
 41 
     | 
    
         
            +
            		j = 0;
         
     | 
| 
      
 42 
     | 
    
         
            +
            		for (i = 0; i < t->size; i++) {
         
     | 
| 
      
 43 
     | 
    
         
            +
            			for (k = 0; k < indent; k++) printf("  ");
         
     | 
| 
      
 44 
     | 
    
         
            +
            			j += dump(js, t+1+j, count-j, indent+1);
         
     | 
| 
      
 45 
     | 
    
         
            +
            			printf(": ");
         
     | 
| 
      
 46 
     | 
    
         
            +
            			j += dump(js, t+1+j, count-j, indent+1);
         
     | 
| 
      
 47 
     | 
    
         
            +
            			printf("\n");
         
     | 
| 
      
 48 
     | 
    
         
            +
            		}
         
     | 
| 
      
 49 
     | 
    
         
            +
            		return j+1;
         
     | 
| 
      
 50 
     | 
    
         
            +
            	} else if (t->type == JSMN_ARRAY) {
         
     | 
| 
      
 51 
     | 
    
         
            +
            		j = 0;
         
     | 
| 
      
 52 
     | 
    
         
            +
            		printf("\n");
         
     | 
| 
      
 53 
     | 
    
         
            +
            		for (i = 0; i < t->size; i++) {
         
     | 
| 
      
 54 
     | 
    
         
            +
            			for (k = 0; k < indent-1; k++) printf("  ");
         
     | 
| 
      
 55 
     | 
    
         
            +
            			printf("   - ");
         
     | 
| 
      
 56 
     | 
    
         
            +
            			j += dump(js, t+1+j, count-j, indent+1);
         
     | 
| 
      
 57 
     | 
    
         
            +
            			printf("\n");
         
     | 
| 
      
 58 
     | 
    
         
            +
            		}
         
     | 
| 
      
 59 
     | 
    
         
            +
            		return j+1;
         
     | 
| 
      
 60 
     | 
    
         
            +
            	}
         
     | 
| 
      
 61 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 62 
     | 
    
         
            +
            }
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            int main() {
         
     | 
| 
      
 65 
     | 
    
         
            +
            	int r;
         
     | 
| 
      
 66 
     | 
    
         
            +
            	int eof_expected = 0;
         
     | 
| 
      
 67 
     | 
    
         
            +
            	char *js = NULL;
         
     | 
| 
      
 68 
     | 
    
         
            +
            	size_t jslen = 0;
         
     | 
| 
      
 69 
     | 
    
         
            +
            	char buf[BUFSIZ];
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            	jsmn_parser p;
         
     | 
| 
      
 72 
     | 
    
         
            +
            	jsmntok_t *tok;
         
     | 
| 
      
 73 
     | 
    
         
            +
            	size_t tokcount = 2;
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            	/* Prepare parser */
         
     | 
| 
      
 76 
     | 
    
         
            +
            	jsmn_init(&p);
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            	/* Allocate some tokens as a start */
         
     | 
| 
      
 79 
     | 
    
         
            +
            	tok = malloc(sizeof(*tok) * tokcount);
         
     | 
| 
      
 80 
     | 
    
         
            +
            	if (tok == NULL) {
         
     | 
| 
      
 81 
     | 
    
         
            +
            		fprintf(stderr, "malloc(): errno=%d\n", errno);
         
     | 
| 
      
 82 
     | 
    
         
            +
            		return 3;
         
     | 
| 
      
 83 
     | 
    
         
            +
            	}
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            	for (;;) {
         
     | 
| 
      
 86 
     | 
    
         
            +
            		/* Read another chunk */
         
     | 
| 
      
 87 
     | 
    
         
            +
            		r = fread(buf, 1, sizeof(buf), stdin);
         
     | 
| 
      
 88 
     | 
    
         
            +
            		if (r < 0) {
         
     | 
| 
      
 89 
     | 
    
         
            +
            			fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
         
     | 
| 
      
 90 
     | 
    
         
            +
            			return 1;
         
     | 
| 
      
 91 
     | 
    
         
            +
            		}
         
     | 
| 
      
 92 
     | 
    
         
            +
            		if (r == 0) {
         
     | 
| 
      
 93 
     | 
    
         
            +
            			if (eof_expected != 0) {
         
     | 
| 
      
 94 
     | 
    
         
            +
            				return 0;
         
     | 
| 
      
 95 
     | 
    
         
            +
            			} else {
         
     | 
| 
      
 96 
     | 
    
         
            +
            				fprintf(stderr, "fread(): unexpected EOF\n");
         
     | 
| 
      
 97 
     | 
    
         
            +
            				return 2;
         
     | 
| 
      
 98 
     | 
    
         
            +
            			}
         
     | 
| 
      
 99 
     | 
    
         
            +
            		}
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            		js = realloc_it(js, jslen + r + 1);
         
     | 
| 
      
 102 
     | 
    
         
            +
            		if (js == NULL) {
         
     | 
| 
      
 103 
     | 
    
         
            +
            			return 3;
         
     | 
| 
      
 104 
     | 
    
         
            +
            		}
         
     | 
| 
      
 105 
     | 
    
         
            +
            		strncpy(js + jslen, buf, r);
         
     | 
| 
      
 106 
     | 
    
         
            +
            		jslen = jslen + r;
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            again:
         
     | 
| 
      
 109 
     | 
    
         
            +
            		r = jsmn_parse(&p, js, jslen, tok, tokcount);
         
     | 
| 
      
 110 
     | 
    
         
            +
            		if (r < 0) {
         
     | 
| 
      
 111 
     | 
    
         
            +
            			if (r == JSMN_ERROR_NOMEM) {
         
     | 
| 
      
 112 
     | 
    
         
            +
            				tokcount = tokcount * 2;
         
     | 
| 
      
 113 
     | 
    
         
            +
            				tok = realloc_it(tok, sizeof(*tok) * tokcount);
         
     | 
| 
      
 114 
     | 
    
         
            +
            				if (tok == NULL) {
         
     | 
| 
      
 115 
     | 
    
         
            +
            					return 3;
         
     | 
| 
      
 116 
     | 
    
         
            +
            				}
         
     | 
| 
      
 117 
     | 
    
         
            +
            				goto again;
         
     | 
| 
      
 118 
     | 
    
         
            +
            			}
         
     | 
| 
      
 119 
     | 
    
         
            +
            		} else {
         
     | 
| 
      
 120 
     | 
    
         
            +
            			dump(js, tok, p.toknext, 0);
         
     | 
| 
      
 121 
     | 
    
         
            +
            			eof_expected = 1;
         
     | 
| 
      
 122 
     | 
    
         
            +
            		}
         
     | 
| 
      
 123 
     | 
    
         
            +
            	}
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            	return EXIT_SUCCESS;
         
     | 
| 
      
 126 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include "../jsmn.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            /*
         
     | 
| 
      
 7 
     | 
    
         
            +
             * A small example of jsmn parsing when JSON structure is known and number of
         
     | 
| 
      
 8 
     | 
    
         
            +
             * tokens is predictable.
         
     | 
| 
      
 9 
     | 
    
         
            +
             */
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            static const char *JSON_STRING =
         
     | 
| 
      
 12 
     | 
    
         
            +
            	"{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000,\n  "
         
     | 
| 
      
 13 
     | 
    
         
            +
            	"\"groups\": [\"users\", \"wheel\", \"audio\", \"video\"]}";
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
         
     | 
| 
      
 16 
     | 
    
         
            +
            	if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
         
     | 
| 
      
 17 
     | 
    
         
            +
            			strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
         
     | 
| 
      
 18 
     | 
    
         
            +
            		return 0;
         
     | 
| 
      
 19 
     | 
    
         
            +
            	}
         
     | 
| 
      
 20 
     | 
    
         
            +
            	return -1;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            int main() {
         
     | 
| 
      
 24 
     | 
    
         
            +
            	int i;
         
     | 
| 
      
 25 
     | 
    
         
            +
            	int r;
         
     | 
| 
      
 26 
     | 
    
         
            +
            	jsmn_parser p;
         
     | 
| 
      
 27 
     | 
    
         
            +
            	jsmntok_t t[128]; /* We expect no more than 128 tokens */
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            	jsmn_init(&p);
         
     | 
| 
      
 30 
     | 
    
         
            +
            	r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/sizeof(t[0]));
         
     | 
| 
      
 31 
     | 
    
         
            +
            	if (r < 0) {
         
     | 
| 
      
 32 
     | 
    
         
            +
            		printf("Failed to parse JSON: %d\n", r);
         
     | 
| 
      
 33 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 34 
     | 
    
         
            +
            	}
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            	/* Assume the top-level element is an object */
         
     | 
| 
      
 37 
     | 
    
         
            +
            	if (r < 1 || t[0].type != JSMN_OBJECT) {
         
     | 
| 
      
 38 
     | 
    
         
            +
            		printf("Object expected\n");
         
     | 
| 
      
 39 
     | 
    
         
            +
            		return 1;
         
     | 
| 
      
 40 
     | 
    
         
            +
            	}
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            	/* Loop over all keys of the root object */
         
     | 
| 
      
 43 
     | 
    
         
            +
            	for (i = 1; i < r; i++) {
         
     | 
| 
      
 44 
     | 
    
         
            +
            		if (jsoneq(JSON_STRING, &t[i], "user") == 0) {
         
     | 
| 
      
 45 
     | 
    
         
            +
            			/* We may use strndup() to fetch string value */
         
     | 
| 
      
 46 
     | 
    
         
            +
            			printf("- User: %.*s\n", t[i+1].end-t[i+1].start,
         
     | 
| 
      
 47 
     | 
    
         
            +
            					JSON_STRING + t[i+1].start);
         
     | 
| 
      
 48 
     | 
    
         
            +
            			i++;
         
     | 
| 
      
 49 
     | 
    
         
            +
            		} else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) {
         
     | 
| 
      
 50 
     | 
    
         
            +
            			/* We may additionally check if the value is either "true" or "false" */
         
     | 
| 
      
 51 
     | 
    
         
            +
            			printf("- Admin: %.*s\n", t[i+1].end-t[i+1].start,
         
     | 
| 
      
 52 
     | 
    
         
            +
            					JSON_STRING + t[i+1].start);
         
     | 
| 
      
 53 
     | 
    
         
            +
            			i++;
         
     | 
| 
      
 54 
     | 
    
         
            +
            		} else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) {
         
     | 
| 
      
 55 
     | 
    
         
            +
            			/* We may want to do strtol() here to get numeric value */
         
     | 
| 
      
 56 
     | 
    
         
            +
            			printf("- UID: %.*s\n", t[i+1].end-t[i+1].start,
         
     | 
| 
      
 57 
     | 
    
         
            +
            					JSON_STRING + t[i+1].start);
         
     | 
| 
      
 58 
     | 
    
         
            +
            			i++;
         
     | 
| 
      
 59 
     | 
    
         
            +
            		} else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) {
         
     | 
| 
      
 60 
     | 
    
         
            +
            			int j;
         
     | 
| 
      
 61 
     | 
    
         
            +
            			printf("- Groups:\n");
         
     | 
| 
      
 62 
     | 
    
         
            +
            			if (t[i+1].type != JSMN_ARRAY) {
         
     | 
| 
      
 63 
     | 
    
         
            +
            				continue; /* We expect groups to be an array of strings */
         
     | 
| 
      
 64 
     | 
    
         
            +
            			}
         
     | 
| 
      
 65 
     | 
    
         
            +
            			for (j = 0; j < t[i+1].size; j++) {
         
     | 
| 
      
 66 
     | 
    
         
            +
            				jsmntok_t *g = &t[i+j+2];
         
     | 
| 
      
 67 
     | 
    
         
            +
            				printf("  * %.*s\n", g->end - g->start, JSON_STRING + g->start);
         
     | 
| 
      
 68 
     | 
    
         
            +
            			}
         
     | 
| 
      
 69 
     | 
    
         
            +
            			i += t[i+1].size + 1;
         
     | 
| 
      
 70 
     | 
    
         
            +
            		} else {
         
     | 
| 
      
 71 
     | 
    
         
            +
            			printf("Unexpected key: %.*s\n", t[i].end-t[i].start,
         
     | 
| 
      
 72 
     | 
    
         
            +
            					JSON_STRING + t[i].start);
         
     | 
| 
      
 73 
     | 
    
         
            +
            		}
         
     | 
| 
      
 74 
     | 
    
         
            +
            	}
         
     | 
| 
      
 75 
     | 
    
         
            +
            	return EXIT_SUCCESS;
         
     | 
| 
      
 76 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,314 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "jsmn.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            /**
         
     | 
| 
      
 4 
     | 
    
         
            +
             * Allocates a fresh unused token from the token pull.
         
     | 
| 
      
 5 
     | 
    
         
            +
             */
         
     | 
| 
      
 6 
     | 
    
         
            +
            static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
         
     | 
| 
      
 7 
     | 
    
         
            +
            		jsmntok_t *tokens, size_t num_tokens) {
         
     | 
| 
      
 8 
     | 
    
         
            +
            	jsmntok_t *tok;
         
     | 
| 
      
 9 
     | 
    
         
            +
            	if (parser->toknext >= num_tokens) {
         
     | 
| 
      
 10 
     | 
    
         
            +
            		return NULL;
         
     | 
| 
      
 11 
     | 
    
         
            +
            	}
         
     | 
| 
      
 12 
     | 
    
         
            +
            	tok = &tokens[parser->toknext++];
         
     | 
| 
      
 13 
     | 
    
         
            +
            	tok->start = tok->end = -1;
         
     | 
| 
      
 14 
     | 
    
         
            +
            	tok->size = 0;
         
     | 
| 
      
 15 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 16 
     | 
    
         
            +
            	tok->parent = -1;
         
     | 
| 
      
 17 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 18 
     | 
    
         
            +
            	return tok;
         
     | 
| 
      
 19 
     | 
    
         
            +
            }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            /**
         
     | 
| 
      
 22 
     | 
    
         
            +
             * Fills token type and boundaries.
         
     | 
| 
      
 23 
     | 
    
         
            +
             */
         
     | 
| 
      
 24 
     | 
    
         
            +
            static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
         
     | 
| 
      
 25 
     | 
    
         
            +
                                        int start, int end) {
         
     | 
| 
      
 26 
     | 
    
         
            +
            	token->type = type;
         
     | 
| 
      
 27 
     | 
    
         
            +
            	token->start = start;
         
     | 
| 
      
 28 
     | 
    
         
            +
            	token->end = end;
         
     | 
| 
      
 29 
     | 
    
         
            +
            	token->size = 0;
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            /**
         
     | 
| 
      
 33 
     | 
    
         
            +
             * Fills next available token with JSON primitive.
         
     | 
| 
      
 34 
     | 
    
         
            +
             */
         
     | 
| 
      
 35 
     | 
    
         
            +
            static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
         
     | 
| 
      
 36 
     | 
    
         
            +
            		size_t len, jsmntok_t *tokens, size_t num_tokens) {
         
     | 
| 
      
 37 
     | 
    
         
            +
            	jsmntok_t *token;
         
     | 
| 
      
 38 
     | 
    
         
            +
            	int start;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            	start = parser->pos;
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
         
     | 
| 
      
 43 
     | 
    
         
            +
            		switch (js[parser->pos]) {
         
     | 
| 
      
 44 
     | 
    
         
            +
            #ifndef JSMN_STRICT
         
     | 
| 
      
 45 
     | 
    
         
            +
            			/* In strict mode primitive must be followed by "," or "}" or "]" */
         
     | 
| 
      
 46 
     | 
    
         
            +
            			case ':':
         
     | 
| 
      
 47 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 48 
     | 
    
         
            +
            			case '\t' : case '\r' : case '\n' : case ' ' :
         
     | 
| 
      
 49 
     | 
    
         
            +
            			case ','  : case ']'  : case '}' :
         
     | 
| 
      
 50 
     | 
    
         
            +
            				goto found;
         
     | 
| 
      
 51 
     | 
    
         
            +
            		}
         
     | 
| 
      
 52 
     | 
    
         
            +
            		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
         
     | 
| 
      
 53 
     | 
    
         
            +
            			parser->pos = start;
         
     | 
| 
      
 54 
     | 
    
         
            +
            			return JSMN_ERROR_INVAL;
         
     | 
| 
      
 55 
     | 
    
         
            +
            		}
         
     | 
| 
      
 56 
     | 
    
         
            +
            	}
         
     | 
| 
      
 57 
     | 
    
         
            +
            #ifdef JSMN_STRICT
         
     | 
| 
      
 58 
     | 
    
         
            +
            	/* In strict mode primitive must be followed by a comma/object/array */
         
     | 
| 
      
 59 
     | 
    
         
            +
            	parser->pos = start;
         
     | 
| 
      
 60 
     | 
    
         
            +
            	return JSMN_ERROR_PART;
         
     | 
| 
      
 61 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            found:
         
     | 
| 
      
 64 
     | 
    
         
            +
            	if (tokens == NULL) {
         
     | 
| 
      
 65 
     | 
    
         
            +
            		parser->pos--;
         
     | 
| 
      
 66 
     | 
    
         
            +
            		return 0;
         
     | 
| 
      
 67 
     | 
    
         
            +
            	}
         
     | 
| 
      
 68 
     | 
    
         
            +
            	token = jsmn_alloc_token(parser, tokens, num_tokens);
         
     | 
| 
      
 69 
     | 
    
         
            +
            	if (token == NULL) {
         
     | 
| 
      
 70 
     | 
    
         
            +
            		parser->pos = start;
         
     | 
| 
      
 71 
     | 
    
         
            +
            		return JSMN_ERROR_NOMEM;
         
     | 
| 
      
 72 
     | 
    
         
            +
            	}
         
     | 
| 
      
 73 
     | 
    
         
            +
            	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
         
     | 
| 
      
 74 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 75 
     | 
    
         
            +
            	token->parent = parser->toksuper;
         
     | 
| 
      
 76 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 77 
     | 
    
         
            +
            	parser->pos--;
         
     | 
| 
      
 78 
     | 
    
         
            +
            	return 0;
         
     | 
| 
      
 79 
     | 
    
         
            +
            }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            /**
         
     | 
| 
      
 82 
     | 
    
         
            +
             * Fills next token with JSON string.
         
     | 
| 
      
 83 
     | 
    
         
            +
             */
         
     | 
| 
      
 84 
     | 
    
         
            +
            static int jsmn_parse_string(jsmn_parser *parser, const char *js,
         
     | 
| 
      
 85 
     | 
    
         
            +
            		size_t len, jsmntok_t *tokens, size_t num_tokens) {
         
     | 
| 
      
 86 
     | 
    
         
            +
            	jsmntok_t *token;
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            	int start = parser->pos;
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            	parser->pos++;
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            	/* Skip starting quote */
         
     | 
| 
      
 93 
     | 
    
         
            +
            	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
         
     | 
| 
      
 94 
     | 
    
         
            +
            		char c = js[parser->pos];
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            		/* Quote: end of string */
         
     | 
| 
      
 97 
     | 
    
         
            +
            		if (c == '\"') {
         
     | 
| 
      
 98 
     | 
    
         
            +
            			if (tokens == NULL) {
         
     | 
| 
      
 99 
     | 
    
         
            +
            				return 0;
         
     | 
| 
      
 100 
     | 
    
         
            +
            			}
         
     | 
| 
      
 101 
     | 
    
         
            +
            			token = jsmn_alloc_token(parser, tokens, num_tokens);
         
     | 
| 
      
 102 
     | 
    
         
            +
            			if (token == NULL) {
         
     | 
| 
      
 103 
     | 
    
         
            +
            				parser->pos = start;
         
     | 
| 
      
 104 
     | 
    
         
            +
            				return JSMN_ERROR_NOMEM;
         
     | 
| 
      
 105 
     | 
    
         
            +
            			}
         
     | 
| 
      
 106 
     | 
    
         
            +
            			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
         
     | 
| 
      
 107 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 108 
     | 
    
         
            +
            			token->parent = parser->toksuper;
         
     | 
| 
      
 109 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 110 
     | 
    
         
            +
            			return 0;
         
     | 
| 
      
 111 
     | 
    
         
            +
            		}
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            		/* Backslash: Quoted symbol expected */
         
     | 
| 
      
 114 
     | 
    
         
            +
            		if (c == '\\' && parser->pos + 1 < len) {
         
     | 
| 
      
 115 
     | 
    
         
            +
            			int i;
         
     | 
| 
      
 116 
     | 
    
         
            +
            			parser->pos++;
         
     | 
| 
      
 117 
     | 
    
         
            +
            			switch (js[parser->pos]) {
         
     | 
| 
      
 118 
     | 
    
         
            +
            				/* Allowed escaped symbols */
         
     | 
| 
      
 119 
     | 
    
         
            +
            				case '\"': case '/' : case '\\' : case 'b' :
         
     | 
| 
      
 120 
     | 
    
         
            +
            				case 'f' : case 'r' : case 'n'  : case 't' :
         
     | 
| 
      
 121 
     | 
    
         
            +
            					break;
         
     | 
| 
      
 122 
     | 
    
         
            +
            				/* Allows escaped symbol \uXXXX */
         
     | 
| 
      
 123 
     | 
    
         
            +
            				case 'u':
         
     | 
| 
      
 124 
     | 
    
         
            +
            					parser->pos++;
         
     | 
| 
      
 125 
     | 
    
         
            +
            					for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
         
     | 
| 
      
 126 
     | 
    
         
            +
            						/* If it isn't a hex character we have an error */
         
     | 
| 
      
 127 
     | 
    
         
            +
            						if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
         
     | 
| 
      
 128 
     | 
    
         
            +
            									(js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
         
     | 
| 
      
 129 
     | 
    
         
            +
            									(js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
         
     | 
| 
      
 130 
     | 
    
         
            +
            							parser->pos = start;
         
     | 
| 
      
 131 
     | 
    
         
            +
            							return JSMN_ERROR_INVAL;
         
     | 
| 
      
 132 
     | 
    
         
            +
            						}
         
     | 
| 
      
 133 
     | 
    
         
            +
            						parser->pos++;
         
     | 
| 
      
 134 
     | 
    
         
            +
            					}
         
     | 
| 
      
 135 
     | 
    
         
            +
            					parser->pos--;
         
     | 
| 
      
 136 
     | 
    
         
            +
            					break;
         
     | 
| 
      
 137 
     | 
    
         
            +
            				/* Unexpected symbol */
         
     | 
| 
      
 138 
     | 
    
         
            +
            				default:
         
     | 
| 
      
 139 
     | 
    
         
            +
            					parser->pos = start;
         
     | 
| 
      
 140 
     | 
    
         
            +
            					return JSMN_ERROR_INVAL;
         
     | 
| 
      
 141 
     | 
    
         
            +
            			}
         
     | 
| 
      
 142 
     | 
    
         
            +
            		}
         
     | 
| 
      
 143 
     | 
    
         
            +
            	}
         
     | 
| 
      
 144 
     | 
    
         
            +
            	parser->pos = start;
         
     | 
| 
      
 145 
     | 
    
         
            +
            	return JSMN_ERROR_PART;
         
     | 
| 
      
 146 
     | 
    
         
            +
            }
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            /**
         
     | 
| 
      
 149 
     | 
    
         
            +
             * Parse JSON string and fill tokens.
         
     | 
| 
      
 150 
     | 
    
         
            +
             */
         
     | 
| 
      
 151 
     | 
    
         
            +
            int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
         
     | 
| 
      
 152 
     | 
    
         
            +
            		jsmntok_t *tokens, unsigned int num_tokens) {
         
     | 
| 
      
 153 
     | 
    
         
            +
            	int r;
         
     | 
| 
      
 154 
     | 
    
         
            +
            	int i;
         
     | 
| 
      
 155 
     | 
    
         
            +
            	jsmntok_t *token;
         
     | 
| 
      
 156 
     | 
    
         
            +
            	int count = parser->toknext;
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            	for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
         
     | 
| 
      
 159 
     | 
    
         
            +
            		char c;
         
     | 
| 
      
 160 
     | 
    
         
            +
            		jsmntype_t type;
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
            		c = js[parser->pos];
         
     | 
| 
      
 163 
     | 
    
         
            +
            		switch (c) {
         
     | 
| 
      
 164 
     | 
    
         
            +
            			case '{': case '[':
         
     | 
| 
      
 165 
     | 
    
         
            +
            				count++;
         
     | 
| 
      
 166 
     | 
    
         
            +
            				if (tokens == NULL) {
         
     | 
| 
      
 167 
     | 
    
         
            +
            					break;
         
     | 
| 
      
 168 
     | 
    
         
            +
            				}
         
     | 
| 
      
 169 
     | 
    
         
            +
            				token = jsmn_alloc_token(parser, tokens, num_tokens);
         
     | 
| 
      
 170 
     | 
    
         
            +
            				if (token == NULL)
         
     | 
| 
      
 171 
     | 
    
         
            +
            					return JSMN_ERROR_NOMEM;
         
     | 
| 
      
 172 
     | 
    
         
            +
            				if (parser->toksuper != -1) {
         
     | 
| 
      
 173 
     | 
    
         
            +
            					tokens[parser->toksuper].size++;
         
     | 
| 
      
 174 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 175 
     | 
    
         
            +
            					token->parent = parser->toksuper;
         
     | 
| 
      
 176 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 177 
     | 
    
         
            +
            				}
         
     | 
| 
      
 178 
     | 
    
         
            +
            				token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
         
     | 
| 
      
 179 
     | 
    
         
            +
            				token->start = parser->pos;
         
     | 
| 
      
 180 
     | 
    
         
            +
            				parser->toksuper = parser->toknext - 1;
         
     | 
| 
      
 181 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 182 
     | 
    
         
            +
            			case '}': case ']':
         
     | 
| 
      
 183 
     | 
    
         
            +
            				if (tokens == NULL)
         
     | 
| 
      
 184 
     | 
    
         
            +
            					break;
         
     | 
| 
      
 185 
     | 
    
         
            +
            				type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
         
     | 
| 
      
 186 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 187 
     | 
    
         
            +
            				if (parser->toknext < 1) {
         
     | 
| 
      
 188 
     | 
    
         
            +
            					return JSMN_ERROR_INVAL;
         
     | 
| 
      
 189 
     | 
    
         
            +
            				}
         
     | 
| 
      
 190 
     | 
    
         
            +
            				token = &tokens[parser->toknext - 1];
         
     | 
| 
      
 191 
     | 
    
         
            +
            				for (;;) {
         
     | 
| 
      
 192 
     | 
    
         
            +
            					if (token->start != -1 && token->end == -1) {
         
     | 
| 
      
 193 
     | 
    
         
            +
            						if (token->type != type) {
         
     | 
| 
      
 194 
     | 
    
         
            +
            							return JSMN_ERROR_INVAL;
         
     | 
| 
      
 195 
     | 
    
         
            +
            						}
         
     | 
| 
      
 196 
     | 
    
         
            +
            						token->end = parser->pos + 1;
         
     | 
| 
      
 197 
     | 
    
         
            +
            						parser->toksuper = token->parent;
         
     | 
| 
      
 198 
     | 
    
         
            +
            						break;
         
     | 
| 
      
 199 
     | 
    
         
            +
            					}
         
     | 
| 
      
 200 
     | 
    
         
            +
            					if (token->parent == -1) {
         
     | 
| 
      
 201 
     | 
    
         
            +
            						if(token->type != type || parser->toksuper == -1) {
         
     | 
| 
      
 202 
     | 
    
         
            +
            							return JSMN_ERROR_INVAL;
         
     | 
| 
      
 203 
     | 
    
         
            +
            						}
         
     | 
| 
      
 204 
     | 
    
         
            +
            						break;
         
     | 
| 
      
 205 
     | 
    
         
            +
            					}
         
     | 
| 
      
 206 
     | 
    
         
            +
            					token = &tokens[token->parent];
         
     | 
| 
      
 207 
     | 
    
         
            +
            				}
         
     | 
| 
      
 208 
     | 
    
         
            +
            #else
         
     | 
| 
      
 209 
     | 
    
         
            +
            				for (i = parser->toknext - 1; i >= 0; i--) {
         
     | 
| 
      
 210 
     | 
    
         
            +
            					token = &tokens[i];
         
     | 
| 
      
 211 
     | 
    
         
            +
            					if (token->start != -1 && token->end == -1) {
         
     | 
| 
      
 212 
     | 
    
         
            +
            						if (token->type != type) {
         
     | 
| 
      
 213 
     | 
    
         
            +
            							return JSMN_ERROR_INVAL;
         
     | 
| 
      
 214 
     | 
    
         
            +
            						}
         
     | 
| 
      
 215 
     | 
    
         
            +
            						parser->toksuper = -1;
         
     | 
| 
      
 216 
     | 
    
         
            +
            						token->end = parser->pos + 1;
         
     | 
| 
      
 217 
     | 
    
         
            +
            						break;
         
     | 
| 
      
 218 
     | 
    
         
            +
            					}
         
     | 
| 
      
 219 
     | 
    
         
            +
            				}
         
     | 
| 
      
 220 
     | 
    
         
            +
            				/* Error if unmatched closing bracket */
         
     | 
| 
      
 221 
     | 
    
         
            +
            				if (i == -1) return JSMN_ERROR_INVAL;
         
     | 
| 
      
 222 
     | 
    
         
            +
            				for (; i >= 0; i--) {
         
     | 
| 
      
 223 
     | 
    
         
            +
            					token = &tokens[i];
         
     | 
| 
      
 224 
     | 
    
         
            +
            					if (token->start != -1 && token->end == -1) {
         
     | 
| 
      
 225 
     | 
    
         
            +
            						parser->toksuper = i;
         
     | 
| 
      
 226 
     | 
    
         
            +
            						break;
         
     | 
| 
      
 227 
     | 
    
         
            +
            					}
         
     | 
| 
      
 228 
     | 
    
         
            +
            				}
         
     | 
| 
      
 229 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 230 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 231 
     | 
    
         
            +
            			case '\"':
         
     | 
| 
      
 232 
     | 
    
         
            +
            				r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
         
     | 
| 
      
 233 
     | 
    
         
            +
            				if (r < 0) return r;
         
     | 
| 
      
 234 
     | 
    
         
            +
            				count++;
         
     | 
| 
      
 235 
     | 
    
         
            +
            				if (parser->toksuper != -1 && tokens != NULL)
         
     | 
| 
      
 236 
     | 
    
         
            +
            					tokens[parser->toksuper].size++;
         
     | 
| 
      
 237 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 238 
     | 
    
         
            +
            			case '\t' : case '\r' : case '\n' : case ' ':
         
     | 
| 
      
 239 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 240 
     | 
    
         
            +
            			case ':':
         
     | 
| 
      
 241 
     | 
    
         
            +
            				parser->toksuper = parser->toknext - 1;
         
     | 
| 
      
 242 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 243 
     | 
    
         
            +
            			case ',':
         
     | 
| 
      
 244 
     | 
    
         
            +
            				if (tokens != NULL && parser->toksuper != -1 &&
         
     | 
| 
      
 245 
     | 
    
         
            +
            						tokens[parser->toksuper].type != JSMN_ARRAY &&
         
     | 
| 
      
 246 
     | 
    
         
            +
            						tokens[parser->toksuper].type != JSMN_OBJECT) {
         
     | 
| 
      
 247 
     | 
    
         
            +
            #ifdef JSMN_PARENT_LINKS
         
     | 
| 
      
 248 
     | 
    
         
            +
            					parser->toksuper = tokens[parser->toksuper].parent;
         
     | 
| 
      
 249 
     | 
    
         
            +
            #else
         
     | 
| 
      
 250 
     | 
    
         
            +
            					for (i = parser->toknext - 1; i >= 0; i--) {
         
     | 
| 
      
 251 
     | 
    
         
            +
            						if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
         
     | 
| 
      
 252 
     | 
    
         
            +
            							if (tokens[i].start != -1 && tokens[i].end == -1) {
         
     | 
| 
      
 253 
     | 
    
         
            +
            								parser->toksuper = i;
         
     | 
| 
      
 254 
     | 
    
         
            +
            								break;
         
     | 
| 
      
 255 
     | 
    
         
            +
            							}
         
     | 
| 
      
 256 
     | 
    
         
            +
            						}
         
     | 
| 
      
 257 
     | 
    
         
            +
            					}
         
     | 
| 
      
 258 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 259 
     | 
    
         
            +
            				}
         
     | 
| 
      
 260 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 261 
     | 
    
         
            +
            #ifdef JSMN_STRICT
         
     | 
| 
      
 262 
     | 
    
         
            +
            			/* In strict mode primitives are: numbers and booleans */
         
     | 
| 
      
 263 
     | 
    
         
            +
            			case '-': case '0': case '1' : case '2': case '3' : case '4':
         
     | 
| 
      
 264 
     | 
    
         
            +
            			case '5': case '6': case '7' : case '8': case '9':
         
     | 
| 
      
 265 
     | 
    
         
            +
            			case 't': case 'f': case 'n' :
         
     | 
| 
      
 266 
     | 
    
         
            +
            				/* And they must not be keys of the object */
         
     | 
| 
      
 267 
     | 
    
         
            +
            				if (tokens != NULL && parser->toksuper != -1) {
         
     | 
| 
      
 268 
     | 
    
         
            +
            					jsmntok_t *t = &tokens[parser->toksuper];
         
     | 
| 
      
 269 
     | 
    
         
            +
            					if (t->type == JSMN_OBJECT ||
         
     | 
| 
      
 270 
     | 
    
         
            +
            							(t->type == JSMN_STRING && t->size != 0)) {
         
     | 
| 
      
 271 
     | 
    
         
            +
            						return JSMN_ERROR_INVAL;
         
     | 
| 
      
 272 
     | 
    
         
            +
            					}
         
     | 
| 
      
 273 
     | 
    
         
            +
            				}
         
     | 
| 
      
 274 
     | 
    
         
            +
            #else
         
     | 
| 
      
 275 
     | 
    
         
            +
            			/* In non-strict mode every unquoted value is a primitive */
         
     | 
| 
      
 276 
     | 
    
         
            +
            			default:
         
     | 
| 
      
 277 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 278 
     | 
    
         
            +
            				r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
         
     | 
| 
      
 279 
     | 
    
         
            +
            				if (r < 0) return r;
         
     | 
| 
      
 280 
     | 
    
         
            +
            				count++;
         
     | 
| 
      
 281 
     | 
    
         
            +
            				if (parser->toksuper != -1 && tokens != NULL)
         
     | 
| 
      
 282 
     | 
    
         
            +
            					tokens[parser->toksuper].size++;
         
     | 
| 
      
 283 
     | 
    
         
            +
            				break;
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
            #ifdef JSMN_STRICT
         
     | 
| 
      
 286 
     | 
    
         
            +
            			/* Unexpected char in strict mode */
         
     | 
| 
      
 287 
     | 
    
         
            +
            			default:
         
     | 
| 
      
 288 
     | 
    
         
            +
            				return JSMN_ERROR_INVAL;
         
     | 
| 
      
 289 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 290 
     | 
    
         
            +
            		}
         
     | 
| 
      
 291 
     | 
    
         
            +
            	}
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
            	if (tokens != NULL) {
         
     | 
| 
      
 294 
     | 
    
         
            +
            		for (i = parser->toknext - 1; i >= 0; i--) {
         
     | 
| 
      
 295 
     | 
    
         
            +
            			/* Unmatched opened object or array */
         
     | 
| 
      
 296 
     | 
    
         
            +
            			if (tokens[i].start != -1 && tokens[i].end == -1) {
         
     | 
| 
      
 297 
     | 
    
         
            +
            				return JSMN_ERROR_PART;
         
     | 
| 
      
 298 
     | 
    
         
            +
            			}
         
     | 
| 
      
 299 
     | 
    
         
            +
            		}
         
     | 
| 
      
 300 
     | 
    
         
            +
            	}
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
            	return count;
         
     | 
| 
      
 303 
     | 
    
         
            +
            }
         
     | 
| 
      
 304 
     | 
    
         
            +
             
     | 
| 
      
 305 
     | 
    
         
            +
            /**
         
     | 
| 
      
 306 
     | 
    
         
            +
             * Creates a new parser based over a given  buffer with an array of tokens
         
     | 
| 
      
 307 
     | 
    
         
            +
             * available.
         
     | 
| 
      
 308 
     | 
    
         
            +
             */
         
     | 
| 
      
 309 
     | 
    
         
            +
            void jsmn_init(jsmn_parser *parser) {
         
     | 
| 
      
 310 
     | 
    
         
            +
            	parser->pos = 0;
         
     | 
| 
      
 311 
     | 
    
         
            +
            	parser->toknext = 0;
         
     | 
| 
      
 312 
     | 
    
         
            +
            	parser->toksuper = -1;
         
     | 
| 
      
 313 
     | 
    
         
            +
            }
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     |