From 06fa452c96c86b8218bd11974346acb03a924998 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Sun, 20 Oct 2019 23:22:11 +0200 Subject: [PATCH] Add a full native JSON parser to Kore. Mostly compliant, ignores \uXXXX in strings for now. New API functions: void kore_json_init(struct kore_json *json, const u_int8_t *data, size_t len); - Prepares JSON data for parsing. int kore_json_parse(struct kore_json *json) - Parses the JSON data prepared via kore_json_init. Returns KORE_RESULT_ERROR if parsing failed or KORE_RESULT_OK if it succeeded. struct kore_json_item *kore_json_get(struct kore_json *json, const char *path, int type); - Try to find the object matching a given search patch and type. eg, given a JSON structure of: { "reasons": { "strings": [ "first reason", "second" ] } } one can obtain the second element in the reasons.strings array via: item = kore_json_get(json, "reasons/strings[0]", KORE_JSON_TYPE_STRING); Returns NULL if the item was not found or a type mismatch was hit, otherwise will return the item of that type. The kore_json_item data structure has a data member that contains the relevant bits depending on the type: KORE_JSON_TYPE_ARRAY, KORE_JSON_TYPE_OBJECT: the data.items member is valid. KORE_JSON_TYPE_STRING: the data.string member is valid. KORE_JSON_TYPE_NUMBER: the data.number member is valid. KORE_JSON_TYPE_LITERAL: the data.literal member is valid. void kore_json_cleanup(struct kore_json *json); - Cleanup any resources const char *kore_json_strerror(struct kore_json *json); - Return pointer to human readable error string. --- Makefile | 4 +-- include/kore/kore.h | 77 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e86e52a..7cf6594 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ PLATFORM=platform.h VERSION=src/version.c S_SRC= src/kore.c src/buf.c src/config.c src/connection.c \ - src/domain.c src/filemap.c src/fileref.c src/mem.c src/msg.c \ - src/module.c src/net.c src/pool.c src/runtime.c src/timer.c \ + src/domain.c src/filemap.c src/fileref.c src/json.c src/mem.c \ + src/msg.c src/module.c src/net.c src/pool.c src/runtime.c src/timer.c \ src/utils.c src/worker.c src/keymgr.c $(VERSION) FEATURES= diff --git a/include/kore/kore.h b/include/kore/kore.h index 390c9ef..c1e3e0b 100644 --- a/include/kore/kore.h +++ b/include/kore/kore.h @@ -464,6 +464,76 @@ struct kore_buf { size_t offset; }; +#define KORE_JSON_TYPE_OBJECT 1 +#define KORE_JSON_TYPE_ARRAY 2 +#define KORE_JSON_TYPE_STRING 3 +#define KORE_JSON_TYPE_NUMBER 4 +#define KORE_JSON_TYPE_LITERAL 5 + +#define KORE_JSON_FALSE 0 +#define KORE_JSON_TRUE 1 +#define KORE_JSON_NULL 2 + +#define KORE_JSON_DEPTH_MAX 10 + +#define KORE_JSON_ERR_NONE 0 +#define KORE_JSON_ERR_INVALID_OBJECT 1 +#define KORE_JSON_ERR_INVALID_ARRAY 2 +#define KORE_JSON_ERR_INVALID_STRING 3 +#define KORE_JSON_ERR_INVALID_NUMBER 4 +#define KORE_JSON_ERR_INVALID_LITERAL 5 +#define KORE_JSON_ERR_DEPTH 6 +#define KORE_JSON_ERR_EOF 7 +#define KORE_JSON_ERR_INVALID_JSON 8 +#define KORE_JSON_ERR_INVALID_SEARCH 9 +#define KORE_JSON_ERR_NOT_FOUND 10 +#define KORE_JSON_ERR_TYPE_MISMATCH 11 +#define KORE_JSON_ERR_LAST KORE_JSON_ERR_TYPE_MISMATCH + +#define kore_json_object(j, p) \ + kore_json_get(j, p, KORE_JSON_TYPE_OBJECT) + +#define kore_json_array(j, p) \ + kore_json_get(j, p, KORE_JSON_TYPE_ARRAY) + +#define kore_json_string(j, p) \ + kore_json_get(j, p, KORE_JSON_TYPE_STRING) + +#define kore_json_number(j, p) \ + kore_json_get(j, p, KORE_JSON_TYPE_NUMBER) + +#define kore_json_literal(j, p) \ + kore_json_get(j, p, KORE_JSON_TYPE_LITERAL) + +struct kore_json { + const u_int8_t *data; + int depth; + int error; + size_t length; + size_t offset; + + struct kore_buf tmpbuf; + struct kore_json_item *root; +}; + +struct kore_json_item { + int type; + char *name; + struct kore_json_item *parent; + + union { + TAILQ_HEAD(, kore_json_item) items; + char *string; + double number; + int literal; + } data; + + int (*parse)(struct kore_json *, + struct kore_json_item *); + + TAILQ_ENTRY(kore_json_item) list; +}; + struct kore_pool_region { void *start; size_t length; @@ -874,6 +944,13 @@ void kore_buf_appendv(struct kore_buf *, const char *, va_list); void kore_buf_replace_string(struct kore_buf *, const char *, const void *, size_t); +int kore_json_parse(struct kore_json *); +void kore_json_cleanup(struct kore_json *); +void kore_json_init(struct kore_json *, const u_int8_t *, size_t); + +const char *kore_json_strerror(struct kore_json *); +struct kore_json_item *kore_json_get(struct kore_json *, const char *, int); + void kore_keymgr_run(void); void kore_keymgr_cleanup(int);