Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e15c54b7cc | ||
|
|
092a6497f8 | ||
|
|
88cdc61357 | ||
|
|
4be1d9b2d0 | ||
|
|
250c6b1e59 |
@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.0.2)
|
||||
project(rjp)
|
||||
set(rjp_VERSION_MAJOR 0)
|
||||
set(rjp_VERSION_MINOR 8)
|
||||
set(rjp_VERSION_REVISION 0)
|
||||
set(rjp_VERSION_REVISION 2)
|
||||
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include)
|
||||
configure_file(
|
||||
"${INCLUDE_PATH}/config.h.in"
|
||||
|
||||
@@ -42,7 +42,7 @@ extern "C"{
|
||||
#define RJP_float double
|
||||
#endif
|
||||
#ifndef RJP_bool
|
||||
#define RJP_bool _Bool
|
||||
#define RJP_bool char
|
||||
#endif
|
||||
|
||||
//used with rjp_to_json
|
||||
@@ -172,9 +172,9 @@ RJP_value* rjp_search_member(const RJP_value* object, const char* search);
|
||||
//Access first member of a json object
|
||||
void rjp_init_object_iterator(RJP_object_iterator* iter, const RJP_value* object);
|
||||
void rjp_delete_object_iterator(RJP_object_iterator* it);
|
||||
RJP_value* rjp_object_iterator_current(RJP_object_iterator* it);
|
||||
RJP_value* rjp_object_iterator_current(const RJP_object_iterator* it);
|
||||
RJP_value* rjp_object_iterator_next(RJP_object_iterator* it);
|
||||
RJP_value* rjp_object_iterator_peek(RJP_object_iterator* it);
|
||||
RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it);
|
||||
|
||||
/***************** ARRAY OPERATIONS *******************/
|
||||
//add an element to a json array
|
||||
@@ -187,9 +187,9 @@ RJP_index rjp_num_elements(const RJP_value* arr);
|
||||
/***************** ARRAY ITERATOR OPERATIONS *******************/
|
||||
void rjp_init_array_iterator(RJP_array_iterator* iter, const RJP_value* array);
|
||||
void rjp_delete_array_iterator(RJP_array_iterator* iter);
|
||||
RJP_value* rjp_array_iterator_current(RJP_array_iterator* it);
|
||||
RJP_value* rjp_array_iterator_current(const RJP_array_iterator* it);
|
||||
RJP_value* rjp_array_iterator_next(RJP_array_iterator* it);
|
||||
RJP_value* rjp_array_iterator_peek(RJP_array_iterator* it);
|
||||
RJP_value* rjp_array_iterator_peek(const RJP_array_iterator* it);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -39,7 +39,8 @@ struct RJP_tree_node{
|
||||
|
||||
RJP_tree_node* irjp_new_node(char* key, RJP_index keylen);
|
||||
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_remove_value(RJP_tree_node* root, const char* key, RJP_value** removed_node, int* status);
|
||||
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_search_value(RJP_tree_node* root, const char* key);
|
||||
RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root);
|
||||
void irjp_free_tree(RJP_tree_node* root);
|
||||
|
||||
@@ -126,6 +126,7 @@ RJP_value* rjp_set_object(RJP_value* v){
|
||||
if(v->type == rjp_json_object)
|
||||
return v;
|
||||
irjp_delete_value(v);
|
||||
memset(&v->object, 0, sizeof(RJP_object));
|
||||
v->type = rjp_json_object;
|
||||
return v;
|
||||
}
|
||||
@@ -133,6 +134,7 @@ RJP_value* rjp_set_array(RJP_value* v){
|
||||
if(v->type == rjp_json_array)
|
||||
return v;
|
||||
irjp_delete_value(v);
|
||||
memset(&v->object, 0, sizeof(RJP_array));
|
||||
v->type = rjp_json_array;
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -76,12 +76,11 @@ void rjp_init_array_iterator(RJP_array_iterator* iter, const RJP_value* array){
|
||||
iter->current = &(array->array.elements->value);
|
||||
}
|
||||
void rjp_delete_array_iterator(RJP_array_iterator* it){
|
||||
if(!it)
|
||||
return;
|
||||
it->current = NULL;
|
||||
}
|
||||
RJP_value* rjp_get_element(const RJP_value* array){
|
||||
return &array->array.elements->value;
|
||||
}
|
||||
RJP_value* rjp_array_iterator_current(RJP_array_iterator* it){
|
||||
RJP_value* rjp_array_iterator_current(const RJP_array_iterator* it){
|
||||
return it->current;
|
||||
}
|
||||
RJP_value* rjp_array_iterator_next(RJP_array_iterator* it){
|
||||
@@ -89,7 +88,7 @@ RJP_value* rjp_array_iterator_next(RJP_array_iterator* it){
|
||||
it->current = curr ? &(curr->next->value) : NULL;
|
||||
return it->current;
|
||||
}
|
||||
RJP_value* rjp_array_iterator_peek(RJP_array_iterator* it){
|
||||
RJP_value* rjp_array_iterator_peek(const RJP_array_iterator* it){
|
||||
RJP_array_element* curr = (RJP_array_element*)it->current;
|
||||
return curr ? &(curr->next->value) : NULL;
|
||||
}
|
||||
|
||||
@@ -148,15 +148,16 @@ RJP_value* rjp_add_member_key_copy(RJP_value* dest, const char* key, RJP_index k
|
||||
return irjp_add_member_impl(dest, newkey, keylen);
|
||||
}
|
||||
RJP_value* rjp_remove_member_by_key(RJP_value* obj, const char* key){
|
||||
int status;
|
||||
RJP_value* removed;
|
||||
obj->object.root = irjp_tree_remove_value(obj->object.root, key, &removed, &status);
|
||||
if(removed)
|
||||
rjp_free(((RJP_object_member*)removed)->name.value);
|
||||
return removed;
|
||||
RJP_value* member = rjp_search_member(obj, key);
|
||||
if(!member)
|
||||
return NULL;
|
||||
return rjp_remove_member(obj, member);
|
||||
}
|
||||
RJP_value* rjp_remove_member(RJP_value* obj, RJP_value* member){
|
||||
return rjp_remove_member_by_key(obj, ((RJP_object_member*)member)->name.value);
|
||||
RJP_tree_node* removed_node = NULL;
|
||||
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);
|
||||
return member;
|
||||
}
|
||||
void rjp_free_member_by_key(RJP_value* obj, const char* key){
|
||||
RJP_value* removed = rjp_remove_member_by_key(obj, key);
|
||||
@@ -167,7 +168,6 @@ void rjp_free_member(RJP_value* obj, RJP_value* member){
|
||||
}
|
||||
|
||||
void rjp_set_key_copy(RJP_value* dest, const char* key, RJP_index keylen){
|
||||
RJP_object_member* mem = (RJP_object_member*)dest;
|
||||
if(key){
|
||||
if(!keylen){
|
||||
keylen = strlen(key);
|
||||
@@ -175,13 +175,12 @@ void rjp_set_key_copy(RJP_value* dest, const char* key, RJP_index keylen){
|
||||
}else{
|
||||
keylen = 0;
|
||||
}
|
||||
mem->name.value = rjp_alloc(keylen + 1);
|
||||
strncpy(mem->name.value, key, keylen);
|
||||
mem->name.value[keylen] = 0;
|
||||
mem->name.length = keylen;
|
||||
char* newkey = rjp_alloc(keylen + 1);
|
||||
strncpy(newkey, key, keylen);
|
||||
newkey[keylen] = 0;
|
||||
rjp_set_key(dest, newkey, keylen);
|
||||
}
|
||||
void rjp_set_key(RJP_value* dest, char* key, RJP_index keylen){
|
||||
RJP_object_member* mem = (RJP_object_member*)dest;
|
||||
if(key){
|
||||
if(!keylen){
|
||||
keylen = strlen(key);
|
||||
@@ -189,8 +188,15 @@ void rjp_set_key(RJP_value* dest, char* key, RJP_index keylen){
|
||||
}else{
|
||||
keylen = 0;
|
||||
}
|
||||
mem->name.value = key;
|
||||
mem->name.length = keylen;
|
||||
RJP_value* parent = dest->parent;
|
||||
RJP_tree_node* removed_node = NULL;
|
||||
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);
|
||||
((RJP_object_member*)removed_node)->name.value = key;
|
||||
((RJP_object_member*)removed_node)->name.length = keylen;
|
||||
|
||||
parent->object.root = irjp_tree_insert_node(parent->object.root, removed_node);
|
||||
}
|
||||
RJP_index rjp_num_members(const RJP_value* object){
|
||||
return object->object.num_members;
|
||||
@@ -215,7 +221,7 @@ void rjp_delete_object_iterator(RJP_object_iterator* it){
|
||||
rjp_free(it->it);
|
||||
it->it = NULL;
|
||||
}
|
||||
RJP_value* rjp_object_iterator_current(RJP_object_iterator* it){
|
||||
RJP_value* rjp_object_iterator_current(const RJP_object_iterator* it){
|
||||
RJP_tree_node* n = irjp_object_iterator_current(it->it);
|
||||
if(!n)
|
||||
return NULL;
|
||||
@@ -227,7 +233,7 @@ RJP_value* rjp_object_iterator_next(RJP_object_iterator* it){
|
||||
return NULL;
|
||||
return &n->data.value;
|
||||
}
|
||||
RJP_value* rjp_object_iterator_peek(RJP_object_iterator* it){
|
||||
RJP_value* rjp_object_iterator_peek(const RJP_object_iterator* it){
|
||||
RJP_tree_node* n = irjp_object_iterator_peek(it->it);
|
||||
if(!n)
|
||||
return NULL;
|
||||
|
||||
29
src/tree.c
29
src/tree.c
@@ -46,10 +46,9 @@ static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* p
|
||||
static void irjp_free_node(RJP_tree_node* node);
|
||||
static void irjp_delete_node(RJP_tree_node* node);
|
||||
|
||||
static RJP_tree_node* irjp_tree_insert_node(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_remove_node(RJP_tree_node* target, RJP_value** removed_node);
|
||||
static RJP_tree_node* irjp_tree_remove_node(RJP_tree_node* target, RJP_tree_node** removed_node);
|
||||
|
||||
|
||||
//Tree helpers
|
||||
@@ -188,7 +187,7 @@ RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, char* key, RJP_index
|
||||
*added = &newnode->data.value;
|
||||
return irjp_tree_insert_node(root, newnode);
|
||||
}
|
||||
static 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){
|
||||
irjp_tree_insert_impl(root, newnode);
|
||||
irjp_tree_repair(newnode);
|
||||
while(root->parent)
|
||||
@@ -337,29 +336,19 @@ void irjp_dbg_print_tree_bfs(RJP_tree_node* root){
|
||||
#undef pop
|
||||
#undef push
|
||||
|
||||
RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, const char* key, RJP_value** removed_node, int* status){
|
||||
if(!root){
|
||||
*removed_node = NULL;
|
||||
*status = RJP_TREE_ERR_NULL_ROOT;
|
||||
RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* restrict root, RJP_tree_node* restrict member, RJP_tree_node** removed_node){
|
||||
if(!root)
|
||||
return root;
|
||||
}
|
||||
RJP_tree_node* n = irjp_tree_search_value(root, key);
|
||||
if(!n){
|
||||
*removed_node = NULL;
|
||||
*status = RJP_TREE_ERR_NOT_FOUND;
|
||||
if(!member)
|
||||
return root;
|
||||
}
|
||||
*status = RJP_TREE_SUCCESS;
|
||||
return irjp_tree_remove_node(n, removed_node);
|
||||
return irjp_tree_remove_node(member, removed_node);
|
||||
}
|
||||
static RJP_tree_node* irjp_tree_remove_node(RJP_tree_node* target, RJP_value** removed_node){
|
||||
if(removed_node)
|
||||
*removed_node = (RJP_value*)target;
|
||||
|
||||
static RJP_tree_node* irjp_tree_remove_node(RJP_tree_node* target, RJP_tree_node** removed_node){
|
||||
while(target->right && target->left){
|
||||
irjp_copy_node_data(target, target->right);
|
||||
target = target->right;
|
||||
}
|
||||
*removed_node = target;
|
||||
RJP_tree_node* retval = target->parent;
|
||||
|
||||
do{
|
||||
@@ -453,6 +442,8 @@ static RJP_tree_node* irjp_tree_remove_node(RJP_tree_node* target, RJP_value** r
|
||||
}
|
||||
}while(1);
|
||||
|
||||
(*removed_node)->left = NULL;
|
||||
(*removed_node)->right = NULL;
|
||||
//return new root
|
||||
if(!retval)
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user