F4MP/f4mp_originalcode/thirdparty/zpl/code/header/json.h

186 lines
6.1 KiB
C
Raw Normal View History

// file: header/json.h
/** @file json.c
@brief JSON5 Parser/Writer
@defgroup json JSON5 parser/writer
Easy to use and very fast JSON5 parser that can easily load 50 megabytes of JSON content under half a second. It also contains simple JSON5 writer and acts as a good library for handling config files. The parser also supports the **Simplified JSON (SJSON)** format.
We can parse JSON5 files in two different modes:
@n 1) Fast way (useful for raw data), which can not handle comments and might cause parsing failure if comment is present.
@n 2) Slower way (useful for config files), which handles comments perfectly but **might** have performance impact
on bigger JSON files. (+50MiB)
@{
*/
#ifdef ZPL_EDITOR
#include <zpl.h>
#endif
ZPL_BEGIN_C_DECLS
//! Debug mode
#ifdef ZPL_JSON_DEBUG
#define ZPL_JSON_ASSERT ZPL_ASSERT(0)
#else
#define ZPL_JSON_ASSERT
#endif
//! JSON object types
typedef enum zpl_json_type {
ZPL_JSON_TYPE_OBJECT,
ZPL_JSON_TYPE_STRING,
ZPL_JSON_TYPE_MULTISTRING,
ZPL_JSON_TYPE_ARRAY,
ZPL_JSON_TYPE_INTEGER,
ZPL_JSON_TYPE_REAL,
ZPL_JSON_TYPE_CONSTANT
} zpl_json_type;
//! Field value properties
typedef enum zpl_json_props {
ZPL_JSON_PROPS_NONE = 0,
ZPL_JSON_PROPS_NAN = 1,
ZPL_JSON_PROPS_NAN_NEG = 2,
ZPL_JSON_PROPS_INFINITY = 3,
ZPL_JSON_PROPS_INFINITY_NEG = 4,
ZPL_JSON_PROPS_IS_EXP = 5,
ZPL_JSON_PROPS_IS_HEX = 6,
// Used internally so that people can fill in real numbers for JSON files they plan to write.
ZPL_JSON_PROPS_IS_PARSED_REAL = 7,
} zpl_json_props;
//! Value constants
typedef enum zpl_json_const {
ZPL_JSON_CONST_FALSE,
ZPL_JSON_CONST_TRUE,
ZPL_JSON_CONST_NULL,
} zpl_json_const;
// TODO(ZaKlaus): Error handling
//! Parser error types
typedef enum zpl_json_error {
ZPL_JSON_ERROR_NONE,
ZPL_JSON_ERROR_INVALID_NAME,
ZPL_JSON_ERROR_INVALID_VALUE,
ZPL_JSON_ERROR_OBJECT_OR_SOURCE_WAS_NULL,
} zpl_json_error;
//! Field name decoration style
typedef enum zpl_json_naming_style {
ZPL_JSON_NAME_STYLE_DOUBLE_QUOTE,
ZPL_JSON_NAME_STYLE_SINGLE_QUOTE,
ZPL_JSON_NAME_STYLE_NO_QUOTES,
} zpl_json_naming_style;
//! Field value assign style
typedef enum zpl_json_assign_style {
ZPL_JSON_ASSIGN_STYLE_COLON,
ZPL_JSON_ASSIGN_STYLE_EQUALS,
ZPL_JSON_ASSIGN_STYLE_LINE,
} zpl_json_assign_style;
//! Field delimiter style
typedef enum zpl_json_delim_style {
ZPL_JSON_DELIM_STYLE_COMMA,
ZPL_JSON_DELIM_STYLE_LINE,
ZPL_JSON_DELIM_STYLE_NEWLINE,
} zpl_json_delim_style;
#define zpl_json_object zpl_json_object
//! JSON object definition.
typedef struct zpl_json_object {
zpl_allocator backing;
char *name;
zpl_u8 type :6;
zpl_u8 name_style :2;
zpl_u8 props :7;
zpl_u8 cfg_mode :1;
zpl_u8 assign_style:4;
zpl_u8 delim_style :4;
zpl_u8 delim_line_width;
union {
struct zpl_json_object *nodes; ///< zpl_array
zpl_i64 integer;
char *string;
struct {
zpl_f64 real;
zpl_i32 base;
zpl_i32 base2;
zpl_i32 base2_offset;
zpl_i32 exp;
zpl_u8 exp_neg :1;
zpl_u8 lead_digit:1;
};
zpl_u8 constant;
};
} zpl_json_object;
//! Parses JSON5/SJSON text.
//! This method takes text form of JSON document as a source and parses its contents into JSON object structure we can work with. It also optionally handles comments that usually appear in documents used for configuration.
//! @param root JSON object we store data to.
//! @param len Text length. (reserved)
//! @param source Text to be processed.
//! @param allocator Memory allocator to use. (ex. zpl_heap())
//! @param handle_comments Whether to handle possible comments or not. Note that if we won't handle comments in a document containing them, the parser will error out. See remark in source code.
//! @param err_code Variable we will store error code in.
ZPL_DEF void zpl_json_parse(zpl_json_object *root, zpl_usize len, char const *source, zpl_allocator allocator, zpl_b32 handle_comments,
zpl_u8 *err_code);
//! Exports JSON5 document into text form and outputs it into a file.
//! This method takes JSON object tree and exports it into valid JSON5 form with the support of various styles that were preserved during import or set up programatically.
//! @param file File we write text to.
//! @param obj JSON object we export data from.
//! @param indent Text indentation used during export. Use 0 for root objects.
ZPL_DEF void zpl_json_write(zpl_file *file, zpl_json_object *obj, zpl_isize indent);
//! Releases used resources by a JSON object.
//! @param obj JSON object to free.
ZPL_DEF void zpl_json_free(zpl_json_object *obj);
//! Searches for a JSON node within a document by its name.
//! @param obj JSON object to search in.
//! @param name JSON node's name to search for.
//! @param deep_search Perform the search recursively.
ZPL_DEF zpl_json_object *zpl_json_find(zpl_json_object *obj, char const *name, zpl_b32 deep_search);
//! Initializes a JSON node.
//! @param obj JSON node to initialize.
//! @param backing Memory allocator to use (ex. zpl_heap())
//! @param name JSON node's name.
//! @param type JSON node's type. (See zpl_json_type)
//! @see zpl_json_type
ZPL_DEF void zpl_json_init_node(zpl_json_object *obj, zpl_allocator backing, char const *name, zpl_u8 type);
//! Adds object into JSON document at a specific index.
//! Initializes and adds a JSON object into a JSON document at a specific index.
//! @param obj Root node to add to.
//! @param index Index to store at.
//! @param name JSON node's name.
//! @param type JSON node's type. (See zpl_json_type)
//! @see zpl_json_type
ZPL_DEF zpl_json_object *zpl_json_add_at(zpl_json_object *obj, zpl_isize index, char const *name, zpl_u8 type);
//! Appends object into JSON document.
//! Initializes and appends a JSON object into a JSON document.
//! @param obj Root node to add to.
//! @param name JSON node's name.
//! @param type JSON node's type. (See zpl_json_type)
//! @see zpl_json_type
ZPL_DEF zpl_json_object *zpl_json_add(zpl_json_object *obj, char const *name, zpl_u8 type);
//! @}
ZPL_END_C_DECLS