summaryrefslogtreecommitdiff
path: root/src/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.c')
-rw-r--r--src/object.c193
1 files changed, 193 insertions, 0 deletions
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 <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <json.h>
+#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);
+}