Add _c API functions to allow custom allocation/deallocation functions

This commit is contained in:
rexy712 2020-07-20 03:16:21 -07:00
parent bf098ac96a
commit e77d20cae4
18 changed files with 396 additions and 208 deletions

View File

@ -113,6 +113,10 @@ typedef struct RJP_parse_error{
int errcode; int errcode;
int row, column; int row, column;
}RJP_parse_error; }RJP_parse_error;
typedef struct RJP_memory_fns{
void (*free)(void*);
void* (*alloc)(RJP_index);
}RJP_memory_fns;
/***************** NON OBJECT OPERATIONS *******************/ /***************** NON OBJECT OPERATIONS *******************/
void* rjp_alloc(RJP_index nbytes); void* rjp_alloc(RJP_index nbytes);
@ -127,10 +131,15 @@ RJP_string rjp_escape(const char* src);
RJP_value* rjp_simple_parse(const char* str); RJP_value* rjp_simple_parse(const char* str);
RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err); RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err);
RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cbacks, RJP_parse_error* err); RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cbacks, RJP_parse_error* err);
RJP_value* rjp_parse_c(const char* str, int flags, RJP_parse_error* err, const RJP_memory_fns* fns);
RJP_value* rjp_parse_cback_c(int flags, RJP_parse_callback* cbacks, RJP_parse_error* err, const RJP_memory_fns* fns);
char* rjp_to_json(const RJP_value* root, int pretty); char* rjp_to_json(const RJP_value* root, int pretty);
char* rjp_to_json_c(const RJP_value* root, int pretty, const RJP_memory_fns* fns);
char* rjp_parse_error_to_string(const RJP_parse_error* err); char* rjp_parse_error_to_string(const RJP_parse_error* err);
char* rjp_parse_error_to_string_c(const RJP_parse_error* err, const RJP_memory_fns* fns);
void rjp_delete_parse_error(RJP_parse_error* err); void rjp_delete_parse_error(RJP_parse_error* err);
void rjp_delete_parse_error_c(RJP_parse_error* err, const RJP_memory_fns* fns);
RJP_value* rjp_new_null(void); RJP_value* rjp_new_null(void);
RJP_value* rjp_new_int(RJP_int val); RJP_value* rjp_new_int(RJP_int val);
@ -142,9 +151,21 @@ RJP_value* rjp_new_object(void);
RJP_value* rjp_new_ordered_object(void); RJP_value* rjp_new_ordered_object(void);
RJP_value* rjp_new_array(void); RJP_value* rjp_new_array(void);
RJP_value* rjp_new_null_c(const RJP_memory_fns* fns);
RJP_value* rjp_new_int_c(RJP_int val, const RJP_memory_fns* fns);
RJP_value* rjp_new_float_c(RJP_float val, const RJP_memory_fns* fns);
RJP_value* rjp_new_bool_c(RJP_bool val, const RJP_memory_fns* fns);
RJP_value* rjp_new_string_c(const char* val, RJP_index length, const RJP_memory_fns* fns);
RJP_value* rjp_new_string_steal_c(char* val, RJP_index length, const RJP_memory_fns* fns);
RJP_value* rjp_new_object_c(const RJP_memory_fns* fns);
RJP_value* rjp_new_ordered_object_c(const RJP_memory_fns* fns);
RJP_value* rjp_new_array_c(const RJP_memory_fns* fns);
void rjp_free_value(RJP_value* root); void rjp_free_value(RJP_value* root);
void rjp_free_value_c(RJP_value* root, const RJP_memory_fns* fns);
RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src); RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src);
RJP_value* rjp_copy_value_c(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns);
RJP_value* rjp_move_value(RJP_value* dest, RJP_value* src); RJP_value* rjp_move_value(RJP_value* dest, RJP_value* src);
RJP_value* rjp_set_null(RJP_value* v); RJP_value* rjp_set_null(RJP_value* v);
@ -157,6 +178,16 @@ RJP_value* rjp_set_object(RJP_value* v);
RJP_value* rjp_set_ordered_object(RJP_value* v); RJP_value* rjp_set_ordered_object(RJP_value* v);
RJP_value* rjp_set_array(RJP_value* v); RJP_value* rjp_set_array(RJP_value* v);
RJP_value* rjp_set_null_c(RJP_value* v, const RJP_memory_fns* fns);
RJP_value* rjp_set_int_c(RJP_value* v, RJP_int val, const RJP_memory_fns* fns);
RJP_value* rjp_set_float_c(RJP_value* v, RJP_float val, const RJP_memory_fns* fns);
RJP_value* rjp_set_bool_c(RJP_value* v, RJP_bool val, const RJP_memory_fns* fns);
RJP_value* rjp_set_string_c(RJP_value* v, const char* val, RJP_index length, const RJP_memory_fns* fns);
RJP_value* rjp_set_string_steal_c(RJP_value* v, char* val, RJP_index length, const RJP_memory_fns* fns);
RJP_value* rjp_set_object_c(RJP_value* v, const RJP_memory_fns* fns);
RJP_value* rjp_set_ordered_object_c(RJP_value* v, const RJP_memory_fns* fns);
RJP_value* rjp_set_array_c(RJP_value* v, const RJP_memory_fns* fns);
RJP_float rjp_get_float(const RJP_value* value); RJP_float rjp_get_float(const RJP_value* value);
RJP_int rjp_get_int(const RJP_value* value); RJP_int rjp_get_int(const RJP_value* value);
RJP_bool rjp_get_bool(const RJP_value* value); RJP_bool rjp_get_bool(const RJP_value* value);
@ -174,13 +205,24 @@ RJP_value* rjp_new_member_steal_key(RJP_value* dest, char* key, RJP_index keylen
RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src); RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src);
RJP_value* rjp_add_member_steal_key(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src); RJP_value* rjp_add_member_steal_key(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src);
RJP_value* rjp_new_member_c(RJP_value* dest, const char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_value* rjp_new_member_steal_key_c(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_value* rjp_add_member_c(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src, const RJP_memory_fns* fns);
RJP_value* rjp_add_member_steal_key_c(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src, const RJP_memory_fns* fns);
RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key); RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key);
RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member); RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member);
void rjp_free_member_by_key(RJP_value* obj, const char* key); void rjp_free_member_by_key(RJP_value* obj, const char* key);
void rjp_free_member(RJP_value* obj, RJP_value* member); void rjp_free_member(RJP_value* obj, RJP_value* member);
RJP_value* rjp_remove_member_by_key_c(RJP_value* obj, const char* key, const RJP_memory_fns* fns);
RJP_value* rjp_remove_member_c(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns);
void rjp_free_member_by_key_c(RJP_value* obj, const char* key, const RJP_memory_fns* fns);
void rjp_free_member_c(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns);
RJP_value* rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen); RJP_value* rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen);
RJP_value* rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen); RJP_value* rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen);
RJP_value* rjp_set_key_steal_c(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_value* rjp_set_key_c(RJP_value* dest, const char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_index rjp_num_members(const RJP_value* object); RJP_index rjp_num_members(const RJP_value* object);
const RJP_string* rjp_member_key(const RJP_value* member); const RJP_string* rjp_member_key(const RJP_value* member);
@ -188,6 +230,8 @@ RJP_value* rjp_search_member(const RJP_value* object, const char* search);
RJP_value* rjp_object_to_ordered(RJP_value* object); RJP_value* rjp_object_to_ordered(RJP_value* object);
RJP_value* rjp_object_to_unordered(RJP_value* object); RJP_value* rjp_object_to_unordered(RJP_value* object);
RJP_value* rjp_object_to_ordered_c(RJP_value* object, const RJP_memory_fns* fns);
RJP_value* rjp_object_to_unordered_c(RJP_value* object, const RJP_memory_fns* fns);
/***************** OBJECT ITERATOR OPERATIONS *******************/ /***************** OBJECT ITERATOR OPERATIONS *******************/
void rjp_init_object_iterator(RJP_object_iterator* iter, const RJP_value* object); void rjp_init_object_iterator(RJP_object_iterator* iter, const RJP_value* object);
@ -199,8 +243,11 @@ RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it);
/***************** ARRAY OPERATIONS *******************/ /***************** ARRAY OPERATIONS *******************/
RJP_value* rjp_new_element(RJP_value* dest); RJP_value* rjp_new_element(RJP_value* dest);
RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src); RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src);
RJP_value* rjp_new_element_c(RJP_value* dest, const RJP_memory_fns* fns);
RJP_value* rjp_add_element_c(RJP_value* dest, RJP_value* src, const RJP_memory_fns* fns);
RJP_value* rjp_remove_element(RJP_value* arr, RJP_value* elem); RJP_value* rjp_remove_element(RJP_value* arr, RJP_value* elem);
void rjp_free_element(RJP_value* arr, RJP_value* elem); void rjp_free_element(RJP_value* arr, RJP_value* elem);
void rjp_free_element_c(RJP_value* arr, RJP_value* elem, const RJP_memory_fns* fns);
RJP_index rjp_num_elements(const RJP_value* arr); RJP_index rjp_num_elements(const RJP_value* arr);

View File

@ -30,8 +30,8 @@ typedef struct RJP_array{
RJP_index num_elements; RJP_index num_elements;
}RJP_array; }RJP_array;
void irjp_add_element(RJP_array* j); void irjp_add_element(RJP_array* j, const RJP_memory_fns* fns);
void irjp_copy_array(RJP_value* dest, const RJP_value* src); void irjp_copy_array(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns);
RJP_index irjp_dump_array(const RJP_value* arr, char* dest, const int flags, int depth); RJP_index irjp_dump_array(const RJP_value* arr, char* dest, const int flags, int depth);

View File

@ -41,4 +41,6 @@ static inline void irjp_ignore_unused(FILE* fp, ...){
} }
#endif #endif
extern const RJP_memory_fns irjp_default_memory_fns;
#endif #endif

View File

