From e079370a92766181ff5281c5d6cea03a1fce5b93 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Fri, 5 Jan 2024 22:51:33 +0100 Subject: initial release Signed-off-by: Anna (navi) Figueiredo Gomes --- src/object.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/object.c (limited to 'src/object.c') diff --git a/src/object.c b/src/object.c new file mode 100644 index 0000000..b380008 --- /dev/null +++ b/src/object.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include "internal.h" + +//inline static size_t hash(const char *key) { + //if (!key) + //return 0; + //size_t ret = 5381; + //for (const char *p = key; *p != '\0'; p++) { + //ret = ((ret << 5) + ret) + *p; + //} + //return ret; +//} + +void add_to_object(struct json *dest, char *key, struct json *src) { + assert(dest->type == JSON_OBJECT); + assert(key); + assert(src); + + src->key = (free(src->key), key); + //src->index = hash(src->key) % dest->children->maxitems; + + for (size_t i = 0; i < dest->children->nitems; i++) { + struct json *e = dest->children->items[i]; + if (strcmp(e->key, key) == 0) { + src->index = e->index; + dest->children->items[i] = src; + + adjust_pointers(e, src); + json_delete(e); + return; + } + } + + add_children(dest, src); +} + +struct json *json_new_object(void) { + struct json *json = json_new(); + json->type = JSON_OBJECT; + init_children(json); + return json; +} + +enum json_parse_result parse_object(struct json **json_out, struct raw_json *raw, size_t depth) { + assert(raw->data[raw->index] == '{'); + enum json_parse_result ret = JSON_PARSE_OK; + struct json *json = NULL; + struct json *obj = NULL; + char *key = NULL; + bool empty = true; + + if (depth++ > 9) { + ret = JSON_PARSE_MAX_DEPTH_ERR; + goto err; + } + + json = json_new_object(); + if (!json) + return JSON_OOM; + + do { + raw->index++; + skip_ws(raw); + + if (raw->data[raw->index] == '}') { + if (empty) { + break; + } + ret = JSON_PARSE_EXPECTED_VALUE_ERR; + goto err; + } + + if (raw->data[raw->index] != '"') { + ret = JSON_PARSE_OBJECT_INVALID_KEY_ERR; + goto err; + } + ret = parse_raw_string(&key, raw); + if (ret != JSON_PARSE_OK) { + goto err; + } + skip_ws(raw); + + if (raw->data[raw->index] != ':') { + ret = JSON_PARSE_OBJECT_EXPECTED_VALUE_ERR; + goto err; + } + + raw->index++; + skip_ws(raw); + + ret = parse_value(&obj, raw, depth); + if (ret != JSON_PARSE_OK) { + goto err; + } + + add_to_object(json, key, obj); + empty = false; + skip_ws(raw); + + obj = NULL; + key = NULL; + } while (raw->index < raw->size && raw->data[raw->index] == ','); + + if (raw->data[raw->index] != '}') { + ret = JSON_PARSE_INVALID_TOKEN_ERR; + goto err; + } + raw->index++; + + *json_out = json; + goto end; +err: + json_clear(json); + json_clear(obj); + +end: + return ret; +} + +bool json_object_add(struct json *dest, const char *key, struct json *src) { + if (!dest || !key || !src) + return false; + add_to_object(dest, strdup(key), src); + return true; +} + +struct json *json_object_get(const struct json *obj, const char *key) { + if (obj->type != JSON_OBJECT) return NULL; + struct json *j = NULL; + json_foreach(j, obj) { + if (strcmp(j->key, key) == 0) + break; + } + return j; +} + +struct json *json_object_getn(const struct json *obj, const char *key, size_t n) { + if (obj->type != JSON_OBJECT) return NULL; + struct json *j = NULL; + json_foreach(j, obj) { + if (strncmp(j->key, key, n) == 0) + break; + } + return j; +} + +struct json *json_object_add_object(struct json *dest, const char *key) { + struct json *obj = json_new_object(); + json_object_add(dest, key, obj); + return obj; +} + +struct json *json_object_add_array(struct json *dest, const char *key) { + struct json *array = json_new_array(); + json_object_add(dest, key, array); + return array; +} +struct json *json_object_add_number(struct json *dest, const char *key, double num) { + struct json *number = json_new_number(num); + json_object_add(dest, key, number); + return number; +} + +struct json *json_object_add_string(struct json *dest, const char *key, const char *string) { + struct json *str = json_new_string_copy(string); + json_object_add(dest, key, str); + return str; +} + +struct json *json_object_add_bool(struct json *dest, const char *key, bool boolean) { + struct json *b = json_new_bool(boolean); + json_object_add(dest, key, b); + return b; +} + +struct json *json_object_add_null(struct json *dest, const char *key) { + struct json *n = json_new_null(); + json_object_add(dest, key, n); + return n; +} + +struct json *json_object_detach(struct json *json, const char *key) { + struct json *tmp = json_object_get(json, key); + json_detach(tmp); + return tmp; +} +void json_object_delete(struct json *json, const char *key) { + struct json *tmp = json_object_detach(json, key); + json_delete(tmp); +} -- cgit v1.2.3