mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-01 09:58:42 -05:00
150 lines
15 KiB
C
150 lines
15 KiB
C
/* -------- Assemble json --------
|
|
Assemble is a high performance C library for loading and saving JSON files. Unlike other JSON parsers it doesnt convert numbers in to doubles but retains values decimal format in order to avoid loss of precission. */
|
|
|
|
#ifndef uint
|
|
typedef unsigned int uint;
|
|
#endif
|
|
#ifndef uint8
|
|
typedef unsigned char uint8;
|
|
#endif
|
|
#ifndef int64
|
|
typedef signed long long int64;
|
|
#endif
|
|
|
|
typedef enum{
|
|
A_JT_BOOLEAN = 0,
|
|
A_JT_NUMBER = 1,
|
|
A_JT_STRING = 2,
|
|
A_JT_OBJECT = 3,
|
|
A_JT_ARRAY = 4,
|
|
A_JT_NULL = 5,
|
|
A_JT_MODULO = 6, /**/
|
|
A_JT_FALSE = A_JT_BOOLEAN + A_JT_MODULO * 0,
|
|
A_JT_TRUE = A_JT_BOOLEAN + A_JT_MODULO * 1,
|
|
A_JT_NUMBER_FLOAT = A_JT_NUMBER + A_JT_MODULO * 0,
|
|
A_JT_NUMBER_DOUBLE = A_JT_NUMBER + A_JT_MODULO * 1,
|
|
A_JT_NUMBER_DECIMAL = A_JT_NUMBER + A_JT_MODULO * 2,
|
|
A_JT_MULTIPLE = -1
|
|
}AJsonType;
|
|
|
|
#define A_JT_NUMBER_INTEGER (A_JT_NUMBER + A_JT_MODULO * 3)
|
|
|
|
typedef struct{
|
|
int64 integer;
|
|
uint8 decimal;
|
|
}AJsonDecimalNumber;
|
|
|
|
typedef uint AJasonArrayCount;
|
|
|
|
#define ASSEMBLE_JSON_ENABLE_DEVELOPER_ERRORS /* Enables errors to be cought and printed out when ever the API is beeing used wrong. If disabled, using the API wrong may cause undefined behaviour. */
|
|
#define ASSEMBLE_JSON_ENABLE_RUNTIME_ERRORS /* Enables errors to be caught and reported during runtime if malloc fails. */
|
|
|
|
#ifndef ASSEMBLE_INTERNAL
|
|
|
|
typedef struct _AJsonValue AJsonValue;
|
|
typedef struct _AJsonMember AJsonMember;
|
|
|
|
/* -------- Parsing json --------
|
|
*/
|
|
|
|
extern AJsonValue *assemble_json_parse(char *string, int write_protected, AJsonType number_type); /* parses a string of json and creates a tree structure of AJasonValues. If write_protected, the Parsing and the resulting tree will be significantly faster but not modifyable. "number_type" needs to be a A_JT_NUMBER_FLOAT, a A_JT_NUMBER_DOUBLE or a A_JT_NUMBER_DECIMAL, and will specify how parsed numbers are stored internaly. All numberd values can be read read/written using nmber get/set function disregarding of how it is stored internally. */
|
|
extern AJsonValue *assemble_json_parse_single_pass(char *string, uint string_length, int write_protected, AJsonType number_type); /* parses a string of json and creates a tree structure of AJasonValues. If write_protected, the Parsing and the resulting tree will be significantly faster but not modifyable. "number_type" needs to be a A_JT_NUMBER_FLOAT, a A_JT_NUMBER_DOUBLE or a A_JT_NUMBER_DECIMAL, and will specify how parsed numbers are stored internaly. All numberd values can be read read/written using number get/set function disregarding of how it is stored internally. This version of the parser forgoes any validation and will crash if the json string is in any way broken. The implementation will allocate lagest possible memory footprint, estimated from the "string_length" parameter, and will therfor be very memory wastefull. */
|
|
extern AJsonValue *assemble_json_clone(AJsonValue *value); /* Closes a Value and all it children. The resulting structure is not write protected. */
|
|
extern void assemble_json_free(AJsonValue *value); /* Free a Value. If the value tree is write protected only can be root can be freed. */
|
|
|
|
/* -------- Printing json --------
|
|
*/
|
|
|
|
extern uint assemble_json_print_size(AJsonValue *value, uint indentation); /* Computes the number of bytes needed to store the resulting JSON generated by a value tree (without termination). The param "indentation" indicates the number of tabs added to each line of jason (usualy 0). */
|
|
extern uint assemble_json_print(char *array, AJsonValue *value, uint indentation); /* Writes out JSON generated by a value tree to the pointer "array". The resulting array is not null terminatred. Use assemble_json_print_size to make sure enough memory is available to write out the entire structure. The param "indentation" indicates the number of tabs added to each line of jason (usualy 0). */
|
|
extern char *assemble_json_print_allocate(AJsonValue *value); /* Allocates enough memory and writes out JSON generated by a value tree and returns the pointer. The user of this function is responsible for freeing the array. The array is null terminated. */
|
|
|
|
/* -------- Decimal --------
|
|
*/
|
|
|
|
#define ASSEMBLE_JSON_DECIMAL_PRINT_MAX (256 + 1 + 1) /* 256 decimals one comma and one minus */
|
|
|
|
extern uint assemble_json_decimal_parce(char *text, int64 *real_output, uint8 *decimal); /* Parses a sring of numbers as a 64 bit integer coupled with a decimal point stored as a 8bit value.*/
|
|
extern double assemble_json_decimal_to_double(int64 real_output, uint8 decimal); /* Convets a 64 bit integer coupled with a 8bit decimal in to a double.*/
|
|
extern void assemble_json_decimal_from_double(double input, int64 *real_output, uint8 *decimal);/* Convets a double in to a 64 bit integer coupled with a 8bit decimal.*/
|
|
extern uint assemble_json_decimal_print(char *text, int64 integer, uint8 decimal); /* Print out the decimal number to the "text" pointer. The function does not terminate the string. The text param needs to have enough space to store the printed number either by using ASSEMBLE_JSON_DECIMAL_PRINT_MAX or by querying assemble_json_decimal_print_size. Returns the size in number of bytes. */
|
|
extern uint assemble_json_decimal_print_size(int64 integer, uint8 decimal); /* Computes the precise number of bytes needed to print out a decimal number. */
|
|
|
|
/* -------- Value -------- */
|
|
|
|
extern AJsonValue *assemble_json_value_allcoate(AJsonType type, double number, char *string); /* Allocates a value of type "type" and returns it. If the value is of type A_JT_NUMBER, the "number" param will be used to set its value. If the value is of type A_JT_STRING, the "string" param will be used to set its value. */
|
|
extern AJsonType assemble_json_value_type_get(AJsonValue *value); /* Returns the type of a value. Note that by moduloing the output of this function with A_JT_MODULO it is possible to turn all A_JT_TRUE and A_JT_FALSE in to A_JT_BOLLEAN and all A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE and A_JT_NUMBER_DECIMAL in to A_JT_NUMBER. */
|
|
|
|
/* -------- String Value -------- */
|
|
|
|
extern char *assemble_json_value_string_get(AJsonValue *value); /* Returns a poiner to a text string of the value if of type A_JT_STRING . */
|
|
extern uint assemble_json_value_string_set(AJsonValue *value, char *string); /* Sets the text string of the value to a copy if "string", if of type A_JT_STRING . */
|
|
|
|
/* -------- Number API -------- */
|
|
|
|
extern float assemble_json_value_number_get_float(AJsonValue *value); /* Returns a float of the value if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern uint assemble_json_value_number_set_float(AJsonValue *value, float number); /* Sets the float of the value to "number", if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern double assemble_json_value_number_get_double(AJsonValue *value); /* Returns a double of the value if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern uint assemble_json_value_number_set_double(AJsonValue *value, double number); /* Sets the double of the value to "number", if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern int64 assemble_json_value_number_get_integer(uint8 *value); /* Returns a int64 of the value if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern void assemble_json_value_number_get_decimal(AJsonValue *value, AJsonDecimalNumber *decimal); /* Fills out a AJsonDecimalNumber of the value if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
extern uint assemble_json_value_number_set_decimal(AJsonValue *value, AJsonDecimalNumber *decimal);/* Sets the AJsonDecimalNumber of the value to "decimal", if of type A_JT_NUMBER, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, or A_JT_NUMBER_DECIMAL. */
|
|
|
|
/* -------- True/False -------- */
|
|
|
|
extern void assemble_json_value_set_true_false(AJsonValue *value, int boolean_value); /* Sets a value to true or false, if its either of type A_JT_TRUE or A_JT_FALSE */
|
|
|
|
/* -------- Object -------- */
|
|
|
|
extern AJsonValue *assemble_json_object_member_add(AJsonValue *object, AJsonValue *value, char *name); /* Attaches a value as a member to a value object, under the name "name". the function will returned an updated pointer to the value beeing inserted. */
|
|
extern AJsonValue *assemble_json_object_member_add_create(AJsonValue *object, char *name, AJsonType type, void *data); /* Creates a new value and inserts it to a object value under the name "name". The new value will be of type "type". If the value is of type A_JT_NUMBER, the "number" param will be used to set its value. If the value is of type A_JT_STRING, the "string" param will be used to set its value. The function will return a pointer to the new object.*/
|
|
extern AJsonValue *assemble_json_object_member_add_boolean_create(AJsonValue *object, char *name, int boolean_value);
|
|
extern AJsonValue *assemble_json_object_member_add_float_create(AJsonValue *object, char *name, float value);
|
|
extern AJsonValue *assemble_json_object_member_add_double_create(AJsonValue *object, char *name, double value);
|
|
extern AJsonValue *assemble_json_object_member_add_decimal_create(AJsonValue *object, char *name, int64 integer, uint8 decimal);
|
|
|
|
extern AJsonMember *assemble_json_object_member_get_first(AJsonValue *value); /* Returns the first member of a value of type A_JT_OBJECT */
|
|
extern AJsonMember *assemble_json_object_member_get_next(AJsonMember *object); /* Returns the next m ember of a object of A_JT_OBJECT following "object". Will return NULL if its the last member. */
|
|
extern char *assemble_json_object_member_get_name(AJsonMember *object); /* Returns the name of a member. */
|
|
extern AJsonValue *assemble_json_object_member_get_value(AJsonMember *object); /* returns the value of a member. */
|
|
extern AJsonMember *assemble_json_object_member_search_name_get_member(AJsonValue *value, char *name, uint type); /* Searches a value of type A_JT_OBJECT for the first member of name "name" and type "type". If type is set to -1, assemble_json_object_member_search_name_get_member will return any member with a matching name. The function returns a pointer to the member or NULL if no matching member is found.*/
|
|
extern AJsonValue *assemble_json_object_member_search_name_get_value(AJsonValue *value, char *name, uint type); /* Searches a value of type A_JT_OBJECT for the first member of name "name" and type "type". If type is set to -1, assemble_json_object_member_search_name_get_member will return any value with a matching name. The function returns a pointer to the value or NULL if no matching member is found.*/
|
|
extern AJsonValue *assemble_json_object_member_search_name_detach_value(AJsonValue *value, char *name, uint type); /* Searches a value of type A_JT_OBJECT for the first member of name "name" and type "type". If type is set to -1, assemble_json_object_member_search_name_get_member will return any value with a matching name. If a matching value is found it is detached from the object and a pointer to the value is returned. NULL is returned if no matching member is found.*/
|
|
extern int assemble_json_object_member_search_name_delete_value(AJsonValue *value, char *name, uint type); /* Searches a value of type A_JT_OBJECT for the first member of name "name" and type "type". If type is set to -1, assemble_json_object_member_search_name_delete_value will delete any value with a matching name. If a matching value is found it is deleted from the object and TRUE returned. FALSE is returned if no matching member is found.*/
|
|
extern int assemble_json_object_member_search_name_enum_test(AJsonValue *value, char *name, char **enum_names, uint enum_count, uint *output); /* Searches a value of type A_JT_OBJECT for the first member of name "name". If the type is a string, it tries to match it with an array of strings. Return true if a matching string is found. */
|
|
|
|
|
|
extern char *assemble_json_object_member_search_name_get_string(uint8 *value, char *name);
|
|
extern size_t assemble_json_object_member_search_name_get_string_copy(uint8 *value, char *name, char *buffer, size_t buffer_size);
|
|
extern float assemble_json_object_member_search_name_get_float(uint8 *value, char *name, float default_value);
|
|
extern double assemble_json_object_member_search_name_get_double(uint8 *value, char *name, float default_value);
|
|
extern void assemble_json_object_member_search_name_get_decimal(uint8 *value, char *name, AJsonDecimalNumber *decimal);
|
|
extern int64 assemble_json_object_member_search_name_get_integer(uint8 *value, char *name, int64 default_value);
|
|
extern int assemble_json_object_member_search_name_get_boolean(uint8 *value, char *name, int default_value);
|
|
|
|
|
|
/* -------- Array -------- */
|
|
|
|
extern AJasonArrayCount assemble_json_value_array_get_length(AJsonValue *value); /* Returns the number of elements in the ARRAY. */
|
|
extern int assemble_json_value_array_first_get_uniform(AJsonValue *value); /* Returns TRUE if all members of the array are of the same type. (A_JT_TRUE and A_JT_FALSE are considerd the same type.) */
|
|
extern AJsonType assemble_json_value_array_first_get_uniform_type(AJsonValue *value); /* Returns the type of the members of the array, or A_JT_MULTIPLE if array contaings multiple different types. (A_JT_TRUE and A_JT_FALSE are considerd the same type.) */
|
|
extern int assemble_json_value_array_uniform_verify(AJsonValue *array); /* */
|
|
|
|
extern AJsonValue *assemble_json_value_array_first_get(AJsonValue *array_value); /* Get the first membert in an array. Retunrns Null if the array is empty.*/
|
|
extern AJsonValue *assemble_json_value_array_add(AJsonValue *array, AJsonValue *insert, AJsonValue *after); /* Adds the value "insert" to the array. If "after is set to NULL", the insert will be added to the front of the array. If "after" is not NULL, it has to be a value that is already a member of the array, and the "insert" will be places after the "after" value in the array.*/
|
|
|
|
extern AJsonValue *assemble_json_value_array_add_to_create(AJsonValue *array, AJsonValue *after, AJsonType type, void *data); /* Creates a new value and inserts it to a object value under the name "name". The new value will be of type "type". If the value is of type A_JT_NUMBER, the "number" param will be used to set its value. If the value is of type A_JT_STRING, the "string" param will be used to set its value. The function will return a pointer to the new object.*/
|
|
extern void *assemble_json_value_array_get_allocate(AJsonValue *array, AJsonType output_array_type, uint *length); /* Allocates an array of A_JT_BOOLEAN, A_JT_STRING, A_JT_NUMBER_FLOAT, A_JT_NUMBER_DOUBLE, A_JT_NUMBER_DECIMAL */
|
|
|
|
|
|
extern AJsonType assemble_json_value_get_is_array_member(AJsonValue *value); /* Returns A_JT_TRUE if the value is a memebr of an array and A_JT_FALSE if it is not. */
|
|
extern AJsonValue *assemble_json_value_get_next(AJsonValue *previous); /* get the next member of an array. Returns NULL if the end of the array is reached. */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|