|  | @@ -13,8 +13,6 @@ Ultralightweight JSON parser in ANSI C.
 | 
	
		
			
				|  |  |    * [Parsing JSON](#parsing-json)
 | 
	
		
			
				|  |  |    * [Printing JSON](#printing-json)
 | 
	
		
			
				|  |  |    * [Example](#example)
 | 
	
		
			
				|  |  | -  * [Some JSON](#some-json)
 | 
	
		
			
				|  |  | -  * [Here's the structure](#heres-the-structure)
 | 
	
		
			
				|  |  |    * [Caveats](#caveats)
 | 
	
		
			
				|  |  |    * [Enjoy cJSON!](#enjoy-cjson)
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -463,270 +461,6 @@ end:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  Note that there are no NULL checks except for the result of `cJSON_Parse` because `cJSON_GetObjectItemCaseSensitive` checks for `NULL` inputs already, so a `NULL` value is just propagated and `cJSON_IsNumber` and `cJSON_IsString` return `0` if the input is `NULL`.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -### Some JSON:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```json
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    "name": "Jack (\"Bee\") Nimble",
 | 
	
		
			
				|  |  | -    "format": {
 | 
	
		
			
				|  |  | -        "type":       "rect",
 | 
	
		
			
				|  |  | -        "width":      1920,
 | 
	
		
			
				|  |  | -        "height":     1080,
 | 
	
		
			
				|  |  | -        "interlace":  false,
 | 
	
		
			
				|  |  | -        "frame rate": 24
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
 | 
	
		
			
				|  |  | -you have a `char *` to it. Everything is a `cJSON` struct.
 | 
	
		
			
				|  |  | -Get it parsed:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON * root = cJSON_Parse(my_json_string);
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -This is an object. We're in C. We don't have objects. But we do have structs.
 | 
	
		
			
				|  |  | -What's the framerate?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON *format = cJSON_GetObjectItemCaseSensitive(root, "format");
 | 
	
		
			
				|  |  | -cJSON *framerate_item = cJSON_GetObjectItemCaseSensitive(format, "frame rate");
 | 
	
		
			
				|  |  | -double framerate = 0;
 | 
	
		
			
				|  |  | -if (cJSON_IsNumber(framerate_item))
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  framerate = framerate_item->valuedouble;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Want to change the framerate?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON *framerate_item = cJSON_GetObjectItemCaseSensitive(format, "frame rate");
 | 
	
		
			
				|  |  | -cJSON_SetNumberValue(framerate_item, 25);
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Back to disk?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -char *rendered = cJSON_Print(root);
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Finished? Delete the root (this takes care of everything else).
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON_Delete(root);
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
 | 
	
		
			
				|  |  | -before you dereference them. If you want to see how you'd build this struct in code?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON *root;
 | 
	
		
			
				|  |  | -cJSON *fmt;
 | 
	
		
			
				|  |  | -root = cJSON_CreateObject();
 | 
	
		
			
				|  |  | -cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
 | 
	
		
			
				|  |  | -cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
 | 
	
		
			
				|  |  | -cJSON_AddStringToObject(fmt, "type", "rect");
 | 
	
		
			
				|  |  | -cJSON_AddNumberToObject(fmt, "width", 1920);
 | 
	
		
			
				|  |  | -cJSON_AddNumberToObject(fmt, "height", 1080);
 | 
	
		
			
				|  |  | -cJSON_AddFalseToObject (fmt, "interlace");
 | 
	
		
			
				|  |  | -cJSON_AddNumberToObject(fmt, "frame rate", 24);
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
 | 
	
		
			
				|  |  | -Look at `test.c` for a bunch of nice examples, mostly all ripped off the [json.org](http://json.org) site, and
 | 
	
		
			
				|  |  | -a few from elsewhere.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -What about manual mode? First up you need some detail.
 | 
	
		
			
				|  |  | -Let's cover how the `cJSON` objects represent the JSON data.
 | 
	
		
			
				|  |  | -cJSON doesn't distinguish arrays from objects in handling; just type.
 | 
	
		
			
				|  |  | -Each `cJSON` has, potentially, a child, siblings, value, a name.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -* The `root` object has: *Object* Type and a Child
 | 
	
		
			
				|  |  | -* The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
 | 
	
		
			
				|  |  | -* Sibling has type *Object*, name "format", and a child.
 | 
	
		
			
				|  |  | -* That child has type *String*, name "type", value "rect", and a sibling:
 | 
	
		
			
				|  |  | -* Sibling has type *Number*, name "width", value 1920, and a sibling:
 | 
	
		
			
				|  |  | -* Sibling has type *Number*, name "height", value 1080, and a sibling:
 | 
	
		
			
				|  |  | -* Sibling has type *False*, name "interlace", and a sibling:
 | 
	
		
			
				|  |  | -* Sibling has type *Number*, name "frame rate", value 24
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -### Here's the structure:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -typedef struct cJSON {
 | 
	
		
			
				|  |  | -    struct cJSON *next,*prev;
 | 
	
		
			
				|  |  | -    struct cJSON *child;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    int type;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    char *valuestring;
 | 
	
		
			
				|  |  | -    int valueint; /* writing to valueint is DEPRECATED, please use cJSON_SetNumberValue instead */
 | 
	
		
			
				|  |  | -    double valuedouble;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    char *string;
 | 
	
		
			
				|  |  | -} cJSON;
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -By default all values are 0 unless set by virtue of being meaningful.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`next`/`prev` is a doubly linked list of siblings. `next` takes you to your sibling,
 | 
	
		
			
				|  |  | -`prev` takes you back from your sibling to you.
 | 
	
		
			
				|  |  | -Only objects and arrays have a `child`, and it's the head of the doubly linked list.
 | 
	
		
			
				|  |  | -A `child` entry will have `prev == 0`, but next potentially points on. The last sibling has `next == 0`.
 | 
	
		
			
				|  |  | -The type expresses *Null*/*True*/*False*/*Number*/*String*/*Array*/*Object*, all of which are `#defined` in
 | 
	
		
			
				|  |  | -`cJSON.h`.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -A *Number* has `valueint` and `valuedouble`. `valueint` is a relict of the past, so always use `valuedouble`.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Any entry which is in the linked list which is the child of an object will have a `string`
 | 
	
		
			
				|  |  | -which is the "name" of the entry. When I said "name" in the above example, that's `string`.
 | 
	
		
			
				|  |  | -`string` is the JSON name for the 'variable name' if you will.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Now you can trivially walk the lists, recursively, and parse as you please.
 | 
	
		
			
				|  |  | -You can invoke `cJSON_Parse` to get cJSON to parse for you, and then you can take
 | 
	
		
			
				|  |  | -the root object, and traverse the structure (which is, formally, an N-tree),
 | 
	
		
			
				|  |  | -and tokenise as you please. If you wanted to build a callback style parser, this is how
 | 
	
		
			
				|  |  | -you'd do it (just an example, since these things are very specific):
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -void parse_and_callback(cJSON *item, const char *prefix)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    while (item)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        char *newprefix = malloc(strlen(prefix) + strlen(item->string) + 2);
 | 
	
		
			
				|  |  | -        sprintf(newprefix, "%s/%s", prefix, item->string);
 | 
	
		
			
				|  |  | -        int dorecurse = callback(newprefix, item->type, item);
 | 
	
		
			
				|  |  | -        if (item->child && dorecurse)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            parse_and_callback(item->child, newprefix);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        item = item->next;
 | 
	
		
			
				|  |  | -        free(newprefix);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -The `prefix` process will build you a separated list, to simplify your callback handling.
 | 
	
		
			
				|  |  | -The `dorecurse` flag would let the callback decide to handle sub-arrays on it's own, or
 | 
	
		
			
				|  |  | -let you invoke it per-item. For the item above, your callback might look like this:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -int callback(const char *name, int type, cJSON *item)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    if (!strcmp(name, "name"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* populate name */
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (!strcmp(name, "format/type"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* handle "rect" */ }
 | 
	
		
			
				|  |  | -    else if (!strcmp(name, "format/width"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* 800 */
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (!strcmp(name, "format/height"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* 600 */
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (!strcmp(name, "format/interlace"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* false */
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (!strcmp(name, "format/frame rate"))
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        /* 24 */
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return 1;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Alternatively, you might like to parse iteratively.
 | 
	
		
			
				|  |  | -You'd use:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -void parse_object(cJSON *item)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    int i;
 | 
	
		
			
				|  |  | -    for (i = 0; i < cJSON_GetArraySize(item); i++)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        cJSON *subitem = cJSON_GetArrayItem(item, i);
 | 
	
		
			
				|  |  | -        // handle subitem
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Or, for PROPER manual mode:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -void parse_object(cJSON *item)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    cJSON *subitem = item->child;
 | 
	
		
			
				|  |  | -    while (subitem)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        // handle subitem
 | 
	
		
			
				|  |  | -        if (subitem->child)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            parse_object(subitem->child);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        subitem = subitem->next;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Of course, this should look familiar, since this is just a stripped-down version
 | 
	
		
			
				|  |  | -of the callback-parser.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -This should cover most uses you'll find for parsing. The rest should be possible
 | 
	
		
			
				|  |  | -to infer.. and if in doubt, read the source! There's not a lot of it! ;)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -In terms of constructing JSON data, the example code above is the right way to do it.
 | 
	
		
			
				|  |  | -You can, of course, hand your sub-objects to other functions to populate.
 | 
	
		
			
				|  |  | -Also, if you find a use for it, you can manually build the objects.
 | 
	
		
			
				|  |  | -For instance, suppose you wanted to build an array of objects?
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -```c
 | 
	
		
			
				|  |  | -cJSON *objects[24];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -cJSON *Create_array_of_anything(cJSON **items, int num)
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    int i;
 | 
	
		
			
				|  |  | -    cJSON *prev;
 | 
	
		
			
				|  |  | -    cJSON *root = cJSON_CreateArray();
 | 
	
		
			
				|  |  | -    for (i = 0; i < 24; i++)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        if (!i)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            root->child = objects[i];
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            prev->next = objects[i];
 | 
	
		
			
				|  |  | -            objects[i]->prev = prev;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        prev = objects[i];
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return root;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -```
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -and simply: `Create_array_of_anything(objects, 24);`
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -cJSON doesn't make any assumptions about what order you create things in.
 | 
	
		
			
				|  |  | -You can attach the objects, as above, and later add children to each
 | 
	
		
			
				|  |  | -of those objects.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -As soon as you call `cJSON_Print`, it renders the structure to text.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -The `test.c` code shows how to handle a bunch of typical cases. If you uncomment
 | 
	
		
			
				|  |  | -the code, it'll load, parse and print a bunch of test files, also from [json.org](http://json.org),
 | 
	
		
			
				|  |  | -which are more complex than I'd care to try and stash into a `const char array[]`.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  ### Caveats
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #### Zero Character
 | 
	
	
		
			
				|  | @@ -768,5 +502,6 @@ When cJSON was originally created, it didn't follow the JSON standard and didn't
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  # Enjoy cJSON!
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -- Dave Gamble, Aug 2009
 | 
	
		
			
				|  |  | -- [cJSON contributors](CONTRIBUTORS.md)
 | 
	
		
			
				|  |  | +- Dave Gamble (original author)
 | 
	
		
			
				|  |  | +- Max Bruckner (current maintainer)
 | 
	
		
			
				|  |  | +- and the other [cJSON contributors](CONTRIBUTORS.md)
 |