diff options
-rw-r--r-- | json.c | 12 | ||||
-rw-r--r-- | json.h | 10 | ||||
-rw-r--r-- | test_json.c | 24 |
3 files changed, 43 insertions, 3 deletions
@@ -63,6 +63,7 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a char valbuf[JSON_VAL_MAX+1], *pval = NULL; const struct json_attr_t *cursor; int substatus, maxlen; + const struct json_enum_t *mp; /* stuff fields with defaults in case they're omitted in the JSON input */ for (cursor = attrs; cursor->attribute != NULL; cursor++) @@ -228,6 +229,8 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a maxlen = cursor->len - 1; else if (cursor->type == check) maxlen = strlen(cursor->dflt.check); + else if (cursor->map != NULL) + maxlen = sizeof(valbuf)-1; if (*cp == '"') { *pval = '\0'; #ifdef JSONDEBUG @@ -260,6 +263,15 @@ static int json_internal_read_object(const char *cp, const struct json_attr_t *a *pval++ = *cp; break; case post_val: + if (cursor->map != 0) { + for (mp = cursor->map; mp->name != NULL; mp++) + if (strcmp(mp->name, valbuf) == 0) { + goto foundit; + } + return JSON_ERR_BADENUM; + foundit: + (void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value); + } if (parent == NULL || parent->element_type != structobject) { /* ordinary case - use the address in the cursor structure */ switch(cursor->type) @@ -9,6 +9,11 @@ typedef enum {integer, uinteger, real, string, boolean, character, #define nullbool -1 /* not true, not false */ +struct json_enum_t { + char *name; + int value; +}; + struct json_array_t { json_type element_type; union { @@ -48,6 +53,7 @@ struct json_attr_t { char *check; } dflt; size_t len; + const struct json_enum_t *map; }; #define JSON_ATTR_MAX 31 /* max chars in JSON attribute name */ @@ -74,8 +80,8 @@ const char *json_error_string(int); #define JSON_ERR_BADSTRING 15 /* error while string parsing */ #define JSON_ERR_CHECKFAIL 16 /* check attribute not matched */ #define JSON_ERR_NOPARSTR 17 /* can't support strings in parallel arrays */ -#define JSON_ERR_MISC 18 /* other data conversion error */ - +#define JSON_ERR_BADENUM 18 /* invalid enumerated value */ +#define JSON_ERR_MISC 19 /* other data conversion error */ /* * Use the following macros to declare template initializers for structobject diff --git a/test_json.c b/test_json.c index 82b78175..c0aeac10 100644 --- a/test_json.c +++ b/test_json.c @@ -109,7 +109,7 @@ static const char *json_str4 = "{\"flag1\":true,\"flag2\":false}"; static bool flag1, flag2; static double dftreal; static int dftinteger; -static int dftuinteger; +static unsigned int dftuinteger; static const struct json_attr_t json_attrs_4[] = { {"dftint", integer, .addr.integer = &dftinteger, .dflt.integer = -5}, @@ -168,6 +168,21 @@ static const char *json_str7 = "{\"class\":\"VERSION\",\ \"release\":\"2.40dev\",\"rev\":\"dummy-revision\",\ \"api_major\":3,\"api_minor\":1}"; +/* Case 8: test parsing arrays of enumerated types */ + +const char *json_str8 = "{\"fee\":\"FOO\",\"fie\":\"BAR\",\"foe\":\"BAZ\"}"; +const struct json_enum_t enum_table[] = { + {"BAR", 6}, {"FOO", 3}, {"BAZ", 14}, {NULL} +}; + +static int fee, fie, foe; +static const struct json_attr_t json_attrs_8[] = { + {"fee", integer, .addr.integer = &fee, .map=enum_table}, + {"fie", integer, .addr.integer = &fie, .map=enum_table}, + {"foe", integer, .addr.integer = &foe, .map=enum_table}, + {NULL}, +}; + #endif /* GPSDNG_ENABLE */ int main(int argc UNUSED, char *argv[] UNUSED) @@ -244,6 +259,13 @@ int main(int argc UNUSED, char *argv[] UNUSED) assert_string("rev", gpsdata.version.rev, "dummy-revision"); assert_integer("api_major", gpsdata.version.api_major, 3); assert_integer("api_minor", gpsdata.version.api_minor, 1); + + status = json_read_object(json_str8, json_attrs_8, NULL); + assert_case(8, status); + assert_integer("fee", fee, 3); + assert_integer("fie", fie, 6); + assert_integer("foe", foe, 14); + #endif /* GPSDNG_ENABLE */ (void)fprintf(stderr, "succeeded.\n"); |