1. Yaroslav Stavnichiy
  2. nxjson

Source

nxjson / README.md

Yaroslav Stavnic… 88d5d67 






Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… f87030e 
Yaroslav Stavnic… ddacc4c 
Yaroslav Stavnic… 93130a6 
Yaroslav Stavnic… 4c3e564 



Yaroslav Stavnic… f87030e 
Yaroslav Stavnic… 88d5d67 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… 88d5d67 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… 88d5d67 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 



























Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 


Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 


Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… 4c3e564 














Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… ddacc4c 
Yaroslav Stavnic… c71b3c5 

Yaroslav Stavnic… 4c3e564 


Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… ddacc4c 
Yaroslav Stavnic… c71b3c5 





Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… c71b3c5 
Yaroslav Stavnic… ddacc4c 
Yaroslav Stavnic… c71b3c5 







Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… 88d5d67 




Yaroslav Stavnic… 5321426 
Yaroslav Stavnic… 88d5d67 









Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… 88d5d67 


Yaroslav Stavnic… 4c3e564 
Yaroslav Stavnic… 88d5d67 


















NXJSON
================================

Very small JSON parser written in C.

##Features

- Parses JSON from null-terminated string
- Easy to use tree traversal API
- Allows // line and /\* block \*/ comments (except before colon ':')
- Operates on single-byte or multi-byte characters (like UTF-8), but not on wide characters
- Unescapes string values (including Unicode codepoints & surrogates)
- Can use custom Unicode encoder, UTF-8 encoder built in
- Can use custom memory allocator
- Can use custom macro to print errors
- Test suite included

## Limitations

- Non-validating parser; might accept invalid JSON (eg., extra or missing commas, comments, octal or hex numeric values, etc.)

## API

Parsed JSON tree consists of nodes. Each node has type:

    typedef enum nx_json_type {
      NX_JSON_NULL,    // this is null value
      NX_JSON_OBJECT,  // this is an object; properties can be found in child nodes
      NX_JSON_ARRAY,   // this is an array; items can be found in child nodes
      NX_JSON_STRING,  // this is a string; value can be found in text_value field
      NX_JSON_INTEGER, // this is an integer; value can be found in int_value field
      NX_JSON_DOUBLE,  // this is a double; value can be found in dbl_value field
      NX_JSON_BOOL     // this is a boolean; value can be found in int_value field
    } nx_json_type;


The node itself:

    typedef struct nx_json {
      nx_json_type type;       // type of json node, see above
      const char* key;         // key of the property; for object's children only
      const char* text_value;  // text value of STRING node
      long int_value;          // the value of INTEGER or BOOL node
      double dbl_value;        // the value of DOUBLE node
      int length;              // number of children of OBJECT or ARRAY
      nx_json* child;          // points to first child
      nx_json* next;           // points to next child
    } nx_json;


#### Parsing

    const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder);

Parses null-terminated string `text` into `nx_json` tree structure. The string is **modified in place**.

Parsing ends right after retrieving first valid JSON value. Remainder of the text is not analysed.

Returns `NULL` on syntax error. Error details are printed out using user-redefinable macro `NX_JSON_REPORT_ERROR(msg, ptr)`.

Inside parse function `nx_json` nodes get allocated using user-redefinable macro `NX_JSON_CALLOC()` and freed by `NX_JSON_FREE(json)`.

All `text_value` pointers refer to the content of original `text` string, which is modified in place to unescape and null-terminate JSON string literals.

`encoder` is a function defined as follows:

    int unicode_to_my_encoding(unsigned int codepoint, char* p, char** endp) { ... }

Encoder takes Unicode codepoint and writes corresponding encoded value into buffer pointed by `p`. It should store pointer to the end of encoded value into `*endp`. The function should return 1 on success and 0 on error. Number of bytes written must not exceed 6.

NXJSON includes sample encoder `nx_json_unicode_to_utf8`, which converts all `\uXXXX` escapes into UTF-8 sequences.

In case `encoder` parameter is `NULL` all unicode escape sequences (`\uXXXX`) are ignored (remain untouched).


    const nx_json* nx_json_parse_utf8(char* text);

This is shortcut for `nx_json_parse(text, nx_json_unicode_to_utf8)` where `nx_json_unicode_to_utf8` is unicode to UTF-8 encoder provided by NXJSON.


    void nx_json_free(const nx_json* js);

Frees resources (`nx_json` nodes) allocated by `nx_json_parse()`.


#### Traversal

    const nx_json* nx_json_get(const nx_json* json, const char* key);

Gets object's property by key.

If `json` points to `OBJECT` node returns first the object's property identified by key `key`.

If there is no such property returns *dummy* node of type `NX_JSON_NULL`. Never returns literal `NULL`.


    const nx_json* nx_json_item(const nx_json* json, int idx);

Gets array's item by its index.

If `json` points to `ARRAY` node returns array's element identified by index `idx`.

If `json` points to `OBJECT` node returns object's property identified by index `idx`.

If there is no such item/property returns *dummy* node of type `NX_JSON_NULL`. Never returns literal `NULL`.


## Usage Example

JSON code:

    {
      "some-int": 195,
      "array": [ 3, 5.1, -7, "nine", /*11*/ ],
      "some-bool": true,
      "some-dbl": -1e-4,
      "some-null": null,
      "hello": "world!",
      //"other": "/OTHER/",
      "obj": {"KEY": "VAL"}
    }

C API:

    const nx_json* json=nx_json_parse(code, 0);
    if (json) {
      printf("some-int=%ld\n", nx_json_get(json, "some-int")->int_value);
      printf("some-dbl=%lf\n", nx_json_get(json, "some-dbl")->dbl_value);
      printf("some-bool=%s\n", nx_json_get(json, "some-bool")->int_value? "true":"false");
      printf("some-null=%s\n", nx_json_get(json, "some-null")->text_value);
      printf("hello=%s\n", nx_json_get(json, "hello")->text_value);
      printf("other=%s\n", nx_json_get(json, "other")->text_value);
      printf("KEY=%s\n", nx_json_get(nx_json_get(json, "obj"), "KEY")->text_value);
      const nx_json* arr=nx_json_get(json, "array");
      int i;
      for (i=0; i<arr->length; i++) {
        const nx_json* item=nx_json_item(arr, i);
        printf("arr[%d]=(%d) %ld %lf %s\n", i, (int)item->type, item->int_value, item->dbl_value, item->text_value);
      }
      nx_json_free(json);
    }

##License

LGPL v3

##Copyright

Copyright (c) 2013 Yaroslav Stavnichiy <yarosla@gmail.com>