144 lines
3.4 KiB
C
144 lines
3.4 KiB
C
#ifndef JSON_H
|
|
#define JSON_H
|
|
|
|
enum json_type {
|
|
JSON_TYPE_INVALID,
|
|
|
|
JSON_TYPE_STRING,
|
|
JSON_TYPE_NULL,
|
|
JSON_TYPE_BOOL,
|
|
JSON_TYPE_ARRAY,
|
|
JSON_TYPE_OBJECT,
|
|
JSON_TYPE_NUMBER
|
|
};
|
|
|
|
struct json_object_entry;
|
|
|
|
struct json_ir_parent_data {
|
|
u32 child_count;
|
|
struct json_ir *child_first;
|
|
struct json_ir *child_last;
|
|
};
|
|
|
|
/* Intermediate representation of JSON hierarchy tree in memory. Used for mutating
|
|
* JSON in parsing stage or for creating new objects. Should be manipulated via the
|
|
* API. */
|
|
struct json_ir {
|
|
enum json_type type;
|
|
struct json_ir *next_child;
|
|
struct string key;
|
|
union {
|
|
struct json_ir_parent_data children;
|
|
b32 boolean;
|
|
struct string string;
|
|
f64 number;
|
|
} val;
|
|
};
|
|
|
|
/* Final representation of JSON hierarchy. Should be manipulated via the API. */
|
|
struct json_val {
|
|
enum json_type type;
|
|
u32 child_count;
|
|
union {
|
|
void *object_table;
|
|
struct json_val *array_children;
|
|
b32 boolean;
|
|
struct string *string;
|
|
f64 number;
|
|
} val;
|
|
};
|
|
|
|
struct json_object_entry {
|
|
struct string key;
|
|
struct json_val value;
|
|
};
|
|
|
|
/* Parse */
|
|
const struct json_ir *json_parse(struct arena *arena, struct buffer bytes, struct string **error);
|
|
|
|
/* Format */
|
|
const struct json_val *json_format(struct arena *arena, const struct json_ir *ir);
|
|
const struct json_val *json_parse_and_format(struct arena *arena, struct buffer bytes, struct string **error);
|
|
|
|
/* Index */
|
|
const struct json_val *json_array_get(const struct json_val *a, u32 index);
|
|
const struct json_val *json_object_get(const struct json_val *obj, struct string key);
|
|
const struct json_object_entry *json_object_get_index(const struct json_val *obj, u32 index);
|
|
|
|
/* Dump */
|
|
struct string json_dump_to_string(struct arena *arena, const struct json_val *val, u32 indent);
|
|
|
|
/* Write */
|
|
struct json_ir *json_ir_object(struct arena *arena);
|
|
struct json_ir *json_ir_number(struct arena *arena, f64 n);
|
|
struct json_ir *json_ir_bool(struct arena *arena, b32 b);
|
|
struct json_ir *json_ir_object_set(struct json_ir *obj, struct string key, struct json_ir *value);
|
|
|
|
/* ========================== *
|
|
* Type util
|
|
* ========================== */
|
|
|
|
INLINE b32 json_is_object(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_OBJECT;
|
|
}
|
|
|
|
INLINE b32 json_is_string(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_STRING;
|
|
}
|
|
|
|
INLINE b32 json_is_number(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_NUMBER;
|
|
}
|
|
|
|
INLINE b32 json_is_array(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_ARRAY;
|
|
}
|
|
|
|
INLINE b32 json_is_bool(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_BOOL;
|
|
}
|
|
|
|
INLINE b32 json_is_null(const struct json_val *v)
|
|
{
|
|
return v && v->type == JSON_TYPE_NULL;
|
|
}
|
|
|
|
/* ========================== *
|
|
* Val util
|
|
* ========================== */
|
|
|
|
INLINE struct string json_string(const struct json_val *v)
|
|
{
|
|
ASSERT(json_is_string(v));
|
|
return *v->val.string;
|
|
}
|
|
|
|
INLINE f64 json_number(const struct json_val *v)
|
|
{
|
|
ASSERT(json_is_number(v));
|
|
return v->val.number;
|
|
}
|
|
|
|
INLINE b32 json_bool(const struct json_val *v)
|
|
{
|
|
ASSERT(json_is_bool(v));
|
|
return v->val.boolean;
|
|
}
|
|
|
|
/* ========================== *
|
|
* Parent util
|
|
* ========================== */
|
|
|
|
INLINE u32 json_child_count(const struct json_val *v)
|
|
{
|
|
ASSERT(json_is_object(v) || json_is_array(v));
|
|
return v->child_count;
|
|
}
|
|
|
|
#endif
|