@ -23,8 +23,8 @@
#include "rjp_ordered_object.h" #include "rjp_ordered_object.h"
#include "rjp_internal.h" #include "rjp_internal.h"
void irjp_copy_object(RJP_value* dest, const RJP_value* src); void irjp_copy_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns);
void irjp_delete_object(RJP_value* obj); void irjp_delete_object(RJP_value* obj, const RJP_memory_fns* fns);
RJP_index irjp_dump_object(const RJP_value* root, char* dest, const int flags, int depth); RJP_index irjp_dump_object(const RJP_value* root, char* dest, const int flags, int depth);

View File

@ -29,14 +29,12 @@ typedef struct RJP_ordered_object{
RJP_index num_members; RJP_index num_members;
}RJP_ordered_object; }RJP_ordered_object;
void irjp_copy_ordered_object(RJP_value* dest, const RJP_value* src); void irjp_copy_ordered_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns);
void irjp_delete_ordered_object(RJP_value* obj); void irjp_delete_ordered_object(RJP_value* obj, const RJP_memory_fns* fns);
void irjp_copy_ordered_object(RJP_value* dest, const RJP_value* src); RJP_value* irjp_add_ordered_member(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
void irjp_delete_ordered_object(RJP_value* obj); RJP_value* irjp_remove_ordered_member(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns);
RJP_value* irjp_add_ordered_member(RJP_value* dest, char* key, RJP_index keylen); void irjp_ordered_set_key(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_value* irjp_remove_ordered_member(RJP_value* obj, RJP_value* member);
void irjp_ordered_set_key(RJP_value* dest, char* key, RJP_index keylen);
RJP_index irjp_ordered_num_members(const RJP_value* object); RJP_index irjp_ordered_num_members(const RJP_value* object);
RJP_value* irjp_ordered_search_member(const RJP_value* object, const char* search); RJP_value* irjp_ordered_search_member(const RJP_value* object, const char* search);
void irjp_init_ordered_object_iterator(RJP_object_iterator* it, const RJP_value* object); void irjp_init_ordered_object_iterator(RJP_object_iterator* it, const RJP_value* object);

View File

@ -20,15 +20,16 @@
#define RJP_STRINGS_H #define RJP_STRINGS_H
#include "rjp.h" #include "rjp.h"
#include "rjp_internal.h"
int irjp_is_whitespace(char c); int irjp_is_whitespace(char c);
int irjp_copy_string_quoted(char* restrict dest, const char* restrict string, RJP_index length); int irjp_copy_string_quoted(char* restrict dest, const char* restrict string, RJP_index length);
int irjp_copy_string_keyed(char* restrict dest, const char* restrict string, RJP_index length); int irjp_copy_string_keyed(char* restrict dest, const char* restrict string, RJP_index length);
char* irjp_convert_string(const char* str, RJP_index length, RJP_index* newlen); char* irjp_convert_string(const char* str, RJP_index length, RJP_index* newlen, const RJP_memory_fns* fns);
RJP_index irjp_array_strlen(const RJP_value* arr, const int flags, int depth); RJP_index irjp_array_strlen(const RJP_value* arr, const int flags, int depth);
RJP_index irjp_object_strlen(const RJP_value* root, const int flags, int depth); RJP_index irjp_object_strlen(const RJP_value* root, const int flags, int depth);
RJP_index irjp_value_strlen(const RJP_value* root, const int flags, int depth); RJP_index irjp_value_strlen(const RJP_value* root, const int flags, int depth);
void irjp_strcpy(RJP_string* dest, const RJP_string* src); void irjp_strcpy(RJP_string* dest, const RJP_string* src, const RJP_memory_fns* fns);
#endif #endif

View File

@ -29,11 +29,11 @@ typedef struct RJP_unordered_object{
RJP_index num_members; RJP_index num_members;
}RJP_unordered_object; }RJP_unordered_object;
void irjp_copy_unordered_object(RJP_value* dest, const RJP_value* src); void irjp_copy_unordered_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns);
void irjp_delete_unordered_object(RJP_value* obj); void irjp_delete_unordered_object(RJP_value* obj, const RJP_memory_fns* fns);
RJP_value* irjp_add_unordered_member(RJP_value* dest, char* key, RJP_index keylen); RJP_value* irjp_add_unordered_member(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_value* irjp_remove_unordered_member(RJP_value* obj, RJP_value* member); RJP_value* irjp_remove_unordered_member(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns);
void irjp_unordered_set_key(RJP_value* dest, char* key, RJP_index keylen); void irjp_unordered_set_key(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_index irjp_unordered_num_members(const RJP_value* object); RJP_index irjp_unordered_num_members(const RJP_value* object);
RJP_value* irjp_unordered_search_member(const RJP_value* object, const char* search); RJP_value* irjp_unordered_search_member(const RJP_value* object, const char* search);
void irjp_init_unordered_object_iterator(RJP_object_iterator* it, const RJP_value* object); void irjp_init_unordered_object_iterator(RJP_object_iterator* it, const RJP_value* object);

View File

@ -40,6 +40,6 @@ typedef struct RJP_value{
enum RJP_data_type type; //flag to determine active member of union enum RJP_data_type type; //flag to determine active member of union
}RJP_value; }RJP_value;
void irjp_delete_value(RJP_value* root); void irjp_delete_value(RJP_value* root, const RJP_memory_fns* fns);
#endif #endif

View File

@ -37,12 +37,12 @@ struct RJP_tree_node{
unsigned color:1; unsigned color:1;
}; };
RJP_tree_node* irjp_new_node(char* key, RJP_index keylen); RJP_tree_node* irjp_new_node(char* key, RJP_index keylen, const RJP_memory_fns* fns);
RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, char* key, RJP_index keylen, RJP_value** added, int* status); RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, char* key, RJP_index keylen, RJP_value** added, int* status, const RJP_memory_fns* fns);
RJP_tree_node* irjp_tree_insert_node(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode); RJP_tree_node* irjp_tree_insert_node(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode);
RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* restrict root, RJP_tree_node* restrict member, RJP_tree_node** removed_node); RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* restrict root, RJP_tree_node* restrict member, RJP_tree_node** removed_node);
RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, const char* key); RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, const char* key);
RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root); RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root, const RJP_memory_fns* fns);
void irjp_free_tree(RJP_tree_node* root); void irjp_free_tree(RJP_tree_node* root, const RJP_memory_fns* fns);
#endif #endif

View File

