Awesome
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
-
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
- lua-laxjson - Lua bindings