Skip to content
Snippets Groups Projects
README.md 6.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • Strhuan Blomquist's avatar
    Strhuan Blomquist committed
    # json-editor
    
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    Json-editor is a library built on top of json-c to offer a syntax akin to javascript when modifying JSON.
    
    ## Building
    
    The library is built using cmake. To build and install the library on your machine run the following instructions from the root directory:
    
    ```
    mkdir build
    cd build
    cmake ../ -DCMAKE_BUILD_TYPE=Release
    make
    sudo make install
    ```
    
    ## API
    
    
    The library currently offers four features, a getter, a setter and a deleter function, accepting a javascript format string representing the syntax, and two functions for reading/writing JSON to a file.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    ### Setter
    
    
    The setter function, ```json_object_set_by_string_delimiter(5)```, will set a value based on provided format, taking five arguments, albeit recommended to be used through a wrapper function ```json_object_set_by_string(4)```, defaulting the delimiter to a dot,```.```.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    ```
    
    int json_object_set_by_string( struct json_object **src, char *fmt, char *val, enum json_type type);
    int json_object_set_by_string_delimiter( struct json_object **src, char *fmt, char *val, enum json_type type, const char *delimiter);
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    ```
    
    
    #### Arguments
    
    1. ```src``` is a pointer to the address of a ```struct json_object```, if it is a null pointer an object will be created.
    2. ```fmt``` is a string representing the syntax pointing to the object to be set, i.e. ```device.macaddr```, note that this syntax may contain nested objects or arrays, i.e. ```a.b[1][0].c```. Additionally, if a key, array or index is missing it will be created and added to the ```src``` pointer. *NULL represents root key.*
    3. ```val``` represents the value to be set. This should always be presented in a string format, albeit can be used to represent integers, strings, arrays of object depending on syntax, i.e. ```{\"macaddr\":\"11:22:33:44:55:66\"}```.
    4. ```type``` expects an enum of ```json_type```, to declare as what object type the input should be added.
    5. ```delimiter``` is syntactical delimiter in the format string.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    #### Example usage
    
    ```
        json_object_set_by_string(&e->modify_obj, "nested0.nested1.integer", "1", json_type_int);
        json_object_set_by_string(&e->modify_obj, "ints", "[ 1, 2, 3 ]", json_type_array);
        json_object_set_by_string(&e->modify_obj, "string", "1", json_type_string);
        json_object_set_by_string(&e->modify_obj, "integer", "1", json_type_int);
        json_object_set_by_string(&e->modify_obj, "obj", "{\"test2\":\"success\"}", json_type_object);
    ```
    
    Assuming an empty starting object this results in the object:
    
    ```
    { "nested0": { "nested1": { "integer": 1 } }, "ints": [ 1, 2, 3 ], "string": "1", "integer": 1, "obj": { "test2": "success" } }
    ```
    
    For more example usage see ```test/api_test.c```.
    
    ### Getter
    
    
    The getter function, ```json_object_get_by_string_delimiter(3)```, gets a key or value based on provided format. Like the setter, recommended to be used through a wrapper function ```json_object_get_by_string(2)```, defaulting the delimiter to a dot,```.```. If the specified format is not present in the object NULL is returned.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    ```
    
    struct json_object *json_object_get_by_string(struct json_object *src, char *fmt);
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    struct json_object *json_object_get_by_string_delimiter(struct json_object *src, char *fmt, const char *delimiter);
    ```
    
    
    #### Arguments
    
    1. ```src``` is a pointer to the  ```struct json_object``` to traverse.
    2. ```fmt``` is a string representing the syntax pointing to the object to be set, i.e. ```device.macaddr```, note that this syntax may contain nested objects or arrays, i.e. ```a.b[1][0].c```.
    3. ```delimiter``` is syntactical delimiter in the format string.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    #### Example usage
    
    Assuming the starting json:
    
    ```
    { "nested0": { "nested1": { "integer": 1 } }, "ints": [ 1, 2, 3 ], "string": "1", "integer": 1, "obj": { "test2": "success" } }
    ```
    Using the getter:
    
    ```
       json_object_get_by_string(e->file_obj, "integer");
    ```
    
    Will return an json object containing ```1```.
    
    For more example usage see ```test/api_test.c```.
    
    
    ### Deleter
    
    The deleter function, ```json_object_del_by_string_delimiter(3)```, deletes a value based on provided format, recommended to be used through the wrapper function ```json_object_del_by_string(2)```, defaulting the delimiter to a dot,```.```. If the specified format is not present in the object NULL is returned.
    
    ```
    int json_object_del_by_string(struct json_object *src, char *fmt);
    int json_object_del_by_string_delimiter(struct json_object *src, char *fmt, const char *delimiter);
    ```
    #### Arguments
    
    ```src``` is a pointer to the  ```struct json_object``` to traverse.
    ```fmt``` is a string representing the syntax pointing to the object to be set, i.e. ```device.macaddr```, note that this syntax may contain nested objects or arrays, i.e. ```a.b[1][0].c```.
    ```delimiter``` is syntactical delimiter in the format string.
    
    #### Example usage
    
    Assuming the starting json:
    
    ```
    { "nested0": { "nested1": { "integer": 1 } }, "ints": [ 1, 2, 3 ], "string": "1", "integer": 1, "obj": { "test2": "success" } }
    ```
    Using the deleter:
    
    ```
       json_object_del_by_string(e->file_obj, "nested0.nested1.integer");
    ```
    
    The remaining object will be:
    
    ```
    { "nested0": { "nested1": { } }, "ints": [ 1, 2, 3 ], "string": "1", "integer": 1, "obj": { "test2": "success" } }
    ```
    
    For more example usage see ```test/api_test.c```.
    
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    ### Read/Write to file
    
    A file to json and a json to file functions have been prepared.
    
    ```
    struct json_object *json_object_file_to_obj(const char *path);
    int json_object_obj_to_file(struct json_object *obj, const char *path);
    ```
    The ```json_object_file_to_obj(1)``` function takes the path to read from as an input and returns an allocated ```struct json_object``` pointer on success, NULL on failure.
    
    ```json_object_obj_to_file(2)``` takes the object to write to file as first argument, and path to the file as second argument. On success 0 is returned, on failure -1.
    
    For example usage see ```test/api_test.c```.
    
    ## Tests
    
    
    During the development of this library cmocka unit testing was used. In total 32 unit tests are prepared, testing a varity of scenarios, with a focus on setters. Additionally, these unit tests are tested with valgrind to ensure no memory leaks are present.
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    
    To run the tests perform the same steps as described under the build section, but this time prepare the cmake build type for debugging (note that if you are building from the same instance you will need to remove ```CMakeCache.txt```):
    
    ```
    mkdir build
    cd build
    cmake ../ -DCMAKE_BUILD_TYPE=Debug
    make
    sudo make install
    ```
    
    There should now be a test subdirectory under the build directory. Now run:
    
    Jakob Olsson's avatar
    Jakob Olsson committed
    
    ```
    sudo make test
    ```
    
    This should run the test cases available:
    ```
    Running tests...
    Test project /home/jakob/git/json-editor/build/test
        Start 1: api_test
    1/2 Test #1: api_test .........................   Passed    0.00 sec
        Start 2: api_test_valgrind
    2/2 Test #2: api_test_valgrind ................   Passed    0.57 sec
    
    100% tests passed, 0 tests failed out of 2
    
    Total Test time (real) =   0.57 sec
    ```