#include #include #include #include #include #include #include "internal.h" #include #include #include struct json *json_parse(const char *str) { return json_parse_len(str, strlen(str)); } struct json *json_new(void) { struct json *json = calloc(1, sizeof(*json)); if (!json) return NULL; json->type = JSON_INVALID; return json; } void json_detach(struct json *json) { if (!json || !json->parent) return; struct json_children *siblings = json->parent->children; if (json->index != --siblings->nitems) { struct json *tmp; for (size_t i = json->index; i < siblings->nitems; i++) { tmp = siblings->items[i] = siblings->items[i + 1]; tmp->index = i; tmp->prev = i > 0 ? siblings->items[tmp->index - 1] : NULL; tmp->next = i < siblings->nitems ? siblings->items[tmp->index + 1] : NULL; } } json->parent = NULL; } void json_delete(struct json *json) { if (!json) return; json_detach(json); json_clear(json); free(json); } void json_clear(struct json *json) { if (!json) return; switch (json->type) { case JSON_OBJECT: case JSON_ARRAY: for (size_t i = 0; i < json->children->nitems; i++) { json_clear(json->children->items[i]); free(json->children->items[i]); } free(json->children); break; case JSON_STRING: free(json->string); break; default: break; } free(json->key); json->type = JSON_INVALID; } struct json *json_new_array(void) { struct json *json = json_new(); if (!json) return NULL; json->type = JSON_ARRAY; init_children(json); return json; } struct json *json_new_bool(bool boolean) { struct json *json = json_new(); if (!json) return NULL; json->type = boolean ? JSON_TRUE : JSON_FALSE; return json; } struct json *json_new_null(void) { struct json *json = json_new(); if (!json) return NULL; json->type = JSON_NULL; return json; } struct json *json_new_number(double num) { struct json *json = json_new(); if (!json) return NULL; json->type = JSON_NUMBER; json->num = num; return json; } struct json *json_new_string(void) { struct json *json = json_new(); if (!json) return NULL; json->type = JSON_STRING; json->string = NULL; return json; } struct json *json_new_string_copy(const char *string) { struct json *json = json_new(); if (!json) return NULL; json->type = JSON_STRING; json->string = strdup(string); return json; } enum json_parse_result parse_value(struct json **json_out, struct raw_json *raw, size_t depth) { skip_ws(raw); struct json *json = NULL; enum json_parse_result ret = JSON_PARSE_OK; switch (raw->data[raw->index]) { case '"': ret = parse_string(&json, raw); break; case '{': ret = parse_object(&json, raw, depth); break; case '[': ret = parse_array(&json, raw, depth); break; default: ret = parse_literal(&json, raw); break; } *json_out = json; return ret; } struct json *json_parse_len(const char *str, size_t size) { if (!str || size == 0) return NULL; struct json *json = NULL; struct raw_json raw = { .index = 0, .data = str, .size = size }; if (parse_value(&json, &raw, 1) != JSON_PARSE_OK) { return NULL; }; skip_ws(&raw); if (raw.index != raw.size) { json_delete(json); return NULL; } return json; }