Giter Club home page Giter Club logo

json-builder's Introduction

Very low footprint DOM-style JSON parser written in portable C89 (sometimes referred to as ANSI C).

  • BSD licensed with no dependencies (i.e. just drop json.c and json.h into your project)
  • Never recurses or allocates more memory than it needs to represent the parsed JSON
  • Very simple API with operator sugar for C++

Build Status

Want to serialize? Check out json-builder!

Installing

There is now a makefile which will produce a libjsonparser static and dynamic library. However, this is not required to build json-parser, and the source files (json.c and json.h) should be happy in any build system you already have in place.

API

json_value * json_parse (const json_char * json,
                         size_t length);

json_value * json_parse_ex (json_settings * settings,
                            const json_char * json,
                            size_t length,
                            char * error);

void json_value_free (json_value *);

The type field of json_value is one of:

  • json_object (see u.object.length, u.object.values[x].name, u.object.values[x].value)
  • json_array (see u.array.length, u.array.values)
  • json_integer (see u.integer)
  • json_double (see u.dbl)
  • json_string (see u.string.ptr, u.string.length)
  • json_boolean (see u.boolean)
  • json_null

Compile-Time Options

Unless otherwise specified, compile definitions must be provided both when compiling json.c and when compiling any of your own source files that include json.h.

JSON_TRACK_SOURCE

Stores the source location (line and column number) inside each json_value.

This is useful for application-level error reporting.

json_int_t

By default, json_int_t is defined as long under C89 and int_fast64_t otherwise. For MSVC it is defined as __int64 regardless of language standard support.

Optionally, you may define json_int_t to be your own preferred type name for integer types parsed from JSON documents. It must be a signed integer type, there is no support for unsigned types. If you specify a raw primitive type without signed or unsigned (and not a typdef), JSON_INT_MAX will be calculated for you. Otherwise, you must provide your own definition of JSON_INT_MAX as the highest positive integer value that can be represented by json_int_t.

Example usage:

  • -Djson_int_t=short
  • "-Djson_int_t=signed char" -DJSON_INT_MAX=127
  • "-Djson_int_t=long long"
  • -Djson_int_t=__int128

Runtime Options

settings |= json_enable_comments;

Enables C-style // line and /* block */ comments.

size_t value_extra

The amount of space (if any) to allocate at the end of each json_value, in order to give the application space to add metadata.

void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);

Custom allocator routines. If NULL, the default malloc and free will be used.

The user_data pointer will be forwarded from json_settings to allow application context to be passed.

Changes in version 1.1.0

  • UTF-8 byte order marks are now skipped if present

  • Allows cross-compilation by honoring --host if given (@wkz)

  • Maximum size for error buffer is now exposed in header (@LB--)

  • GCC warning for static after const fixed (@batrick)

  • Optional support for C-style line and block comments added (@Jin-W-FS)

  • name_length field added to object values

  • It is now possible to retrieve the source line/column number of a parsed json_value when JSON_TRACK_SOURCE is enabled

  • The application may now extend json_value using the value_extra setting

  • Un-ambiguate pow call in the case of C++ overloaded pow (@fcartegnie)

  • Fix null pointer de-reference when a non-existing array is closed and no root value is present

json-builder's People

Contributors

booklearner avatar chromaticisobar avatar dewitt-garmin avatar marcelmeulemans avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-builder's Issues

Could not understand how to use this library

I am not able to understand from the description about how can I use the json-builder to create json files from the software. Can you please post a bit more explanation on how to create JSON files using the functions.

Thanks,
Rohit

push_nocopy object/string bug

If you push an object or string to another json object though any of the noncopy functions, when calling json_builder_free, this function tries to deallocate the .name and .ptr, which have not been allocated in this scenario.

I am posting this from my phone sorry for my brevity.

json_object_merge does not merge

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "json.h"
#include "json-builder.h"

#define R(x...) #x

