Utility functions and test program for JSON processing.

This commit is contained in:
Stephen Heumann 2019-04-10 15:30:40 -05:00
parent 20345b436d
commit 07472f7391
3 changed files with 100 additions and 0 deletions

34
jsonutil.c Normal file
View File

@ -0,0 +1,34 @@
#include <string.h>
#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;
}

24
jsonutil.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef JSONUTIL_H
#define JSONUTIL_H
#include "json.h"
#ifdef __ORCAC__
#include <types.h>
#else
#include <stdbool.h>
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

42
test.c Normal file
View File

@ -0,0 +1,42 @@
#pragma lint -1
#include <stdio.h>
#include <string.h>
#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);
}