kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 06fa452c96c86b8218bd11974346acb03a924998
parent 7da7141c21a880ff3503e231676d0962a2553959
Author: Joris Vink <joris@coders.se>
Date:   Sun, 20 Oct 2019 23:22:11 +0200

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.

Diffstat:
Makefile | 4++--
include/kore/kore.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 2 deletions(-)

diff --git 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 @@ -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);