#ifndef _JSON_H_ #define _JSON_H_ #include #include struct json { char *key; size_t index; enum { JSON_FALSE, JSON_TRUE, JSON_OBJECT, JSON_ARRAY, JSON_STRING, JSON_NUMBER, JSON_NULL, JSON_INVALID } type; union { struct json_children { size_t nitems, maxitems; struct json *items[]; } *children; char *string; double num; }; 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_len(size_t size, const char str[size]); struct json *json_new(void); void json_clear(struct json *json); void json_detach(struct json *json); void json_delete(struct json *json); /* ====== json object ====== */ struct json *json_new_object(void); #define json_object_get(obj, key) _Generic((obj), \ struct json *: json_object_get_mut, \ const struct json *: json_object_get_const \ )((obj), (key)) #define json_object_getn(obj, key, n) _Generic((obj), \ struct json *: json_object_getn_mut, \ const struct json *: json_object_getn_const \ )((obj), (key), (n)) struct json *json_object_get_mut(struct json *obj, const char *key); struct json *json_object_getn_mut(struct json *obj, const char *key, size_t n); const struct json *json_object_get_const(const struct json *obj, const char *key); const struct json *json_object_getn_const(const struct json *obj, const char *key, size_t n); bool json_object_add(struct json *dest, const char *key, struct json *src); struct json *json_object_add_object(struct json *dest, const char *key); struct json *json_object_add_array(struct json *dest, const char *key); struct json *json_object_add_number(struct json *dest, const char *key, double num); struct json *json_object_add_string(struct json *dest, const char *key, const char *string); struct json *json_object_add_bool(struct json *dest, const char *key, bool boolean); struct json *json_object_add_null(struct json *dest, const char *key); struct json *json_object_detach(struct json *json, const char *key); void json_object_delete(struct json *json, const char *key); /* ====== json array ====== */ struct json *json_new_array(void); bool json_array_append(struct json *dest, struct json *src); #define json_array_get(obj, index) _Generic((obj), \ struct json *: json_array_get_mut, \ const struct json *: json_array_get_const \ )((obj), (index)) struct json *json_array_get_mut(struct json *array, size_t index); const struct json *json_array_get_const(const struct json *array, size_t index); struct json *json_array_add_object(struct json *dest); struct json *json_array_add_array(struct json *dest); struct json *json_array_add_number(struct json *dest, double num); struct json *json_array_add_string(struct json *dest, const char *string); struct json *json_array_add_bool(struct json *dest, bool boolean); struct json *json_array_add_null(struct json *dest); struct json *json_array_detach(struct json *json, size_t index); void json_array_delete(struct json *json, size_t index); /* ====== json string ====== */ struct json *json_new_string(void); struct json *json_new_string_copy(const char *string); char *json_string_get(const 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_new_number(double number); struct json *json_new_bool(bool boolean); struct json *json_new_null(void); char *json_print(struct json *json); #define json_foreach(e, o) \ for (e = json_is_object(o) || json_is_array(o) ? o->children->items[0] : NULL; e; e = e->next) static inline bool json_is_object(struct json *json) { return json && json->type == JSON_OBJECT; } static inline bool json_is_array(struct json *json) { return json && json->type == JSON_ARRAY; } static inline bool json_is_number(struct json *json) { return json && json->type == JSON_NUMBER; } static inline bool json_is_string(struct json *json) { return json && json->type == JSON_STRING; } static inline bool json_is_bool(struct json *json) { return json && (json->type == JSON_TRUE || json->type == JSON_FALSE); } static inline bool json_is_null(struct json *json) { return json && json->type == JSON_NULL; } #endif