C library for parsing JSON config files
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
example
include
src
test
.gitignore
CHANGELOG.md
CMakeLists.txt
COPYING
README.md

README.md

Relaxed Streaming JSON Parser C Library

Differences from RFC 4627

  • unquoted keys
  • single quotes '
  • // and /* */ style comments
  • extra commas , in arrays and objects

Why?

Official JSON is almost human-readable and human-writable. If we disable a few of the strict rules, we can make it significantly more so.

You would use this library when parsing user input, such as a config file. You would not use this library when serializing or deserializing, or as a format for computer-to-computer communication.

I could not find another JSON parser that fit all of these requirements:

  • C library
  • Relaxed parsing rules as outlined above. As a rule of thumb the parser should be compatible with GYP.
  • Streaming - ability to not buffer the entire JSON string in memory before parsing it.
  • In Debian/Ubuntu's package repository or at least scheduled to be in it.

So I wrote one that satisfies all these requirements. It has a test suite and is already in use by another project. It has been uploaded to Debian and is scheduled to be released in "jessie" and Ubuntu 14.10 Utopic Unicorn.

Usage

See include/laxjson.h for more details.

#include <laxjson.h>
#include <stdio.h>

static int on_string(struct LaxJsonContext *context,
    enum LaxJsonType type, const char *value, int length)
{
    const char *type_name = type == LaxJsonTypeProperty ? "property" : "string";
    printf("%s: %s\n", type_name, value);
    return 0;
}

static int on_number(struct LaxJsonContext *context, double x) {
    printf("number: %f\n", x);
    return 0;
}

static int on_primitive(struct LaxJsonContext *context, enum LaxJsonType type) {
    const char *type_name;
    if (type == LaxJsonTypeTrue)
        type_name = "true";
    else if (type == LaxJsonTypeFalse)
        type_name = "false";
    else
        type_name = "null";

    printf("primitive: %s\n", type_name);
    return 0;
}

static int on_begin(struct LaxJsonContext *context, enum LaxJsonType type) {
    const char *type_name = (type == LaxJsonTypeArray) ? "array" : "object";
    printf("begin %s\n", type_name);
    return 0;
}

static int on_end(struct LaxJsonContext *context, enum LaxJsonType type) {
    const char *type_name = (type == LaxJsonTypeArray) ? "array" : "object";
    printf("end %s\n", type_name);
    return 0;
}

int main() {
    char buf[1024];
    struct LaxJsonContext *context;
    FILE *f;
    int amt_read;
    enum LaxJsonError err;

    context = lax_json_create();

    context->userdata = NULL; /* can set this to whatever you want */
    context->string = on_string;
    context->number = on_number;
    context->primitive = on_primitive;
    context->begin = on_begin;
    context->end = on_end;

    f = fopen("file.json", "rb");
    while ((amt_read = fread(buf, 1, sizeof(buf), f))) {
        if ((err = lax_json_feed(context, amt_read, buf))) {
            fprintf(stderr, "Line %d, column %d: %s\n",
                    context->line, context->column, lax_json_str_err(err));
            return -1;
        }
        lax_json_feed(context, amt_read, buf);
    }
    if ((err = lax_json_eof(context))) {
        fprintf(stderr, "Line %d, column %d: %s\n",
                context->line, context->column, lax_json_str_err(err));
        return -1;
    }
    lax_json_destroy(context);

    return 0;
}

Installation

Pre-Built Packages

  • Ubuntu PPA

    sudo apt-add-repository ppa:andrewrk/rucksack
    sudo apt-get update
    sudo apt-get install liblaxjson-dev
    

From Source

mkdir build
cd build
cmake ..
make
sudo make install

To run the tests, use make test.

Projects Using liblaxjson

Feel free to make a pull request adding to this list.

  • rucksack - a texture packer and resource bundler
  • Genesis - digital audio workstation