int main()
{
    const char *json1 = R({"x": 1, "y": 2});
    const char *json2 = R({"y": 3, "z": 4});

    char error[128];
    json_settings settings = {};
    settings.value_extra = json_builder_extra;
    json_value *obj1 = json_parse_ex(&settings, json1, strlen(json1), error);
    json_value *obj2 = json_parse_ex(&settings, json2, strlen(json1), error);

    json_object_merge(obj1, obj2);

    char *buf = malloc(json_measure(obj1));
    json_serialize(buf, obj1);

    printf("buf: `%s'\n", buf);
    return 0;
}
buf: `, "z": 4{ "y": 3, "z": 4 }'

That's odd, isn't it? I think, I was supposed to get {"x": 1, "y": 3, "z": 4"} here. Maybe the function should be rewritten completely using the recursive scheme. I suppose, it must be good to have an ability to merge e.g.

{"arr": [{"id": "1", "data": "A"}, {"id": "2", "data": "B"}]} <+>
{"arr": [{"id": "1", "extra": "@"}, {"id": "2", "data": "Z"}, {"id": "C"}]} ==
{"arr": [{"id": "1", "data": "A", "extra": "@"}, {"id": "2", "data": "Z"}, {"id": "3"}]}

I'll try to take a look on the sources in a couple of days and figure it out.

Is there any way to remove double quotes from the string

I am trying to put a string value in the JSON format but do not want double quotes around the string value, is there any way to remove those double quotes ?
All I want to do is to display a number in Hex format, as I am generating that number in form of a string I have to use the json_string_new method, which results in adding double quotes around that number. It would be great if you can show how to remove double quotes or if you have any dedicated function for displaying Hex values.

Thanks,
Rohit

json_measure seg_faults

I was testing round-triping myself i.e. building up a object, serialize it to char *, parse it again, and then try to print the resulting object. But when I try to allocate buffer for the last object using json_measure, it seg faults.

The testing code is below:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "json.h"
#include "json-builder.h"

json_value *create_entry_obj(char *name, char *data) {
    json_value *obj = json_object_new(0);
    json_object_push(obj, "name", json_string_new(name));
    json_object_push(obj, "data", json_string_new(data));
    json_object_push(obj, "date", json_integer_new(time(NULL)));
    return obj;
}

int main() {
    json_value *arr = json_array_new(0);
    json_array_push(arr, create_entry_obj("name1", "data1"));
    json_array_push(arr, create_entry_obj("name2", "data2"));

    int len = json_measure(arr);
    char *buf = malloc(json_measure(arr));
    json_serialize(buf, arr);
    printf("%s\n", buf);

    json_value *parsed = json_parse(buf, len);
    printf("%d, %lu\n", len, strlen(buf));
    printf("%ld\n", json_measure(parsed));
    char *buf2 = malloc(json_measure(parsed));
    printf("%s\n", buf2);
    
    free(buf);
    free(buf2);
    json_builder_free(arr);
    json_builder_free(parsed);
}

gcc -v:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Lost precision in double values

I would like to use json-builder for a project that sometime has to export time in julian date (as a number of day + fraction of day). The values need to keep a high precision (at least 6 digits after the coma), but currently json-builder doesn't handle this case very well, because the '%g' format used in the code will for example convert "55080.708333" to "55080.7"

I wish there was an option to specify the format used. Maybe a string in json_serialize_opts to override the "%g" ?

Roundtrip fail

Recently I encountered crash on some platform (Ubuntu/gcc-5) during a roundtrip of this JSON:

[-9223372036854775808]

I saved it in valid-0013.json and run the test, which reproduced the problem but did not crash on my machine (OS X El Capitan/clang):

...
Running test: valid-0013.json
measured len: 7
serialized len: 7
serialized:
[ -e ]
Failed to re-parse: 1:0: Expected digit after `e`

I found that several tests in test/main.cc are also failed. I make a note here as well.

...
Running test: valid-0003.json
measured len: 36
serialized len: 36
serialized:
{ "min": -1e+28.0, "max": 1e+28.0 }
Failed to re-parse: 1:0: Unexpected `.` in object
...
Running test: valid-0005.json
measured len: 106
serialized len: 106
serialized:
[ 12.0004, 1.7734, 15, -42, -1.7734, 1e+28.0, -1e+28.0, 1e-28.0, -1e-28.0, -18.3872, -2.1, -1.23457e+06 ]
Failed to re-parse: 1:0: Expected , before .
...
Running test: valid-0008.json
measured len: 59
serialized len: 59
serialized:
[ 400000.0, 4e-07.0, 400000.0, 4e+06.0, 4e-06.0, 4e+06.0 ]
Failed to re-parse: 1:0: Expected , before .
...

BTW, I discovered this during integrating Travis in https://github.com/miloyip/nativejson-benchmark .

Building simple doc leaks memory

The simple CUnit test function below leaks memory when run in Valgrind.
Maybe I'm doing something wrong. Please let me know if I'm doing something wrong or this is a real memory leak. Thanks.

int build_simple_doc_test() {
    json_value * a_doc = json_object_new(0);
    json_value * dh_body = json_object_new(0);
    json_value * host = json_string_new("192.168.1.15");

    json_object_push(dh_body, "host", host);
    json_object_push(a_doc, "DebugHost", dh_body);

    char * buf = malloc(json_measure(a_doc));
    json_serialize(buf, a_doc);

    printf("%s\n", buf);
    free(buf);
    json_builder_free(a_doc);
}

Results from running with

valgrind my_test_app

Suite: json_input_test
  Test: build DebughHost response ...{ "DebugHost": { "host": "192.168.1.15" } }
passed

Run Summary:    Type  Total    Ran Passed Failed Inactive
              suites      1      1    n/a      0        0
               tests      1      1      1      0        0
             asserts      0      0      0      0      n/a

Elapsed time =    0.040 seconds
==16284== 
==16284== HEAP SUMMARY:
==16284==     in use at exit: 5 bytes in 1 blocks
==16284==   total heap usage: 17 allocs, 16 frees, 771 bytes allocated
==16284== 
==16284== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==16284==    at 0x4A0610C: malloc (vg_replace_malloc.c:195)
==16284==    by 0x4066FC: json_object_push_length (json-builder.c:219)
==16284==    by 0x4066B1: json_object_push (json-builder.c:208)
==16284==    by 0x403945: build_simple_doc_test (json_test.c:91)
==16284==    by 0x4C124E4: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
==16284==    by 0x4C1211E: run_single_suite (in /usr/local/lib/libcunit.so.1.0.1)
==16284==    by 0x4C0FA66: CU_run_all_tests (in /usr/local/lib/libcunit.so.1.0.1)
==16284==    by 0x4C14311: basic_run_all_tests (in /usr/local/lib/libcunit.so.1.0.1)
==16284==    by 0x4C140AF: CU_basic_run_tests (in /usr/local/lib/libcunit.so.1.0.1)
==16284==    by 0x404058: main (json_test.c:245)
==16284== 
==16284== LEAK SUMMARY:
==16284==    definitely lost: 5 bytes in 1 blocks
==16284==    indirectly lost: 0 bytes in 0 blocks
==16284==      possibly lost: 0 bytes in 0 blocks
==16284==    still reachable: 0 bytes in 0 blocks
==16284==         suppressed: 0 bytes in 0 blocks
==16284== 
==16284== For counts of detected and suppressed errors, rerun with: -v
==16284== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

json_double_new

When I called json_double_new function gave the double value but it display the exponential value.
For E.g. I Gave double = 534.1256 then it displayed 2.23007e+43

json-builder does not escape strings

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "json-builder.h"

#define R(x...) #x

int main()
{
    const char *json = R({"s": "a\"b\"c"});

    char error[128];
    json_settings settings = {};
    settings.value_extra = json_builder_extra;
    json_value *obj = json_parse_ex(&settings, json, strlen(json), error);

    char *buf = malloc(json_measure(obj));
    json_serialize(buf, obj);

    printf("`%s' vs. `%s'\n", json, buf);
    return 0;
}
`{"s": "a\"b\"c"}' vs. `{ "s": "a"b"c" }'

That's me again ๐Ÿ˜€ The library as you can see does not escape strings producing invalid JSON. I think, "\n", "\t" are worth escaping too. Nevertheless, "\u..." are not.

Error when serializing sub object

I am trying to parse a json file (using json.h) and then serialize a sub object of it using json-builder, but I get some strange results.

In this simple example, my input data is:

{ "data": {"x": 10}}

And I try to serialize {"x": 10}, but instead I get:

{ "x": 10 }{ "data": { "x": 10 } }

Here is the code, compiled on linux with gcc:

#include "json-builder.h"
#include <string.h>
#include <stdio.h>

static const char *JSON = "{\"data\": {\"x\":10}}";

int main()
{
    char err[128];
    char *buf;
    json_value *value, *data;
    json_settings settings = {};
    settings.value_extra = json_builder_extra;
    value = json_parse_ex(&settings, JSON, strlen(JSON), err);
    data = value->u.object.values[0].value;
    buf = malloc(json_measure(data));
    json_serialize(buf, data);
    printf("%s\n", buf);
    free(buf);
    json_builder_free(value);
}

Duplicate objects are allowed

Duplicate objects with same keys(names) are accepted and added at the end instead of replacing existing ones.

RFC 7159: says

The names within an object SHOULD be unique.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.