Yet Another JSON Library (YAJL)
1.0.5
- Author:
- Lloyd Hilaiel
- Date:
- 2007-2009
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style) JSON parser written in ANSI C, and a small validating JSON generator. YAJL is released under the BSD license.
- Stream (incremental) parsing and generation of JSON
- ANSI C
- Human readable error messages with context
- tiny
- event driven
- support for generating "beautified" JSON
The following code sample is a complete JSON "reformating" program. It demonstrates how to perform stream parsing and generation.
#include <yajl/yajl_parse.h>
#include <yajl/yajl_gen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int reformat_null(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_null(g);
return 1;
}
static int reformat_boolean(void * ctx, int boolean)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_bool(g, boolean);
return 1;
}
static int reformat_number(void * ctx, const char * s, unsigned int l)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_number(g, s, l);
return 1;
}
static int reformat_string(void * ctx, const unsigned char * stringVal,
unsigned int stringLen)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_string(g, stringVal, stringLen);
return 1;
}
static int reformat_map_key(void * ctx, const unsigned char * stringVal,
unsigned int stringLen)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_string(g, stringVal, stringLen);
return 1;
}
static int reformat_start_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_map_open(g);
return 1;
}
static int reformat_end_map(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_map_close(g);
return 1;
}
static int reformat_start_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_array_open(g);
return 1;
}
static int reformat_end_array(void * ctx)
{
yajl_gen g = (yajl_gen) ctx;
yajl_gen_array_close(g);
return 1;
}
static yajl_callbacks callbacks = {
reformat_null,
reformat_boolean,
NULL,
NULL,
reformat_number,
reformat_string,
reformat_start_map,
reformat_map_key,
reformat_end_map,
reformat_start_array,
reformat_end_array
};
static void
usage(const char * progname)
{
fprintf(stderr, "usage: %s <filename>\n"
" -m minimize json rather than beautify (default)\n"
" -u allow invalid UTF8 inside strings during parsing\n",
progname);
exit(1);
}
int
main(int argc, char ** argv)
{
yajl_handle hand;
static unsigned char fileData[65536];
yajl_gen_config conf = { 1, " " };
yajl_gen g;
yajl_status stat;
size_t rd;
yajl_parser_config cfg = { 1, 1 };
int done = 0;
if (argc == 2) {
if (!strcmp("-m", argv[1])) {
conf.beautify = 0;
} else if (!strcmp("-u", argv[1])) {
cfg.checkUTF8 = 0;
} else {
usage(argv[0]);
}
} else if (argc != 1) {
usage(argv[0]);
}
g = yajl_gen_alloc(&conf, NULL);
hand = yajl_alloc(&callbacks, &cfg, NULL, (void *) g);
while (!done) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
if (rd == 0) {
if (!feof(stdin)) {
fprintf(stderr, "error on file read.\n");
break;
}
done = 1;
}
fileData[rd] = 0;
if (done)
stat = yajl_parse_complete(hand);
else
stat = yajl_parse(hand, fileData, rd);
if (stat != yajl_status_ok &&
stat != yajl_status_insufficient_data)
{
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, (const char *) str);
yajl_free_error(hand, str);
} else {
const unsigned char * buf;
unsigned int len;
yajl_gen_get_buf(g, &buf, &len);
fwrite(buf, 1, len, stdout);
yajl_gen_clear(g);
}
}
yajl_gen_free(g);
yajl_free(hand);
return 0;
}