diff --git a/jsonutil.c b/jsonutil.c new file mode 100644 index 0000000..e56e37f --- /dev/null +++ b/jsonutil.c @@ -0,0 +1,34 @@ +#include +#include "jsonutil.h" + +json_value *findEntryInObject(json_value *obj, json_char *name, json_type type) { + if (obj == NULL || obj->type != json_object) + return NULL; + json_object_entry *entry = obj->u.object.values; + for (unsigned int i = 0; i < obj->u.object.length; i++,entry++) { + if (entry->name_length != strlen(name)) { + continue; + } + if (memcmp(name, entry->name, entry->name_length) == 0) { + if (entry->value->type == type) + return entry->value; + else + return NULL; + } + } + return NULL; +} + + +boolean processArray(json_value *arr, json_type member_type, boolean (*f)(json_value*)) { + if (arr == NULL || arr->type != json_array) + return false; + for (unsigned int i = 0; i < arr->u.array.length; i++) { + json_value *v = arr->u.array.values[i]; + if (v->type != member_type) + continue; + if (f(v) == false) + return false; + } + return true; +} diff --git a/jsonutil.h b/jsonutil.h new file mode 100644 index 0000000..c3919cc --- /dev/null +++ b/jsonutil.h @@ -0,0 +1,24 @@ +#ifndef JSONUTIL_H +#define JSONUTIL_H + +#include "json.h" + +#ifdef __ORCAC__ +#include +#else +#include +typedef _Bool boolean; +#endif + +/* + * Find an entry with specified name and type in a json object. + */ +json_value *findEntryInObject(json_value *obj, json_char *name, json_type type); + +/* + * Call f on each member of type member_type in a json array. + * Stops and returns false if any call to f returns false. + */ +boolean processArray(json_value *arr, json_type member_type, boolean (*f)(json_value*)); + +#endif diff --git a/test.c b/test.c new file mode 100644 index 0000000..31cb4b5 --- /dev/null +++ b/test.c @@ -0,0 +1,42 @@ +#pragma lint -1 + +#include +#include +#include "json.h" +#include "jsonutil.h" + +char jsonData[] = "{\"responseHeader\":{\"status\":0,\"QTime\":10,\"params\":{\"query\":\"emulator:apple2gs\",\"qin\":\"emulator:apple2gs\",\"fields\":\"identifier,title\",\"wt\":\"json\",\"rows\":\"3\",\"json.wrf\":\"callback\",\"start\":0}},\"response\":{\"numFound\":2428,\"start\":0,\"docs\":[{\"identifier\":\"TypeWest_disk_1_no_boot\",\"title\":\"TypeWest disk 1 (no boot)\"},{\"identifier\":\"a2gs_mindshadow\",\"title\":\"Mindshadow\"},{\"identifier\":\"a2gs_Impossible_Mission_II_1989_Epyx_a\",\"title\":\"Apple IIgs: Impossible Mission II (1989)(Epyx)[a]\"}]}}"; + + +boolean processDoc(json_value *docObj) { + if (docObj == NULL || docObj->type != json_object) + return false; + json_value *id = findEntryInObject(docObj, "identifier", json_string); + json_value *title = findEntryInObject(docObj, "title", json_string); + if (id == NULL || title == NULL) + return true; + printf("Document:\n"); + printf(" id = %s\n", id->u.string.ptr); + printf(" title = %s\n", title->u.string.ptr); + return true; +} + + +int main(void) { + json_value *value = json_parse(jsonData, sizeof(jsonData)-1); + + if (value == NULL) + return -1; + + json_value *response = findEntryInObject(value, "response", json_object); + + json_value *numFound = findEntryInObject(response, "numFound", json_integer); + if (numFound != NULL) { + printf("numFound = %li\n", (long)numFound->u.integer); + } + + json_value *docs = findEntryInObject(response, "docs", json_array); + processArray(docs, json_object, processDoc); + + json_value_free(value); +}