rjp/doc/api
2020-04-09 14:53:18 -07:00

622 lines
17 KiB
Plaintext

/**
rjp
Copyright (C) 2018-2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Control how rjp_to_json outputs
*/
typedef enum RJP_format_flag{
RJP_FORMAT_NONE = 0,
RJP_FORMAT_KEY_SPACES = 1,
RJP_FORMAT_NEWLINES = 2,
RJP_FORMAT_TABBED_LINES = RJP_FORMAT_NEWLINES | 4,
RJP_FORMAT_COMMA_SPACES = 8,
RJP_FORMAT_PRETTY = RJP_FORMAT_KEY_SPACES | RJP_FORMAT_NEWLINES | RJP_FORMAT_TABBED_LINES
}RJP_format_flag;
/*
* Control what extensions are allowed in rjp_parse
*/
typedef enum RJP_parse_flag{
RJP_PARSE_NO_EXT = 0,
RJP_PARSE_ALLOW_COMMENTS = 1,
RJP_PARSE_ALLOW_TRAILING_COMMA = 2,
RJP_PARSE_ALL_EXT = RJP_PARSE_ALLOW_COMMENTS | RJP_PARSE_ALLOW_TRAILING_COMMA
}RJP_parse_flag;
/*
* Different data types allowed in JSON. Used to determine
* what type a given RJP_value holds.
*/
typedef enum RJP_data_type{
rjp_json_object = 1,
rjp_json_ordered_object = 3,
rjp_json_string = 2,
rjp_json_integer = 4,
rjp_json_dfloat = 8,
rjp_json_boolean = 16,
rjp_json_array = 32,
rjp_json_null = 64
}RJP_data_type;
/*
* Represent a C string
@member value: NULL terminated C string
@member length: Length of value excluding NULL terminator
*/
typedef struct RJP_string{
char* value;
RJP_index length;
}RJP_string;
/*
* Used to iterate over object members
* Members should NOT be accessed directly by user
*/
typedef struct RJP_object_iterator{
union{
struct RJP_object_iterator_impl* it;
RJP_value* current;
};
RJP_data_type type;
}RJP_object_iterator;
/*
* Used to iterate over array elements
* Members should NOT be accessed directly by user
*/
typedef struct RJP_array_iterator{
RJP_value* current;
}RJP_array_iterator;
/*
* Information needed by rjp_parse_cback
@member read: callback to read JSON string from.
required to retun number of bytes read.
@member data: data to be passed to read callback function
*/
typedef struct RJP_parse_callback{
int(*read)(char*,int,void*);
void* data;
}RJP_parse_callback;
/*
* Retains enough information from a parse run to construct an error message and where the error occurred.
@member parsestate: internal use only
@member errcode: enumeration of what the error was
@member row: what row of the input contained the error
@member column: where in the row that the error occurred
*/
typedef struct RJP_parse_error{
void* parsestate;
int errcode;
int row, column;
}RJP_parse_error;
/***************** NON OBJECT OPERATIONS *******************/
/*
* Allocate heap space for rjp to use. Use if the memory is to be freed
* by rjp
@param nbytes: number of bytes to allocate
@returns: pointer to newly allocated memory
*/
void* rjp_alloc(RJP_index nbytes);
/*
* Allocate heap space for rjp and initialize to 0.
@param num: number of elements to allocate
@param nbytes: number of bytes per element
@returns: pointer to newly allocated memory
*/
void* rjp_calloc(RJP_index num, RJP_index nbytes);
/*
* Free memory allocated by rjp_alloc or rjp_calloc
@param dest: memory to free
*/
void rjp_free(void* dest);
/*
* copy input string and add json escape sequences
@param dest: output buffer
@param src: source string
@returns: length of string in dest excluding NULL terminator
*/
RJP_index rjp_escape_strcpy(char* dest, const char* src);
/*
* length of string after escaping
@param src: string to measure
@returns: length of escaped string excluding NULL terminator
*/
RJP_index rjp_escape_strlen(const char* str);
/*
* copy input string and add json escape sequences
@param src: source string
@returns: newly allocated string copy
*/
RJP_string rjp_escape(const char* src);
/***************** GENERIC OPERATIONS *******************/
/*
* Convert C string of json data into RJP's format using no extensions and without
error reporting.
@param str: input JSON
@returns: pointer to root value or NULL on failure
*/
RJP_value* rjp_simple_parse(const char* str);
/*
* Convert C string consisting of json data into RJP's format
@param str: input JSON
@param flags: RJP_parse_flags OR'd together
@returns: pointer to root value or NULL on failure
*/
RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err);
/*
* Read json data in using a user supplied callback and convert
* it to RJP's format
@param flags: RJP_parse_flags OR'd together
@param cbacks: RJP_parse_callback with function/data used for reading
@returns: pointer to root value or NULL on failure
*/
RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cbacks, RJP_parse_error* err);
/*
* Allocate a string representing the error stored in RJP_parse_error structure
@param err: pointer to error to stringify
@returns: rjp_alloc'd pointer to string describing the error.
Must be freed with rjp_free
*/
char* rjp_parse_error_to_string(const RJP_parse_error* err);
/*
* Cleanup a RJP_parse_error structure when finished
Note: DO NOT call if rjp_parse* was successful. Error will contain garbage data and
will cause a segfault.
@param err: pointer to error which needs cleanup
*/
void rjp_delete_parse_error(RJP_parse_error* err);
/*
* Convert RJP's representation to rjp_alloc'd JSON string
@param root: RJP_value to print out
@param pretty: RJP_format_flag on how to print
@returns: rjp_alloc'd string with JSON data or NULL on error
*/
char* rjp_to_json(const RJP_value* root, int pretty);
/*
* Create new RJP_value of null type
@returns: are you stupid?
*/
RJP_value* rjp_new_null(void);
/*
* Create new RJP_value of int type
@param val: really?
@returns: are you stupid?
*/
RJP_value* rjp_new_int(RJP_int val);
/*
* Create new RJP_value of float type
@param val: really?
@returns: are you stupid?
*/
RJP_value* rjp_new_float(RJP_float val);
/*
* Create new RJP_value of bool type
@param val: really?
@returns: are you stupid?
*/
RJP_value* rjp_new_bool(RJP_bool val);
/*
* Create new RJP_value of string type, coping val
@param val: really?
@param length: c'mon
@returns: are you stupid?
*/
RJP_value* rjp_new_string(const char* val, RJP_index length);
/*
* Create new RJP_value of string type, stealing value of val
@param val: really?
@param length: c'mon
@returns: are you stupid?
*/
RJP_value* rjp_new_string_steal(char* val, RJP_index length);
/*
* Create new RJP_value of object type
@returns: are you stupid?
*/
RJP_value* rjp_new_object(void);
/*
* Create new RJP_value of ordered object type
@returns: are you stupid?
*/
RJP_value* rjp_new_ordered_object(void);
/*
* Create new RJP_value of array type
@returns: are you stupid?
*/
RJP_value* rjp_new_array(void);
/*
* Deallocate RJP_value and all its members/elements
@param root: RJP_value to free
*/
void rjp_free_value(RJP_value* root);
/*
* Deep copy RJP_value. When dest is not null, cleanup
* and then fill the object pointed to by dest.
* Otherwise allocate a new value.
@param dest: value to copy to or NULL
@param src: value to copy from
@returns: pointer to dest or newly allocated copy of src
*/
RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src);
/*
* Steal resources from src and use them to populate dest
* No copy is performed.
@param dest: value to copy to
@param src: value to copy from
@returns: poniter to dest
*/
RJP_value* rjp_move_value(RJP_value* dest, RJP_value* src);
/*
* change an RJP_value to null type
@param v: RJP_value to set
@returns: pointer to v
*/
RJP_value* rjp_set_null(RJP_value* v);
/*
* change an RJP_value to int type
@param v: RJP_value to set
@param val: really?
@returns: pointer to v
*/
RJP_value* rjp_set_int(RJP_value* v, RJP_int val);
/*
* change an RJP_value to float type
@param v: RJP_value to set
@param val: really?
@returns: pointer to v
*/
RJP_value* rjp_set_float(RJP_value* v, RJP_float val);
/*
* change an RJP_value to bool type
@param v: RJP_value to set
@param val: really?
@returns: pointer to v
*/
RJP_value* rjp_set_bool(RJP_value* v, RJP_bool val);
/*
* change an RJP_value to string type, copying source
@param v: RJP_value to set
@param val: string to copy
@param length: length of val
@returns: pointer to v
*/
RJP_value* rjp_set_string(RJP_value* v, const char* val, RJP_index length);
/*
* change an RJP_value to string type, stealing source
@param v: RJP_value to set
@param val: string to steal
@param length: length of val
@returns: pointer to v
*/
RJP_value* rjp_set_string_steal(RJP_value* v, char* val, RJP_index length);
/*
* change an RJP_value to object type
@param v: RJP_value to set
@returns: pointer to v
*/
RJP_value* rjp_set_object(RJP_value* v);
/*
* change an RJP_value to ordered object type
@param v: RJP_value to set
@returns: pointer to v
*/
RJP_value* rjp_set_ordered_object(RJP_value* v);
/*
* change an RJP_value to array type
@param v: RJP_value to set
@returns: pointer to v
*/
RJP_value* rjp_set_array(RJP_value* v);
/*
* Retrieve float value in value
@param value: RJP_value to query
@returns: duh
*/
RJP_float rjp_get_float(const RJP_value* value);
/*
* Retrieve int value in value
@param value: RJP_value to query
@returns: duh
*/
RJP_int rjp_get_int(const RJP_value* value);
/*
* Retrieve bool value in value
@param value: RJP_value to query
@returns: duh
*/
RJP_bool rjp_get_bool(const RJP_value* value);
/*
* Retrieve string value in value
@param value: RJP_value to query
@returns: RJP_string pointer with value and length inside
*/
RJP_string* rjp_get_string(RJP_value* value);
/*
* Retrieve float value in value
@param value: RJP_value to query
@returns: RJP_string pointer with value and length inside
*/
const RJP_string* rjp_get_cstring(const RJP_value* value);
/***************** OBJECT/ARRAY SHARED OPERATIONS *******************/
/*
* Get pointer to parent of value
@param element: value to query
@returns: pointer to parent of element
*/
RJP_value* rjp_value_parent(const RJP_value* element);
/*
* Return type of value
@param value: value to query
@returns: seek help if you can't figure this out
*/
RJP_data_type rjp_value_type(const RJP_value* value);
/***************** OBJECT OPERATIONS *******************/
/*
* create a member in an object
@param dest: object to add to
@param key: key to copy value of
@param keylen: length of key
@returns: pointer to new member
*/
RJP_value* rjp_new_member(RJP_value* dest, const char* key, RJP_index keylen);
/*
* create a member in an object, stealing key
@param dest: object to add to
@param key: key to steal value from
@param keylen: length of key
@returns: pointer to new member
*/
RJP_value* rjp_new_member_steal_key(RJP_value* dest, char* key, RJP_index keylen);
/*
* move a value into a new member in an object
@param dest: object to add to
@param key: key to copy value of
@param keylen: length of key
@param src: value to move from
@returns: pointer to new member
*/
RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src);
/*
* move a value into a new meber in an object, stealing key
@param dest: object to add to
@param key: key to steal value from
@param keylen: length of key
@param src: value to move from
@returns: pointer to new member
*/
RJP_value* rjp_add_member_steal_key(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src);
/*
* Remove member without freeing
@param obj: object to remove from
@param key: key to search for
@returns: pointer to former member
*/
RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key);
/*
* Remove member without freeing
@param obj: object to remove from
@param member: pointer to object's member
@returns: pointer to former member
*/
RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member);
/*
* Remove and free member
@param obj: object to remove from
@param key: key to search for
*/
void rjp_free_member_by_key(RJP_value* obj, const char* key);
/*
* Remove and free member
@param obj: object to remove from
@param member: pointer to object's member
*/
void rjp_free_member(RJP_value* obj, RJP_value* member);
/*
* set existing object member's key. Steal's value of parameter.
* key must be allocated using rjp_alloc/rjp_calloc
@param dest: member to set key of
@param key: key to steal value of
@param keylen: length of key
*/
void rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen);
/*
* set existing object member's key. Copies key parameter
@param dest: member to set key of
@param key: key to copy value of
@param keylen: length of key
*/
void rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen);
/*
* Return number of members in the object
@param object: object to query
@returns: dear god please help me
*/
RJP_index rjp_num_members(const RJP_value* object);
/*
* Return the object member's key
@param member: object member to query
@returns: object member's key/length pair
*/
const RJP_string* rjp_member_key(const RJP_value* member);
/*
* Search for an object member with given key
@param object: object to search within
@param search: key to search for
@returns: pointer to member with given key or NULL if not found
*/
RJP_value* rjp_search_member(const RJP_value* object, const char* search);
/*
* Convert unordered object to ordered object
@param object: object to convert
@returns: pointer to object
*/
RJP_value* rjp_object_to_ordered(RJP_value* object);
/*
* Convert ordered object to unordered object
@param object: object to convert
@returns: pointer to object
*/
RJP_value* rjp_object_to_unordered(RJP_value* object);
/***************** OBJECT ITERATOR OPERATIONS *******************/
/*
* Initialize object iterator to iterate over given object
@param iter: iterator to initialize
@param object: object to iterate over
*/
void rjp_init_object_iterator(RJP_object_iterator* iter, const RJP_value* object);
/*
* Delete object iterator
@param it: iterator to delete
*/
void rjp_delete_object_iterator(RJP_object_iterator* it);
/*
* Get current value in iterator
@param it: iterator to query
@returns: pointer to current value in iterator
*/
RJP_value* rjp_object_iterator_current(const RJP_object_iterator* it);
/*
* Advance iterator to next value and return it
@param it: iterator to query
@returns: pointer to next value in iterator
*/
RJP_value* rjp_object_iterator_next(RJP_object_iterator* it);
/*
* View next value in iterator without advancing
@param it: iterator to query
@returns: pointer to next value in iterator
*/
RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it);
/***************** ARRAY OPERATIONS *******************/
/*
* create an element in an array
@param dest: array to add element to
@returns: pointer to new element
*/
RJP_value* rjp_new_element(RJP_value* dest);
/*
* create an element in an array and steal value in src
@param arr: array to add element to
@param src: value to steal contents of
@returns: pointer to new element
*/
RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src);
/*
* remove element from array without freeing it
@param arr: array to remove element from
@param elem: element to remove
@returns: pointer to former element
*/
RJP_value* rjp_remove_element(RJP_value* arr, RJP_value* elem);
/*
* remove and free element from array
@param arr: array to remove element from
@param elem: element to free
*/
void rjp_free_element(RJP_value* arr, RJP_value* elem);
/*
* Get number of element in array
@param src: array to query
@returns: don't be gay
*/
RJP_index rjp_num_elements(const RJP_value* arr);
/***************** ARRAY ITERATOR OPERATIONS *******************/
/*
* Initialize object iterator to iterate over given object
@param iter: iterator to initialize
@param array: array to iterate over
@returns: you're bein gay
*/
void rjp_init_array_iterator(RJP_array_iterator* iter, const RJP_value* array);
/*
* Delete array iterator
@param iter: iterator to delete
*/
void rjp_delete_array_iterator(RJP_array_iterator* iter);
/*
* Get current value in iterator
@param it: iterator to query
@returns: pointer to current value in iterator
*/
RJP_value* rjp_array_iterator_current(const RJP_array_iterator* it);
/*
* Advance iterator to next value and return it
@param it: iterator to query
@returns: pointer to next value in iterator
*/
RJP_value* rjp_array_iterator_next(RJP_array_iterator* it);
/*
* View next value in iterator without advancing
@param it: iterator to query
@returns: pointer to next value in iterator
*/
RJP_value* rjp_array_iterator_peek(const RJP_array_iterator* it);