#ifndef _JSON_H_ #define _JSON_H_ #include #include struct json { char *key; size_t index; enum json_type { JSON_NULL = 0, JSON_BOOL = 1 << 0, JSON_STRING = 1 << 1, JSON_NUMBER = 1 << 2, JSON_OBJECT = 1 << 3, JSON_ARRAY = 1 << 4, } type; union { struct json_children { size_t nitems, maxitems; struct json *items[]; } *children; char *string; double num; bool boolean; }; struct json *parent; struct json *prev, *next; }; enum json_parse_result { JSON_PARSE_OK, JSON_PARSE_INVALID_TOKEN_ERR, JSON_PARSE_EXPECTED_VALUE_ERR, JSON_PARSE_OBJECT_EXPECTED_VALUE_ERR, JSON_PARSE_OBJECT_INVALID_KEY_ERR, JSON_PARSE_MAX_DEPTH_ERR, JSON_PARSE_INVALID_NUMBER_ERR, JSON_PARSE_INVALID_STRING_ERR, JSON_PARSE_STRING_INVALID_ESCAPE_ERR, JSON_PARSE_STRING_INVALID_UNICODE_ERR, JSON_PARSE_STRING_INVALID_ERR, JSON_OOM }; struct json *json_parse(const char *str); struct json *json_parse_sized(size_t len, const char str[len]); struct json *json_new(void); struct json *json_dup(const struct json *src); void json_clear(struct json *json); void json_detach(struct json *json); void json_delete(struct json *json); size_t json_len(const struct json *json); /* ====== json object ====== */ struct json *json_object(void); #define json_get(obj, key) _Generic((obj), \ struct json *: json_get_mut, \ const struct json *: json_get_const \ )((obj), (key)) #define json_get_sized(obj, len, key) _Generic((obj), \ struct json *: json_get_sized_mut, \ const struct json *: json_get_sized_const \ )((obj), (len), (key)) struct json *json_get_mut(struct json *obj, const char key[]); struct json *json_get_sized_mut(struct json *obj, size_t len, const char key[len]); const struct json *json_get_const(const struct json *obj, const char key[]); const struct json *json_get_sized_const(const struct json *obj, size_t len, const char key[len]); struct json *json_set(struct json *dest, const char *key, struct json *src); //struct json *json_set_sized(struct json *dest, size_t len, const char key[len], struct json *src); struct json *json_detach_key(struct json *json, const char *key); struct json *json_swap_key(struct json *json, const char *key, struct json *src); void json_delete_key(struct json *json, const char *key); struct json *json_detach_key_sized(struct json *json, size_t len, const char key[len]); struct json *json_swap_key_sized(struct json *json, size_t len, const char key[len], struct json *src); void json_delete_key_sized(struct json *json, size_t len, const char key[len]); /* ====== json array ====== */ struct json *json_array(void); //struct json *json_array_from(size_t count, struct json *array[count]); bool json_append(struct json *dest, struct json *src); bool json_insert(struct json *dest, size_t index, struct json *src); bool json_replace(struct json *dest, size_t index, struct json *src); #define json_at(obj, index) _Generic((obj), \ struct json *: json_at_mut, \ const struct json *: json_at_const \ )((obj), (index)) struct json *json_at_mut(struct json *array, size_t index); const struct json *json_at_const(const struct json *array, size_t index); struct json *json_detach_index(struct json *json, size_t index); struct json *json_swap_index(struct json *json, size_t index, struct json *src); void json_delete_index(struct json *json, size_t index); /* ====== json string ====== */ struct json *json_string(const char *string); struct json *json_string_from(char *string); #define json_string_get(string) _Generic((string), \ struct json *: json_string_get_mut, \ const struct json *: json_string_get_const \ )(string) char *json_string_get_mut(struct json *string); const char *json_string_get_const(const struct json *string); void json_string_set(struct json *dest, const char *string); /* ====== json literals ====== */ struct json *json_number(double number); struct json *json_bool(bool boolean); char *json_print(struct json *json); #define json_foreach(e, o) \ for (struct json *e = json_check_type((o), JSON_OBJECT | JSON_ARRAY) ? (o)->children->items[0] : NULL; e; e = e->next) static inline bool json_check_type(const struct json *json, const enum json_type type) { return json && json->type & type; } static inline bool json_is_object(const struct json *json) { return json && json->type == JSON_OBJECT; } static inline bool json_is_array(const struct json *json) { return json && json->type == JSON_ARRAY; } static inline bool json_is_number(const struct json *json) { return json && json->type == JSON_NUMBER; } static inline bool json_is_string(const struct json *json) { return json && json->type == JSON_STRING; } static inline bool json_is_bool(const struct json *json) { return json && json->type == JSON_BOOL; } static inline bool json_is_null(const struct json *json) { return json && json->type == JSON_NULL; } #endif