@ -30,123 +30,187 @@
#include <stdio.h> //sprintf #include <stdio.h> //sprintf
RJP_value* rjp_new_null(void){ RJP_value* rjp_new_null(void){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); return rjp_new_null_c(&irjp_default_memory_fns);
}
RJP_value* rjp_new_int(RJP_int val){
return rjp_new_int_c(val, &irjp_default_memory_fns);
}
RJP_value* rjp_new_float(RJP_float val){
return rjp_new_float_c(val, &irjp_default_memory_fns);
}
RJP_value* rjp_new_bool(RJP_bool val){
return rjp_new_bool_c(val, &irjp_default_memory_fns);
}
RJP_value* rjp_new_string_steal(char* val, RJP_index length){
return rjp_new_string_steal_c(val, length, &irjp_default_memory_fns);
}
RJP_value* rjp_new_string(const char* value, RJP_index length){
return rjp_new_string_c(value, length, &irjp_default_memory_fns);
}
RJP_value* rjp_new_object(void){
return rjp_new_object_c(&irjp_default_memory_fns);
}
RJP_value* rjp_new_ordered_object(void){
return rjp_new_ordered_object_c(&irjp_default_memory_fns);
}
RJP_value* rjp_new_array(void){
return rjp_new_array_c(&irjp_default_memory_fns);
}
RJP_value* rjp_new_null_c(const RJP_memory_fns* fns){
RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_null; ret->type = rjp_json_null;
return ret; return ret;
} }
RJP_value* rjp_new_int(RJP_int val){ RJP_value* rjp_new_int_c(RJP_int val, const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_integer; ret->type = rjp_json_integer;
ret->integer = val; ret->integer = val;
return ret; return ret;
} }
RJP_value* rjp_new_float(RJP_float val){ RJP_value* rjp_new_float_c(RJP_float val, const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_dfloat; ret->type = rjp_json_dfloat;
ret->dfloat = val; ret->dfloat = val;
return ret; return ret;
} }
RJP_value* rjp_new_bool(RJP_bool val){ RJP_value* rjp_new_bool_c(RJP_bool val, const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_boolean; ret->type = rjp_json_boolean;
ret->boolean = val; ret->boolean = val;
return ret; return ret;
} }
RJP_value* rjp_new_string_steal(char* val, RJP_index length){ RJP_value* rjp_new_string_steal_c(char* val, RJP_index length, const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_string; ret->type = rjp_json_string;
ret->string.value = val; ret->string.value = val;
ret->string.length = length; ret->string.length = length;
return ret; return ret;
} }
RJP_value* rjp_new_string(const char* value, RJP_index length){ RJP_value* rjp_new_string_c(const char* value, RJP_index length, const RJP_memory_fns* fns){
UNUSED_VARIABLE(length); UNUSED_VARIABLE(length);
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_string; ret->type = rjp_json_string;
RJP_index esclen = rjp_escape_strlen(value); RJP_index esclen = rjp_escape_strlen(value);
ret->string.value = rjp_alloc(esclen+1); ret->string.value = fns->alloc(esclen+1);
rjp_escape_strcpy(ret->string.value, value); rjp_escape_strcpy(ret->string.value, value);
ret->string.value[esclen] = 0; ret->string.value[esclen] = 0;
ret->string.length = esclen; ret->string.length = esclen;
return ret; return ret;
} }
RJP_value* rjp_new_object(void){ RJP_value* rjp_new_object_c(const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_object; ret->type = rjp_json_object;
return ret; return ret;
} }
RJP_value* rjp_new_ordered_object(void){ RJP_value* rjp_new_ordered_object_c(const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_ordered_object; ret->type = rjp_json_ordered_object;
return ret; return ret;
} }
RJP_value* rjp_new_array(void){ RJP_value* rjp_new_array_c(const RJP_memory_fns* fns){
RJP_value* ret = rjp_calloc(1, sizeof(RJP_value)); RJP_value* ret = fns->alloc(sizeof(RJP_value));
memset(ret, 0, sizeof(RJP_value));
ret->type = rjp_json_array; ret->type = rjp_json_array;
return ret; return ret;
} }
RJP_value* rjp_set_null(RJP_value* v){ RJP_value* rjp_set_null(RJP_value* v){
irjp_delete_value(v); return rjp_set_null_c(v, &irjp_default_memory_fns);
}
RJP_value* rjp_set_int(RJP_value* v, RJP_int val){
return rjp_set_int_c(v, val, &irjp_default_memory_fns);
}
RJP_value* rjp_set_float(RJP_value* v, RJP_float val){
return rjp_set_float_c(v, val, &irjp_default_memory_fns);
}
RJP_value* rjp_set_bool(RJP_value* v, RJP_bool val){
return rjp_set_bool_c(v, val, &irjp_default_memory_fns);
}
RJP_value* rjp_set_string_steal(RJP_value* v, char* val, RJP_index len){
return rjp_set_string_steal_c(v, val, len, &irjp_default_memory_fns);
}
RJP_value* rjp_set_string(RJP_value* v, const char* val, RJP_index length){
return rjp_set_string_c(v, val, length, &irjp_default_memory_fns);
}
RJP_value* rjp_set_object(RJP_value* v){
return rjp_set_object_c(v, &irjp_default_memory_fns);
}
RJP_value* rjp_set_ordered_object(RJP_value* v){
return rjp_set_ordered_object_c(v, &irjp_default_memory_fns);
}
RJP_value* rjp_set_array(RJP_value* v){
return rjp_set_array_c(v, &irjp_default_memory_fns);
}
RJP_value* rjp_set_null_c(RJP_value* v, const RJP_memory_fns* fns){
irjp_delete_value(v, fns);
v->type = rjp_json_null; v->type = rjp_json_null;
return v; return v;
} }
RJP_value* rjp_set_int(RJP_value* v, RJP_int val){ RJP_value* rjp_set_int_c(RJP_value* v, RJP_int val, const RJP_memory_fns* fns){
irjp_delete_value(v); irjp_delete_value(v, fns);
v->type = rjp_json_integer; v->type = rjp_json_integer;
v->integer = val; v->integer = val;
return v; return v;
} }
RJP_value* rjp_set_float(RJP_value* v, RJP_float val){ RJP_value* rjp_set_float_c(RJP_value* v, RJP_float val, const RJP_memory_fns* fns){
irjp_delete_value(v); irjp_delete_value(v, fns);
v->type = rjp_json_dfloat; v->type = rjp_json_dfloat;
v->dfloat = val; v->dfloat = val;
return v; return v;
} }
RJP_value* rjp_set_bool(RJP_value* v, RJP_bool val){ RJP_value* rjp_set_bool_c(RJP_value* v, RJP_bool val, const RJP_memory_fns* fns){
irjp_delete_value(v); irjp_delete_value(v, fns);
v->type = rjp_json_boolean; v->type = rjp_json_boolean;
v->boolean = val; v->boolean = val;
return v; return v;
} }
RJP_value* rjp_set_string_steal(RJP_value* v, char* val, RJP_index len){ RJP_value* rjp_set_string_steal_c(RJP_value* v, char* val, RJP_index len, const RJP_memory_fns* fns){
irjp_delete_value(v); irjp_delete_value(v, fns);
v->type = rjp_json_string; v->type = rjp_json_string;
v->string.value = val; v->string.value = val;
v->string.length = len; v->string.length = len;
return v; return v;
} }
RJP_value* rjp_set_string(RJP_value* v, const char* val, RJP_index length){ RJP_value* rjp_set_string_c(RJP_value* v, const char* val, RJP_index length, const RJP_memory_fns* fns){
UNUSED_VARIABLE(length); UNUSED_VARIABLE(length);
irjp_delete_value(v); irjp_delete_value(v, fns);
v->type = rjp_json_string; v->type = rjp_json_string;
RJP_index esclen = rjp_escape_strlen(val); RJP_index esclen = rjp_escape_strlen(val);
v->string.value = rjp_alloc(esclen+1); v->string.value = fns->alloc(esclen+1);
rjp_escape_strcpy(v->string.value, val); rjp_escape_strcpy(v->string.value, val);
v->string.value[esclen] = 0; v->string.value[esclen] = 0;
v->string.length = esclen; v->string.length = esclen;
return v; return v;
} }
RJP_value* rjp_set_object(RJP_value* v){ RJP_value* rjp_set_object_c(RJP_value* v, const RJP_memory_fns* fns){
if(v->type == rjp_json_object) if(v->type == rjp_json_object)
return v; return v;
irjp_delete_value(v); irjp_delete_value(v, fns);
memset(&v->object, 0, sizeof(RJP_unordered_object)); memset(&v->object, 0, sizeof(RJP_unordered_object));
v->type = rjp_json_object; v->type = rjp_json_object;
return v; return v;
} }
RJP_value* rjp_set_ordered_object(RJP_value* v){ RJP_value* rjp_set_ordered_object_c(RJP_value* v, const RJP_memory_fns* fns){
if(v->type == rjp_json_ordered_object) if(v->type == rjp_json_ordered_object)
return v; return v;
irjp_delete_value(v); irjp_delete_value(v, fns);
memset(&v->orobject, 0, sizeof(RJP_ordered_object)); memset(&v->orobject, 0, sizeof(RJP_ordered_object));
v->type = rjp_json_ordered_object; v->type = rjp_json_ordered_object;
return v; return v;
} }
RJP_value* rjp_set_array(RJP_value* v){ RJP_value* rjp_set_array_c(RJP_value* v, const RJP_memory_fns* fns){
if(v->type == rjp_json_array) if(v->type == rjp_json_array)
return v; return v;
irjp_delete_value(v); irjp_delete_value(v, fns);
memset(&v->array, 0, sizeof(RJP_array)); memset(&v->array, 0, sizeof(RJP_array));
v->type = rjp_json_array; v->type = rjp_json_array;
return v; return v;
@ -279,12 +343,15 @@ RJP_index irjp_dump_object(const RJP_value* root, char* dest, const int flags, i
} }
char* rjp_to_json(const RJP_value* root, const int flags){ char* rjp_to_json(const RJP_value* root, const int flags){
return rjp_to_json_c(root, flags, &irjp_default_memory_fns);
}
char* rjp_to_json_c(const RJP_value* root, const int flags, const RJP_memory_fns* fns){
if(!root) if(!root)
return NULL; return NULL;
RJP_index len = irjp_value_strlen(root, flags, 0); RJP_index len = irjp_value_strlen(root, flags, 0);
if(!len) if(!len)
return NULL; return NULL;
char* tmp = rjp_alloc(len + 1); char* tmp = fns->alloc(len + 1);
tmp[len] = 0; tmp[len] = 0;
irjp_write_value(tmp, root, flags, 0); irjp_write_value(tmp, root, flags, 0);

View File

@ -34,28 +34,33 @@ void rjp_free(void* data){
free(data); free(data);
} }
const RJP_memory_fns irjp_default_memory_fns = {rjp_free, rjp_alloc};
RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src){ RJP_value* rjp_copy_value(RJP_value* dest, const RJP_value* src){
return rjp_copy_value_c(dest, src, &irjp_default_memory_fns);
}
RJP_value* rjp_copy_value_c(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){
RJP_value* ret; RJP_value* ret;
if(dest){ if(dest){
irjp_delete_value(dest); irjp_delete_value(dest, fns);
ret = dest; ret = dest;
}else{ }else{
ret = rjp_new_null(); ret = rjp_new_null_c(fns);
} }
ret->type = src->type; ret->type = src->type;
switch(src->type){ switch(src->type){
case rjp_json_object: case rjp_json_object:
irjp_copy_object(ret, src); irjp_copy_object(ret, src, fns);
break; break;
case rjp_json_ordered_object: case rjp_json_ordered_object:
irjp_copy_ordered_object(ret, src); irjp_copy_ordered_object(ret, src, fns);
break; break;
case rjp_json_array: case rjp_json_array:
irjp_copy_array(ret, src); irjp_copy_array(ret, src, fns);
break; break;
case rjp_json_string: case rjp_json_string:
irjp_strcpy(&ret->string, &src->string); irjp_strcpy(&ret->string, &src->string, fns);
break; break;
case rjp_json_integer: case rjp_json_integer:
ret->integer = src->integer; ret->integer = src->integer;
@ -77,37 +82,40 @@ RJP_value* rjp_move_value(RJP_value* dest, RJP_value* src){
return dest; return dest;
} }
static void irjp_delete_array(RJP_value* root){ static void irjp_delete_array(RJP_value* root, const RJP_memory_fns* fns){
RJP_array_iterator it; RJP_array_iterator it;
rjp_init_array_iterator(&it, root); rjp_init_array_iterator(&it, root);
RJP_value* next = rjp_array_iterator_current(&it); RJP_value* next = rjp_array_iterator_current(&it);
for(RJP_value* current = next;current;current = next){ for(RJP_value* current = next;current;current = next){
next = rjp_array_iterator_next(&it); next = rjp_array_iterator_next(&it);
rjp_free_value(current); rjp_free_value_c(current, fns);
} }
} }
void irjp_delete_value(RJP_value* root){ void irjp_delete_value(RJP_value* root, const RJP_memory_fns* fns){
switch(root->type){ switch(root->type){
case rjp_json_object: case rjp_json_object:
case rjp_json_ordered_object: case rjp_json_ordered_object:
irjp_delete_object(root); irjp_delete_object(root, fns);
break; break;
case rjp_json_array: case rjp_json_array:
irjp_delete_array(root); irjp_delete_array(root, fns);
break; break;
case rjp_json_string: case rjp_json_string:
rjp_free(root->string.value); fns->free(root->string.value);
break; break;
default: break; default: break;
}; };
} }
void rjp_free_value(RJP_value* root){ void rjp_free_value(RJP_value* root){
rjp_free_value_c(root, &irjp_default_memory_fns);
}
void rjp_free_value_c(RJP_value* root, const RJP_memory_fns* fns){
if(!root) if(!root)
return; return;
irjp_delete_value(root); irjp_delete_value(root, fns);
rjp_free(root); fns->free(root);
} }
/* VALUE SETTING */ /* VALUE SETTING */

View File

@ -17,42 +17,51 @@
*/ */
#include <stddef.h> #include <stddef.h>
#include <string.h> //memset
#include "rjp_internal.h" #include "rjp_internal.h"
#include "rjp_array.h" #include "rjp_array.h"
#include "rjp_value.h" #include "rjp_value.h"
#include "rjp_array_element.h" #include "rjp_array_element.h"
void irjp_copy_array(RJP_value* dest, const RJP_value* src){ void irjp_copy_array(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){
dest->array.elements = dest->array.last = NULL; dest->array.elements = dest->array.last = NULL;
for(RJP_array_element* curr = src->array.elements;curr;curr = curr->next){ for(RJP_array_element* curr = src->array.elements;curr;curr = curr->next){
RJP_value* copy_mem; RJP_value* copy_mem;
copy_mem = rjp_new_element(dest); copy_mem = rjp_new_element_c(dest, fns);
rjp_copy_value(copy_mem, &curr->value); rjp_copy_value_c(copy_mem, &curr->value, fns);
} }
} }
void irjp_add_element(RJP_array* j){ void irjp_add_element(RJP_array* j, const RJP_memory_fns* fns){
++j->num_elements; ++j->num_elements;
if(!j->elements){ if(!j->elements){
j->elements = rjp_calloc(1, sizeof(RJP_array_element)); j->elements = fns->alloc(sizeof(RJP_array_element));
memset(j->elements, 0, sizeof(RJP_array_element));
j->last = j->elements; j->last = j->elements;
}else{ }else{
j->last->next = rjp_calloc(1, sizeof(RJP_array_element)); j->last->next = fns->alloc(sizeof(RJP_array_element));
memset(j->last->next, 0, sizeof(RJP_array_element));
j->last = j->last->next; j->last = j->last->next;
j->last->prev = j->last; j->last->prev = j->last;
} }
} }
RJP_value* rjp_new_element(RJP_value* dest){ RJP_value* rjp_new_element(RJP_value* dest){
irjp_add_element(&dest->array); return rjp_new_element_c(dest, &irjp_default_memory_fns);
}
RJP_value* rjp_new_element_c(RJP_value* dest, const RJP_memory_fns* fns){
irjp_add_element(&dest->array, fns);
dest->array.last->value.parent = dest; dest->array.last->value.parent = dest;
return &dest->array.last->value; return &dest->array.last->value;
} }
RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src){ RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src){
RJP_value* newelm = rjp_new_element(dest); return rjp_add_element_c(dest, src, &irjp_default_memory_fns);
}
RJP_value* rjp_add_element_c(RJP_value* dest, RJP_value* src, const RJP_memory_fns* fns){
RJP_value* newelm = rjp_new_element_c(dest, fns);
if(!newelm) if(!newelm)
return NULL; return NULL;
rjp_move_value(newelm, src); rjp_move_value(newelm, src);
rjp_free(src); fns->free(src);
return newelm; return newelm;
} }
RJP_value* rjp_remove_element(RJP_value* dest, RJP_value* value){ RJP_value* rjp_remove_element(RJP_value* dest, RJP_value* value){
@ -75,8 +84,11 @@ RJP_value* rjp_remove_element(RJP_value* dest, RJP_value* value){
return value; return value;
} }
void rjp_free_element(RJP_value* dest, RJP_value* value){ void rjp_free_element(RJP_value* dest, RJP_value* value){
rjp_free_element_c(dest, value, &irjp_default_memory_fns);
}
void rjp_free_element_c(RJP_value* dest, RJP_value* value, const RJP_memory_fns* fns){
rjp_remove_element(dest, value); rjp_remove_element(dest, value);
rjp_free_value(value); rjp_free_value_c(value, fns);
} }
RJP_index rjp_num_elements(const RJP_value* array){ RJP_index rjp_num_elements(const RJP_value* array){
return array->array.num_elements; return array->array.num_elements;

View File

@ -25,29 +25,32 @@
#include <string.h> //strlen, strncpy #include <string.h> //strlen, strncpy
void irjp_copy_object(RJP_value* dest, const RJP_value* src){ void irjp_copy_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){
switch(src->type){ switch(src->type){
case rjp_json_object: case rjp_json_object:
irjp_copy_unordered_object(dest, src); irjp_copy_unordered_object(dest, src, fns);
break; break;
case rjp_json_ordered_object: case rjp_json_ordered_object:
irjp_copy_ordered_object(dest, src); irjp_copy_ordered_object(dest, src, fns);
break; break;
default: break; default: break;
}; };
} }
void irjp_delete_object(RJP_value* obj){ void irjp_delete_object(RJP_value* obj, const RJP_memory_fns* fns){
switch(obj->type){ switch(obj->type){
case rjp_json_object: case rjp_json_object:
irjp_delete_unordered_object(obj); irjp_delete_unordered_object(obj, fns);
break; break;
case rjp_json_ordered_object: case rjp_json_ordered_object:
irjp_delete_ordered_object(obj); irjp_delete_ordered_object(obj, fns);
break; break;
default: break; default: break;
}; };
} }
RJP_value* rjp_new_member_steal_key(RJP_value* dest, char* key, RJP_index keylen){ RJP_value* rjp_new_member_steal_key(RJP_value* dest, char* key, RJP_index keylen){
return rjp_new_member_steal_key_c(dest, key, keylen, &irjp_default_memory_fns);
}
RJP_value* rjp_new_member_steal_key_c(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
if(!key) if(!key)
return NULL; return NULL;
if(!keylen) if(!keylen)
@ -55,78 +58,105 @@ RJP_value* rjp_new_member_steal_key(RJP_value* dest, char* key, RJP_index keylen
return NULL; return NULL;
switch(dest->type){ switch(dest->type){
case rjp_json_object: case rjp_json_object:
return irjp_add_unordered_member(dest, key, keylen); return irjp_add_unordered_member(dest, key, keylen, fns);
case rjp_json_ordered_object: case rjp_json_ordered_object:
return irjp_add_ordered_member(dest, key, keylen); return irjp_add_ordered_member(dest, key, keylen, fns);
default: break; default: break;
}; };
return NULL; return NULL;
} }
RJP_value* rjp_new_member(RJP_value* dest, const char* key, RJP_index keylen){ RJP_value* rjp_new_member(RJP_value* dest, const char* key, RJP_index keylen){
return rjp_new_member_c(dest, key, keylen, &irjp_default_memory_fns);
}
RJP_value* rjp_new_member_c(RJP_value* dest, const char* key, RJP_index keylen, const RJP_memory_fns* fns){
if(!key) if(!key)
return NULL; return NULL;
if(!keylen) if(!keylen)
if(!(keylen = rjp_escape_strlen(key))) if(!(keylen = rjp_escape_strlen(key)))
return NULL; return NULL;
char* newkey = rjp_alloc(keylen+1); char* newkey = fns->alloc(keylen+1);
rjp_escape_strcpy(newkey, key); rjp_escape_strcpy(newkey, key);
newkey[keylen] = 0; newkey[keylen] = 0;
return rjp_new_member_steal_key(dest, newkey, keylen); return rjp_new_member_steal_key_c(dest, newkey, keylen, fns);
} }
RJP_value* rjp_add_member_steal_key(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src){ RJP_value* rjp_add_member_steal_key(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src){
RJP_value* newval = rjp_new_member_steal_key(dest, key, keylen); return rjp_add_member_steal_key_c(dest, key, keylen, src, &irjp_default_memory_fns);
}
RJP_value* rjp_add_member_steal_key_c(RJP_value* dest, char* key, RJP_index keylen, RJP_value* src, const RJP_memory_fns* fns){
RJP_value* newval = rjp_new_member_steal_key_c(dest, key, keylen, fns);
if(!newval) if(!newval)
return NULL; return NULL;
rjp_move_value(newval, src); rjp_move_value(newval, src);
rjp_free(src); fns->free(src);
return newval; return newval;
} }
RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src){ RJP_value* rjp_add_member(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src){
RJP_value* newval = rjp_new_member(dest, key, keylen); return rjp_add_member_c(dest, key, keylen, src, &irjp_default_memory_fns);
}
RJP_value* rjp_add_member_c(RJP_value* dest, const char* key, RJP_index keylen, RJP_value* src, const RJP_memory_fns* fns){
RJP_value* newval = rjp_new_member_c(dest, key, keylen, fns);
if(!newval) if(!newval)
return NULL; return NULL;
rjp_move_value(newval, src); rjp_move_value(newval, src);
rjp_free(src); fns->free(src);
return newval; return newval;
} }
RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key){ RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key){
return rjp_remove_member_by_key_c(obj, key, &irjp_default_memory_fns);
}
RJP_value* rjp_remove_member_by_key_c(RJP_value* obj, const char* key, const RJP_memory_fns* fns){
RJP_value* member = rjp_search_member(obj, key); RJP_value* member = rjp_search_member(obj, key);
if(!member) if(!member)
return NULL; return NULL;
return rjp_remove_member(obj, member); return rjp_remove_member_c(obj, member, fns);
} }
RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member){ RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member){
return rjp_remove_member_c(obj, member, &irjp_default_memory_fns);
}
RJP_value* rjp_remove_member_c(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns){
if(member->parent != obj) if(member->parent != obj)
return NULL; return NULL;
switch(obj->type){ switch(obj->type){
case rjp_json_object: case rjp_json_object:
return irjp_remove_unordered_member(obj, member); return irjp_remove_unordered_member(obj, member, fns);
case rjp_json_ordered_object: case rjp_json_ordered_object:
return irjp_remove_ordered_member(obj, member); return irjp_remove_ordered_member(obj, member, fns);
default: break; default: break;
}; };
return NULL; return NULL;
} }
void rjp_free_member_by_key(RJP_value* obj, const char* key){ void rjp_free_member_by_key(RJP_value* obj, const char* key){
rjp_free_member_by_key_c(obj, key, &irjp_default_memory_fns);
}
void rjp_free_member_by_key_c(RJP_value* obj, const char* key, const RJP_memory_fns* fns){
RJP_value* removed = rjp_remove_member_by_key(obj, key); RJP_value* removed = rjp_remove_member_by_key(obj, key);
rjp_free_value(removed); rjp_free_value_c(removed, fns);
} }
void rjp_free_member(RJP_value* obj, RJP_value* member){ void rjp_free_member(RJP_value* obj, RJP_value* member){
rjp_free_member_by_key(obj, ((RJP_object_member*)member)->name.value); rjp_free_member_c(obj, member, &irjp_default_memory_fns);
}
void rjp_free_member_c(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns){
rjp_free_member_by_key_c(obj, ((RJP_object_member*)member)->name.value, fns);
} }
RJP_value* rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen){ RJP_value* rjp_set_key(RJP_value* dest, const char* key, RJP_index keylen){
return rjp_set_key_c(dest, key, keylen, &irjp_default_memory_fns);
}
RJP_value* rjp_set_key_c(RJP_value* dest, const char* key, RJP_index keylen, const RJP_memory_fns* fns){
if(!key) if(!key)
return NULL; return NULL;
if(!keylen){ if(!keylen){
if(!(keylen = strlen(key))) if(!(keylen = strlen(key)))
return NULL; return NULL;
} }
char* newkey = rjp_alloc(keylen + 1); char* newkey = fns->alloc(keylen + 1);
strncpy(newkey, key, keylen+1); strncpy(newkey, key, keylen+1);
return rjp_set_key_steal(dest, newkey, keylen); return rjp_set_key_steal(dest, newkey, keylen);
} }
RJP_value* rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen){ RJP_value* rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen){
return rjp_set_key_steal_c(dest, key, keylen, &irjp_default_memory_fns);
}
RJP_value* rjp_set_key_steal_c(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
if(!key) if(!key)
return NULL; return NULL;
if(!keylen){ if(!keylen){
@ -135,10 +165,10 @@ RJP_value* rjp_set_key_steal(RJP_value* dest, char* key, RJP_index keylen){
} }
switch(dest->parent->type){ switch(dest->parent->type){
case rjp_json_object: case rjp_json_object:
irjp_unordered_set_key(dest, key, keylen); irjp_unordered_set_key(dest, key, keylen, fns);
break; break;
case rjp_json_ordered_object: case rjp_json_ordered_object:
irjp_ordered_set_key(dest, key, keylen); irjp_ordered_set_key(dest, key, keylen, fns);
break; break;
default: break; default: break;
}; };
@ -233,6 +263,9 @@ RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it){
} }
RJP_value* rjp_object_to_ordered(RJP_value* object){ RJP_value* rjp_object_to_ordered(RJP_value* object){
return rjp_object_to_ordered_c(object, &irjp_default_memory_fns);
}
RJP_value* rjp_object_to_ordered_c(RJP_value* object, const RJP_memory_fns* fns){
if(object->type == rjp_json_ordered_object) if(object->type == rjp_json_ordered_object)
return object; return object;
RJP_value newobj = {0}; RJP_value newobj = {0};
@ -242,11 +275,11 @@ RJP_value* rjp_object_to_ordered(RJP_value* object){
irjp_init_unordered_object_iterator(&it, object); irjp_init_unordered_object_iterator(&it, object);
RJP_value* next = irjp_unordered_object_iterator_current(&it); RJP_value* next = irjp_unordered_object_iterator_current(&it);
for(RJP_value* current = next;current;current = next){ for(RJP_value* current = next;current;current = next){
RJP_value* newcur = irjp_add_ordered_member(&newobj, rjp_member_key(current)->value, rjp_member_key(current)->length); RJP_value* newcur = irjp_add_ordered_member(&newobj, rjp_member_key(current)->value, rjp_member_key(current)->length, fns);
((RJP_object_member*)current)->name.value = NULL; ((RJP_object_member*)current)->name.value = NULL;
rjp_move_value(newcur, current); rjp_move_value(newcur, current);
next = irjp_unordered_object_iterator_next(&it); next = irjp_unordered_object_iterator_next(&it);
rjp_free(current); fns->free(current);
} }
irjp_delete_unordered_object_iterator(&it); irjp_delete_unordered_object_iterator(&it);
@ -256,6 +289,9 @@ RJP_value* rjp_object_to_ordered(RJP_value* object){
return object; return object;
} }
RJP_value* rjp_object_to_unordered(RJP_value* object){ RJP_value* rjp_object_to_unordered(RJP_value* object){
return rjp_object_to_unordered_c(object, &irjp_default_memory_fns);
}
RJP_value* rjp_object_to_unordered_c(RJP_value* object, const RJP_memory_fns* fns){
if(object->type == rjp_json_object) if(object->type == rjp_json_object)
return object; return object;
RJP_value newobj = {0}; RJP_value newobj = {0};
@ -265,11 +301,11 @@ RJP_value* rjp_object_to_unordered(RJP_value* object){
irjp_init_ordered_object_iterator(&it, object); irjp_init_ordered_object_iterator(&it, object);
RJP_value* next = irjp_ordered_object_iterator_current(&it); RJP_value* next = irjp_ordered_object_iterator_current(&it);
for(RJP_value* current = next;current;current = next){ for(RJP_value* current = next;current;current = next){
RJP_value* newcur = irjp_add_unordered_member(&newobj, rjp_member_key(current)->value, rjp_member_key(current)->length); RJP_value* newcur = irjp_add_unordered_member(&newobj, rjp_member_key(current)->value, rjp_member_key(current)->length, fns);
((RJP_object_member*)current)->name.value = NULL; ((RJP_object_member*)current)->name.value = NULL;
rjp_move_value(newcur, current); rjp_move_value(newcur, current);
next = irjp_ordered_object_iterator_next(&it); next = irjp_ordered_object_iterator_next(&it);
rjp_free(current); fns->free(current);
} }
irjp_delete_ordered_object_iterator(&it); irjp_delete_ordered_object_iterator(&it);

View File

@ -30,33 +30,33 @@ typedef struct RJP_ordered_member{
struct RJP_ordered_member* next; struct RJP_ordered_member* next;
}RJP_ordered_member; }RJP_ordered_member;
static void irjp_copy_ordered_member(RJP_ordered_member* dest, const RJP_ordered_member* src){ static void irjp_copy_ordered_member(RJP_ordered_member* dest, const RJP_ordered_member* src, const RJP_memory_fns* fns){
irjp_strcpy(&dest->member.name, &src->member.name); irjp_strcpy(&dest->member.name, &src->member.name, fns);
rjp_copy_value(&dest->member.value, &src->member.value); rjp_copy_value_c(&dest->member.value, &src->member.value, fns);
} }
void irjp_copy_ordered_object(RJP_value* dest, const RJP_value* src){ void irjp_copy_ordered_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){
irjp_delete_ordered_object(dest); irjp_delete_ordered_object(dest, fns);
dest->orobject.num_members = 0; dest->orobject.num_members = 0;
RJP_object_iterator it; RJP_object_iterator it;
irjp_init_ordered_object_iterator(&it, src); irjp_init_ordered_object_iterator(&it, src);
for(const RJP_value* current = irjp_ordered_object_iterator_current(&it);current;current = irjp_ordered_object_iterator_next(&it)){ for(const RJP_value* current = irjp_ordered_object_iterator_current(&it);current;current = irjp_ordered_object_iterator_next(&it)){
RJP_string keycopy; RJP_string keycopy;
irjp_strcpy(&keycopy, &((RJP_object_member*)current)->name); irjp_strcpy(&keycopy, &((RJP_object_member*)current)->name, fns);
RJP_ordered_member* newmemb = (RJP_ordered_member*)irjp_add_ordered_member(dest, keycopy.value, keycopy.length); RJP_ordered_member* newmemb = (RJP_ordered_member*)irjp_add_ordered_member(dest, keycopy.value, keycopy.length, fns);
irjp_copy_ordered_member(newmemb, (RJP_ordered_member*)current); irjp_copy_ordered_member(newmemb, (RJP_ordered_member*)current, fns);
} }
irjp_delete_ordered_object_iterator(&it); irjp_delete_ordered_object_iterator(&it);
} }
void irjp_delete_ordered_object(RJP_value* obj){ void irjp_delete_ordered_object(RJP_value* obj, const RJP_memory_fns* fns){
RJP_object_iterator it; RJP_object_iterator it;
irjp_init_ordered_object_iterator(&it, obj); irjp_init_ordered_object_iterator(&it, obj);
RJP_value* next = irjp_ordered_object_iterator_current(&it); RJP_value* next = irjp_ordered_object_iterator_current(&it);
for(RJP_value* current = next;current;current = next){ for(RJP_value* current = next;current;current = next){
next = irjp_ordered_object_iterator_next(&it); next = irjp_ordered_object_iterator_next(&it);
rjp_free(((RJP_object_member*)current)->name.value); fns->free(((RJP_object_member*)current)->name.value);
rjp_free_value(current); rjp_free_value_c(current, fns);
} }
irjp_delete_ordered_object_iterator(&it); irjp_delete_ordered_object_iterator(&it);
} }
@ -73,15 +73,16 @@ static RJP_ordered_member* irjp_append_ordered_member(RJP_ordered_object* dest,
dest->last = newmemb; dest->last = newmemb;
return newmemb; return newmemb;
} }
RJP_value* irjp_add_ordered_member(RJP_value* dest, char* key, RJP_index keylen){ RJP_value* irjp_add_ordered_member(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
RJP_ordered_member* newmemb = rjp_calloc(1, sizeof(RJP_ordered_member)); RJP_ordered_member* newmemb = fns->alloc(sizeof(RJP_ordered_member));
memset(newmemb, 0, sizeof(RJP_ordered_member));
irjp_append_ordered_member((RJP_ordered_object*)dest, newmemb); irjp_append_ordered_member((RJP_ordered_object*)dest, newmemb);
irjp_ordered_set_key((RJP_value*)newmemb, key, keylen); irjp_ordered_set_key((RJP_value*)newmemb, key, keylen, fns);
((RJP_value*)newmemb)->parent = dest; ((RJP_value*)newmemb)->parent = dest;
((RJP_value*)newmemb)->type = rjp_json_null; ((RJP_value*)newmemb)->type = rjp_json_null;
return (RJP_value*)newmemb; return (RJP_value*)newmemb;
} }
RJP_value* irjp_remove_ordered_member(RJP_value* obj, RJP_value* member){ RJP_value* irjp_remove_ordered_member(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns){
RJP_ordered_member* current = (RJP_ordered_member*)member; RJP_ordered_member* current = (RJP_ordered_member*)member;
RJP_ordered_member* prev = current->prev; RJP_ordered_member* prev = current->prev;
RJP_ordered_member* next = current->next; RJP_ordered_member* next = current->next;
@ -97,11 +98,12 @@ RJP_value* irjp_remove_ordered_member(RJP_value* obj, RJP_value* member){
obj->orobject.last = prev; obj->orobject.last = prev;
member->parent = NULL; member->parent = NULL;
fns->free(((RJP_object_member*)member)->name.value);
return member; return member;
} }
void irjp_ordered_set_key(RJP_value* dest, char* key, RJP_index keylen){ void irjp_ordered_set_key(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
RJP_object_member* mem = (RJP_object_member*)dest; RJP_object_member* mem = (RJP_object_member*)dest;
rjp_free(mem->name.value); fns->free(mem->name.value);
mem->name.value = key; mem->name.value = key;
mem->name.length = keylen; mem->name.length = keylen;
} }

View File

@ -104,7 +104,7 @@ static void irjp_parse_stack_set(RJP_parse_stack* s, RJP_parse_target target){
s->stack[s->position] = target; s->stack[s->position] = target;
} }
static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_parse_state* state){ static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_parse_state* state, const RJP_memory_fns* fns){
RJP_index length = state->lexstate.length; RJP_index length = state->lexstate.length;
RJP_index offset = state->lexstate.offset; RJP_index offset = state->lexstate.offset;
const char* str = state->lexstate.str + offset; const char* str = state->lexstate.str + offset;
@ -112,7 +112,7 @@ static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_parse_st
case rjp_lex_string:; case rjp_lex_string:;
RJP_index newlength; RJP_index newlength;
newval->type = rjp_json_string; newval->type = rjp_json_string;
newval->string.value = irjp_convert_string(str, length, &newlength); newval->string.value = irjp_convert_string(str, length, &newlength, fns);
if(!newval->string.value) if(!newval->string.value)
return 1; return 1;
newval->string.length = newlength; newval->string.length = newlength;
@ -152,20 +152,20 @@ static int irjp_init_value(RJP_value* newval, RJP_lex_category cat, RJP_parse_st
}; };
return 0; return 0;
} }
static RJP_value* irjp_add_value_to_array(RJP_lex_category cat, RJP_parse_state* state){ static RJP_value* irjp_add_value_to_array(RJP_lex_category cat, RJP_parse_state* state, const RJP_memory_fns* fns){
state->lastadded = rjp_new_element(state->curr); state->lastadded = rjp_new_element_c(state->curr, fns);
if(irjp_init_value(state->lastadded, cat, state)) if(irjp_init_value(state->lastadded, cat, state, fns))
return NULL; return NULL;
return state->lastadded; return state->lastadded;
} }
static RJP_value* irjp_add_value_to_object(RJP_parse_state* state, const char* key, RJP_index keylen){ static RJP_value* irjp_add_value_to_object(RJP_parse_state* state, const char* key, RJP_index keylen, const RJP_memory_fns* fns){
RJP_index newlen; RJP_index newlen;
char* newkey = irjp_convert_string(key, keylen, &newlen); char* newkey = irjp_convert_string(key, keylen, &newlen, fns);
if(!newlen){ //cannot have empty key if(!newlen){ //cannot have empty key
rjp_free(newkey); fns->free(newkey);
return NULL; return NULL;
} }
return (state->lastadded = rjp_new_member_steal_key(state->curr, newkey, newlen)); return (state->lastadded = rjp_new_member_steal_key_c(state->curr, newkey, newlen, fns));
} }
@ -176,25 +176,26 @@ static RJP_lex_category irjp_convert_comment(_Bool allow_comments){
return rjp_lex_invalid; return rjp_lex_invalid;
} }
static void irjp_init_parse_state(RJP_parse_state* state, const char* str){ static void irjp_init_parse_state(RJP_parse_state* state, const char* str, const RJP_memory_fns* fns){
state->column = 1; state->column = 1;
state->row = 1; state->row = 1;
irjp_init_parse_stack(&state->target_stack); irjp_init_parse_stack(&state->target_stack);
state->lexstate.str = (char*)str; state->lexstate.str = (char*)str;
state->root = state->curr = state->lastadded = rjp_calloc(1, sizeof(RJP_value)); state->root = state->curr = state->lastadded = fns->alloc(sizeof(RJP_value));
memset(state->root, 0, sizeof(RJP_value));
} }
static void irjp_delete_parse_state(RJP_parse_state* state){ static void irjp_delete_parse_state(RJP_parse_state* state){
irjp_delete_parse_stack(&state->target_stack); irjp_delete_parse_stack(&state->target_stack);
irjp_delete_lex_state(&state->lexstate); irjp_delete_lex_state(&state->lexstate);
} }
static void irjp_delete_parse_state_no_preserve_root(RJP_parse_state* state){ static void irjp_delete_parse_state_no_preserve_root(RJP_parse_state* state, const RJP_memory_fns* fns){
irjp_delete_parse_state(state); irjp_delete_parse_state(state);
rjp_free_value(state->root); rjp_free_value_c(state->root, fns);
state->root = NULL; state->root = NULL;
} }
static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state){ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state, const RJP_memory_fns* fns){
if(cat == rjp_lex_line_comment || cat == rjp_lex_block_comment) if(cat == rjp_lex_line_comment || cat == rjp_lex_block_comment)
cat = irjp_convert_comment(state->allow_comments); cat = irjp_convert_comment(state->allow_comments);
@ -212,7 +213,7 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state
case rjp_parse_start: case rjp_parse_start:
irjp_parse_stack_set(&state->target_stack, rjp_parse_end); irjp_parse_stack_set(&state->target_stack, rjp_parse_end);
if(irjp_init_value(state->root, cat, state)){ if(irjp_init_value(state->root, cat, state, fns)){
return RJP_PARSE_STATUS_NO_ROOT_VALUE; return RJP_PARSE_STATUS_NO_ROOT_VALUE;
} }
break; break;
@ -225,7 +226,7 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state
case rjp_parse_mem_key: case rjp_parse_mem_key:
if(cat == rjp_lex_string){ if(cat == rjp_lex_string){
irjp_parse_stack_set(&state->target_stack, rjp_parse_key_colon); irjp_parse_stack_set(&state->target_stack, rjp_parse_key_colon);
if(!irjp_add_value_to_object(state, state->lexstate.str+state->lexstate.offset, state->lexstate.length)){ if(!irjp_add_value_to_object(state, state->lexstate.str+state->lexstate.offset, state->lexstate.length, fns)){
return RJP_PARSE_STATUS_MISSING_KEY; return RJP_PARSE_STATUS_MISSING_KEY;
} }
}else{ }else{
@ -241,7 +242,7 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state
//fallthrough //fallthrough
case rjp_parse_arr_value: case rjp_parse_arr_value:
irjp_parse_stack_set(&state->target_stack, rjp_parse_arr_comma); irjp_parse_stack_set(&state->target_stack, rjp_parse_arr_comma);
if(!irjp_add_value_to_array(cat, state)) if(!irjp_add_value_to_array(cat, state, fns))
return RJP_PARSE_STATUS_MISSING_VALUE; return RJP_PARSE_STATUS_MISSING_VALUE;
} }
break; break;
@ -253,7 +254,7 @@ static int irjp_parse_handle_lexcat(RJP_lex_category cat, RJP_parse_state* state
break; break;
case rjp_parse_obj_value: case rjp_parse_obj_value:
irjp_parse_stack_set(&state->target_stack, rjp_parse_obj_comma); irjp_parse_stack_set(&state->target_stack, rjp_parse_obj_comma);
if(irjp_init_value(state->lastadded, cat, state)){ if(irjp_init_value(state->lastadded, cat, state, fns)){
return RJP_PARSE_STATUS_MISSING_VALUE; return RJP_PARSE_STATUS_MISSING_VALUE;
} }
break; break;
@ -296,28 +297,31 @@ static int irjp_handle_final_parse_token(RJP_parse_state* state, RJP_lex_categor
} }
//Basic parse loop //Basic parse loop
static int irjp_parse(RJP_parse_state* state){ static int irjp_parse(RJP_parse_state* state, const RJP_memory_fns* fns){
RJP_lex_category cat; RJP_lex_category cat;
RJP_parse_status status; RJP_parse_status status;
for(cat = irjp_lex(&state->lexstate);cat & rjp_lex_accept;cat = irjp_lex(&state->lexstate),state->row += state->lexstate.length){ for(cat = irjp_lex(&state->lexstate);cat & rjp_lex_accept;cat = irjp_lex(&state->lexstate),state->row += state->lexstate.length){
if((status = irjp_parse_handle_lexcat(cat, state)) != RJP_PARSE_STATUS_SUC) if((status = irjp_parse_handle_lexcat(cat, state, fns)) != RJP_PARSE_STATUS_SUC)
return status; return status;
} }
return irjp_handle_final_parse_token(state, cat); return irjp_handle_final_parse_token(state, cat);
} }
//Callback parse loop //Callback parse loop
static int irjp_parse_cback(RJP_parse_state* state, RJP_parse_callback* cback){ static int irjp_parse_cback(RJP_parse_state* state, RJP_parse_callback* cback, const RJP_memory_fns* fns){
RJP_lex_category cat; RJP_lex_category cat;
RJP_parse_status status; RJP_parse_status status;
for(cat = irjp_lex_cback(&state->lexstate, cback);cat & rjp_lex_accept;cat = irjp_lex_cback(&state->lexstate, cback),state->row += state->lexstate.length){ for(cat = irjp_lex_cback(&state->lexstate, cback);cat & rjp_lex_accept;cat = irjp_lex_cback(&state->lexstate, cback),state->row += state->lexstate.length){
if((status = irjp_parse_handle_lexcat(cat, state)) != RJP_PARSE_STATUS_SUC) if((status = irjp_parse_handle_lexcat(cat, state, fns)) != RJP_PARSE_STATUS_SUC)
return status; return status;
} }
return irjp_handle_final_parse_token(state, cat); return irjp_handle_final_parse_token(state, cat);
} }
char* rjp_parse_error_to_string(const RJP_parse_error* err){ char* rjp_parse_error_to_string(const RJP_parse_error* err){
return rjp_parse_error_to_string_c(err, &irjp_default_memory_fns);
}
char* rjp_parse_error_to_string_c(const RJP_parse_error* err, const RJP_memory_fns* fns){
const RJP_parse_state* state = (const RJP_parse_state*)err->parsestate; const RJP_parse_state* state = (const RJP_parse_state*)err->parsestate;
RJP_parse_status status = err->errcode; RJP_parse_status status = err->errcode;
char* buffer = NULL; char* buffer = NULL;
@ -325,42 +329,42 @@ char* rjp_parse_error_to_string(const RJP_parse_error* err){
switch(status){ switch(status){
case RJP_PARSE_STATUS_MISSING_VALUE: case RJP_PARSE_STATUS_MISSING_VALUE:
format = "Expected value before '%.*s'"; format = "Expected value before '%.*s'";
buffer = rjp_alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1); buffer = fns->alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1);
sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)); sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset));
break; break;
case RJP_PARSE_STATUS_MISSING_COMMA: case RJP_PARSE_STATUS_MISSING_COMMA:
format = "Expected comma before '%.*s'"; format = "Expected comma before '%.*s'";
buffer = rjp_alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1); buffer = fns->alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1);
sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)); sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset));
break; break;
case RJP_PARSE_STATUS_INVALID: case RJP_PARSE_STATUS_INVALID:
format = "Invalid lex token '%.*s'"; format = "Invalid lex token '%.*s'";
buffer = rjp_alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1); buffer = fns->alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1);
sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)); sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset));
break; break;
case RJP_PARSE_STATUS_NO_ROOT_VALUE: case RJP_PARSE_STATUS_NO_ROOT_VALUE:
format = "Missing root JSON value"; format = "Missing root JSON value";
buffer = rjp_alloc(snprintf(NULL, 0, "%s", format) + 1); buffer = fns->alloc(snprintf(NULL, 0, "%s", format) + 1);
sprintf(buffer, "%s", format); sprintf(buffer, "%s", format);
break; break;
case RJP_PARSE_STATUS_MISSING_KEY: case RJP_PARSE_STATUS_MISSING_KEY:
format = "Expected key before '%.*s'"; format = "Expected key before '%.*s'";
buffer = rjp_alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1); buffer = fns->alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1);
sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)); sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset));
break; break;
case RJP_PARSE_STATUS_MISSING_COLON: case RJP_PARSE_STATUS_MISSING_COLON:
format = "Expected colon before '%.*s'"; format = "Expected colon before '%.*s'";
buffer = rjp_alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1); buffer = fns->alloc(snprintf(NULL, 0, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)) + 1);
sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset)); sprintf(buffer, format, (int)state->lexstate.length, (state->lexstate.str + state->lexstate.offset));
break; break;
case RJP_PARSE_STATUS_EXCESS_DATA: case RJP_PARSE_STATUS_EXCESS_DATA:
format = "Excess data after JSON"; format = "Excess data after JSON";
buffer = rjp_alloc(snprintf(NULL, 0, "%s", format) + 1); buffer = fns->alloc(snprintf(NULL, 0, "%s", format) + 1);
sprintf(buffer, "%s", format); sprintf(buffer, "%s", format);
break; break;
case RJP_PARSE_STATUS_MISSING_CLOSE_BRACE: case RJP_PARSE_STATUS_MISSING_CLOSE_BRACE:
format = "Missing closing brace"; format = "Missing closing brace";
buffer = rjp_alloc(snprintf(NULL, 0, "%s", format) + 1); buffer = fns->alloc(snprintf(NULL, 0, "%s", format) + 1);
sprintf(buffer, "%s", format); sprintf(buffer, "%s", format);
break; break;
default: default:
@ -369,22 +373,28 @@ char* rjp_parse_error_to_string(const RJP_parse_error* err){
return buffer; return buffer;
} }
void rjp_delete_parse_error(RJP_parse_error* err){ void rjp_delete_parse_error(RJP_parse_error* err){
irjp_delete_parse_state_no_preserve_root((RJP_parse_state*)err->parsestate); rjp_delete_parse_error_c(err, &irjp_default_memory_fns);
}
void rjp_delete_parse_error_c(RJP_parse_error* err, const RJP_memory_fns* fns){
irjp_delete_parse_state_no_preserve_root((RJP_parse_state*)err->parsestate, fns);
rjp_free(err->parsestate); rjp_free(err->parsestate);
} }
RJP_value* rjp_simple_parse(const char* str){ RJP_value* rjp_simple_parse(const char* str){
return rjp_parse(str, RJP_PARSE_NO_EXT, NULL); return rjp_parse_c(str, RJP_PARSE_NO_EXT, NULL, &irjp_default_memory_fns);
} }
RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err){ RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err){
return rjp_parse_c(str, flags, err, &irjp_default_memory_fns);
}
RJP_value* rjp_parse_c(const char* str, int flags, RJP_parse_error* err, const RJP_memory_fns* fns){
RJP_parse_state* state = rjp_calloc(sizeof(RJP_parse_state), 1); RJP_parse_state* state = rjp_calloc(sizeof(RJP_parse_state), 1);
state->allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS); state->allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS);
state->allow_trail_comma = (flags & RJP_PARSE_ALLOW_TRAILING_COMMA); state->allow_trail_comma = (flags & RJP_PARSE_ALLOW_TRAILING_COMMA);
irjp_init_parse_state(state, str); irjp_init_parse_state(state, str, fns);
irjp_init_lex_state(&state->lexstate); irjp_init_lex_state(&state->lexstate);
int status = irjp_parse(state); int status = irjp_parse(state, fns);
if(status == RJP_PARSE_STATUS_SUC){ if(status == RJP_PARSE_STATUS_SUC){
irjp_delete_parse_state(state); irjp_delete_parse_state(state);
RJP_value* root = state->root; RJP_value* root = state->root;
@ -397,7 +407,7 @@ RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err){
err->row = state->column; err->row = state->column;
err->column = state->row; err->column = state->row;
}else{ }else{
irjp_delete_parse_state_no_preserve_root(state); irjp_delete_parse_state_no_preserve_root(state, fns);
rjp_free(state); rjp_free(state);
} }
return NULL; return NULL;
@ -407,13 +417,16 @@ RJP_value* rjp_parse(const char* str, int flags, RJP_parse_error* err){
//Callback based parse. Runs identical to normal parsing except sets up callback //Callback based parse. Runs identical to normal parsing except sets up callback
//lex state and calls callback lex function //lex state and calls callback lex function
RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cback, RJP_parse_error* err){ RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cback, RJP_parse_error* err){
return rjp_parse_cback_c(flags, cback, err, &irjp_default_memory_fns);
}
RJP_value* rjp_parse_cback_c(int flags, RJP_parse_callback* cback, RJP_parse_error* err, const RJP_memory_fns* fns){
RJP_parse_state* state = rjp_calloc(sizeof(RJP_parse_state), 1); RJP_parse_state* state = rjp_calloc(sizeof(RJP_parse_state), 1);
state->allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS); state->allow_comments = (flags & RJP_PARSE_ALLOW_COMMENTS);
state->allow_trail_comma = (flags & RJP_PARSE_ALLOW_TRAILING_COMMA); state->allow_trail_comma = (flags & RJP_PARSE_ALLOW_TRAILING_COMMA);
irjp_init_parse_state(state, NULL); irjp_init_parse_state(state, NULL, fns);
irjp_init_lex_cback_state(&state->lexstate); irjp_init_lex_cback_state(&state->lexstate);
int status = irjp_parse_cback(state, cback); int status = irjp_parse_cback(state, cback, fns);
if(status == RJP_PARSE_STATUS_SUC){ if(status == RJP_PARSE_STATUS_SUC){
irjp_delete_parse_state(state); irjp_delete_parse_state(state);
RJP_value* root = state->root; RJP_value* root = state->root;
@ -426,7 +439,7 @@ RJP_value* rjp_parse_cback(int flags, RJP_parse_callback* cback, RJP_parse_error
err->row = state->column; err->row = state->column;
err->column = state->row; err->column = state->row;
}else{ }else{
irjp_delete_parse_state_no_preserve_root(state); irjp_delete_parse_state_no_preserve_root(state, fns);
rjp_free(state); rjp_free(state);
} }
return NULL; return NULL;

View File

@ -163,7 +163,7 @@ int irjp_copy_string_keyed(char* restrict dest, const char* restrict string, RJP
dest[offset] = ':'; dest[offset] = ':';
return offset+1; return offset+1;
} }
char* irjp_convert_string(const char* str, RJP_index length, RJP_index* newlen){ char* irjp_convert_string(const char* str, RJP_index length, RJP_index* newlen, const RJP_memory_fns* fns){
char* newstring; char* newstring;
RJP_index oldpos = 1; //ignore opening quote RJP_index oldpos = 1; //ignore opening quote
--length; //ignore closing quote --length; //ignore closing quote
@ -184,7 +184,7 @@ char* irjp_convert_string(const char* str, RJP_index length, RJP_index* newlen){
return NULL; return NULL;
} }
} }
newstring = rjp_alloc(newlength + 1); newstring = fns->alloc(newlength + 1);
newstring[newlength] = 0; newstring[newlength] = 0;
*newlen = newlength; *newlen = newlength;
oldpos = 1; oldpos = 1;
@ -276,8 +276,8 @@ RJP_index rjp_escape_strcpy(char* dest, const char* src){
dest[j] = 0; dest[j] = 0;
return j; return j;
} }
void irjp_strcpy(RJP_string* dest, const RJP_string* src){ void irjp_strcpy(RJP_string* dest, const RJP_string* src, const RJP_memory_fns* fns){
dest->value = rjp_alloc(src->length + 1); dest->value = fns->alloc(src->length + 1);
strcpy(dest->value, src->value); strcpy(dest->value, src->value);
dest->value[src->length] = 0; dest->value[src->length] = 0;
dest->length = src->length; dest->length = src->length;

View File

@ -79,36 +79,36 @@ static RJP_tree_node* irjp_double_peek_tree_stack(RJP_tree_stack* stack){
} }
/* RJP_OBJECT */ /* RJP_OBJECT */
void irjp_copy_unordered_object(RJP_value* dest, const RJP_value* src){ void irjp_copy_unordered_object(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){
dest->object.root = irjp_copy_tree(src->object.root); dest->object.root = irjp_copy_tree(src->object.root, fns);
} }
void irjp_delete_unordered_object(RJP_value* obj){ void irjp_delete_unordered_object(RJP_value* obj, const RJP_memory_fns* fns){
irjp_free_tree(obj->object.root); irjp_free_tree(obj->object.root, fns);
} }
RJP_value* irjp_add_unordered_member(RJP_value* dest, char* key, RJP_index keylen){ RJP_value* irjp_add_unordered_member(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
++dest->object.num_members; ++dest->object.num_members;
int status; int status;
RJP_value* retval; RJP_value* retval;
dest->object.root = irjp_tree_insert_value(dest->object.root, key, keylen, &retval, &status); dest->object.root = irjp_tree_insert_value(dest->object.root, key, keylen, &retval, &status, fns);
retval->parent = dest; retval->parent = dest;
retval->type = rjp_json_null; retval->type = rjp_json_null;
return retval; return retval;
} }
RJP_value* irjp_remove_unordered_member(RJP_value* obj, RJP_value* member){ RJP_value* irjp_remove_unordered_member(RJP_value* obj, RJP_value* member, const RJP_memory_fns* fns){
RJP_tree_node* removed_node = NULL; RJP_tree_node* removed_node = NULL;
obj->object.root = irjp_tree_remove_value(obj->object.root, (RJP_tree_node*)member, &removed_node); obj->object.root = irjp_tree_remove_value(obj->object.root, (RJP_tree_node*)member, &removed_node);
rjp_free(((RJP_object_member*)removed_node)->name.value); fns->free(((RJP_object_member*)removed_node)->name.value);
member->parent = NULL; member->parent = NULL;
--obj->object.num_members; --obj->object.num_members;
return member; return member;
} }
void irjp_unordered_set_key(RJP_value* dest, char* key, RJP_index keylen){ void irjp_unordered_set_key(RJP_value* dest, char* key, RJP_index keylen, const RJP_memory_fns* fns){
RJP_value* parent = dest->parent; RJP_value* parent = dest->parent;
RJP_tree_node* removed_node = NULL; RJP_tree_node* removed_node = NULL;
parent->object.root = irjp_tree_remove_value(parent->object.root, (RJP_tree_node*)dest, &removed_node); parent->object.root = irjp_tree_remove_value(parent->object.root, (RJP_tree_node*)dest, &removed_node);
rjp_free(((RJP_object_member*)removed_node)->name.value); fns->free(((RJP_object_member*)removed_node)->name.value);
((RJP_object_member*)removed_node)->name.value = key; ((RJP_object_member*)removed_node)->name.value = key;
((RJP_object_member*)removed_node)->name.length = keylen; ((RJP_object_member*)removed_node)->name.length = keylen;

View File

@ -40,10 +40,10 @@ static inline int irjp_is_inside_right(RJP_tree_node* n);
static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restrict child); static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restrict child);
static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src); static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src);
static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent); static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent, const RJP_memory_fns* fns);
static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent); static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent, const RJP_memory_fns* fns);
static void irjp_free_node(RJP_tree_node* node); static void irjp_free_node(RJP_tree_node* node, const RJP_memory_fns* fns);
static void irjp_delete_node(RJP_tree_node* node); static void irjp_delete_node(RJP_tree_node* node, const RJP_memory_fns* fns);
static RJP_tree_node* irjp_tree_insert_impl(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode); static RJP_tree_node* irjp_tree_insert_impl(RJP_tree_node *restrict root, RJP_tree_node *restrict newnode);
static RJP_tree_node* irjp_tree_repair(RJP_tree_node* node); static RJP_tree_node* irjp_tree_repair(RJP_tree_node* node);
@ -123,8 +123,9 @@ static void irjp_replace_node(RJP_tree_node *restrict node, RJP_tree_node *restr
} }
//Node construction / destruction //Node construction / destruction
RJP_tree_node* irjp_new_node(char* key, RJP_index keylen){ RJP_tree_node* irjp_new_node(char* key, RJP_index keylen, const RJP_memory_fns* fns){
RJP_tree_node* node = rjp_calloc(sizeof(RJP_tree_node), 1); RJP_tree_node* node = fns->alloc(sizeof(RJP_tree_node));
memset(node, 0, sizeof(RJP_tree_node));
node->data.name.value = key; node->data.name.value = key;
node->data.name.length = keylen; node->data.name.length = keylen;
node->parent = node->left = node->right = NULL; node->parent = node->left = node->right = NULL;
@ -134,54 +135,55 @@ RJP_tree_node* irjp_new_node(char* key, RJP_index keylen){
static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src){ static void irjp_copy_node_data(RJP_tree_node *restrict dest, RJP_tree_node *restrict src){
dest->data = src->data; dest->data = src->data;
} }
static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent){ static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent, const RJP_memory_fns* fns){
RJP_tree_node* dest = rjp_calloc(1, sizeof(RJP_tree_node)); RJP_tree_node* dest = fns->alloc(sizeof(RJP_tree_node));
rjp_copy_value(&dest->data.value, &src->data.value); memset(dest, 0, sizeof(RJP_tree_node));
irjp_strcpy(&dest->data.name, &src->data.name); rjp_copy_value_c(&dest->data.value, &src->data.value, fns);
irjp_strcpy(&dest->data.name, &src->data.name, fns);
dest->parent = parent; dest->parent = parent;
return dest; return dest;
} }
static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent){ static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent, const RJP_memory_fns* fns){
if(!root){ if(!root){
return NULL; return NULL;
} }
RJP_tree_node* newnode = irjp_clone_node(root, parent); RJP_tree_node* newnode = irjp_clone_node(root, parent, fns);
newnode->left = irjp_copy_node(root->left, newnode); newnode->left = irjp_copy_node(root->left, newnode, fns);
newnode->right = irjp_copy_node(root->right, newnode); newnode->right = irjp_copy_node(root->right, newnode, fns);
return newnode; return newnode;
} }
static void irjp_free_node(RJP_tree_node* node){ static void irjp_free_node(RJP_tree_node* node, const RJP_memory_fns* fns){
irjp_delete_node(node); irjp_delete_node(node, fns);
rjp_free(node); fns->free(node);
} }
static void irjp_delete_node(RJP_tree_node* node){ static void irjp_delete_node(RJP_tree_node* node, const RJP_memory_fns* fns){
rjp_free(node->data.name.value); fns->free(node->data.name.value);
irjp_delete_value(&node->data.value); irjp_delete_value(&node->data.value, fns);
} }
/* TREE */ /* TREE */
//Tree construction / destruction //Tree construction / destruction
RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root){ RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root, const RJP_memory_fns* fns){
return irjp_copy_node(root, NULL); return irjp_copy_node(root, NULL, fns);
} }
void irjp_free_tree(RJP_tree_node* root){ void irjp_free_tree(RJP_tree_node* root, const RJP_memory_fns* fns){
if(!root) if(!root)
return; return;
irjp_free_tree(root->left); irjp_free_tree(root->left, fns);
irjp_free_tree(root->right); irjp_free_tree(root->right, fns);
irjp_free_node(root); irjp_free_node(root, fns);
} }
//Tree operations //Tree operations
RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, char* key, RJP_index keylen, RJP_value** added, int* status){ RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, char* key, RJP_index keylen, RJP_value** added, int* status, const RJP_memory_fns* fns){
*status = RJP_TREE_SUCCESS; *status = RJP_TREE_SUCCESS;
if(!root){ if(!root){
root = irjp_new_node(key, keylen); root = irjp_new_node(key, keylen, fns);
if(added) if(added)
*added = &root->data.value; *added = &root->data.value;
return root; return root;
} }
RJP_tree_node* newnode = irjp_new_node(key, keylen); RJP_tree_node* newnode = irjp_new_node(key, keylen, fns);
if(added) if(added)
*added = &newnode->data.value; *added = &newnode->data.value;
return irjp_tree_insert_node(root, newnode); return irjp_tree_insert_node(root, newnode);