JSON done almost dangerously.
Enum: Scalar, Object, Array. Thing type.
Enum: String, Doble (Double), Truthval. Scalar type.
Key-value pair for an object lookup. Fields: char *key, thing_t *val. To construct:
pair_t *pa = new_pair((char *)key, (thing_t *_val);
Enum: True, False, Null
An all-purpose type. Always has one field: type_t type. Either Scalar, Array, or Object. Depending on type, its (used) fields should vary.
Recursively destroys a thing_t * instance.
del_thing((thing_t *)t);
Access function:
sa(scal, field)
To construct:
thing_t *scal = new_scal((char *)stringval, (stype_t)stype);
Note that you must independently assign a value to one of the scalar's value fields, described below.
Field: char *string.
Fields: double doble, int exp.
Fields:
truthval_t truthval.
Access function:
aa(arr, field)
To construct:
thing_t *arr = new_arr(maxlength); // maxlength means nothing right now
Arrays are variable length and grow to accomodate new entries. Add elements to end:
addelem(array, thing);
Index array:
thing_t *val = getarrval(array, index);
Access function: oa(obj, field) To construct:
thing_t *obj = new_obj(maxlength); // maxlength means nothing right now
Objects are also variable length and accomodate new key/value pairs. Adding an entry:
addkv(object, pair);
Looking up an entry:
thing_t *found = getobjval(object, lookupstr);
Prints full newlines and two-space indentation.
Prints no newlines or indentation, good for using the fewest bytes possible.
To compile a printer that prints in a certain mode, compile with:
-D X_PRINT // X is one of PRETTY and COMPACT
Or define X_PRINT before including jdad.h.
You can also provide a mode (Pretty or Compact) to the printer_t constructor. This will be somewhat slower than the compile-time mode choice, but it will provide greater flexibility in printing.
JSON printer. To construct:
printer_t *prin = new_printer((FILE *)outstream, // Or NULL - defaults to stdout
(printmode_t)mode); // Pretty or Compact; defaults to Pretty
To destroy:
del_printer(prin);
Note that you have to close the outstream on your own with:
close_ostream(prin);
General, simple print function.
print_thing((printer_t *)p, (thing_t*)th);
parser_t *p = new_parser((char *)filename_to_open);
Populates p->data with the next thing_t * constructed from the file.
register thing_t *result;
while (parse((parser_t *)p))
{
result = p->data;
// Do something with result
}
Note that you must del_thing() each result because they are not stored or automatically freed.
Destroys all the resources of the parser.
parser_quit((parser_t *)p);
In parse.c, the main() function shows an example usage of the parser. It simply reads in the contents of the file indicated by its first command line argument, creates data structures for it, and prints them. By itself it could be used to prettify JSON. It also prints out memory statistics. Its code:
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "no filename supplied.\n");
exit(-1);
}
parser_t *p = new_parser(argv[1]);
printer_t *print = new_printer(NULL);
unsigned int level = 0, ctr = 0;
register thing_t *t;
while (parse(p))
{
t = p->data;
fprintf(stderr, "[%d]\n", ctr++);
print_thing(print, t);
del_thing(t);
}
del_printer(print);
parser_quit(p);
fprintf(stderr, "MEM STATS:\n");
fprintf(stderr, "Allocs: %d\nBytes: %d\n", malloc_c, mem_c);
fprintf(stderr, "Frees: %d\n", free_c);
return 0;
}