Moved rjp.c, memory.c, and strings.c over to new tree-based objects. Unfortunately, the API did need modified because C lacks the 'mutable' keyword.

This commit is contained in:
rexy712 2020-01-13 15:19:27 -08:00
parent 6e53fe29e2
commit a646d1c4e8
7 changed files with 123 additions and 210 deletions

View File

@ -74,14 +74,23 @@ typedef struct RJP_string{
}RJP_string; }RJP_string;
//Forward declarations //Forward declarations
struct RJP_object_member;
struct RJP_array_element; struct RJP_array_element;
typedef struct RJP_tree_node RJP_tree_node;
typedef struct RJP_tree_stack{
RJP_tree_node** data;
int size;
int pos;
}RJP_tree_stack;
typedef struct RJP_object_iterator{
RJP_tree_stack stack;
RJP_tree_node* current;
}RJP_object_iterator;
//Represents a json object //Represents a json object
typedef struct RJP_object{ typedef struct RJP_object{
struct RJP_object_member* members; //linked list of members struct RJP_tree_node* root;
struct RJP_object_member* last; //final member of linked list int num_members;
size_t num_members;
}RJP_object; }RJP_object;
//Represents a json array //Represents a json array
@ -162,7 +171,7 @@ RJP_value rjp_object(void);
RJP_value rjp_array(void); RJP_value rjp_array(void);
//Access first member of a json object //Access first member of a json object
RJP_value* rjp_get_member(const RJP_value* object); RJP_value* rjp_get_member(RJP_object_iterator* object);
//Access next member of a json object given the previous member //Access next member of a json object given the previous member
RJP_value* rjp_next_member(const RJP_value* member); RJP_value* rjp_next_member(const RJP_value* member);
//Return number of members in the object //Return number of members in the object
@ -172,13 +181,10 @@ char* rjp_member_name(const RJP_value* member);
//Return the object member's key name length excluding null terminator //Return the object member's key name length excluding null terminator
size_t rjp_member_name_length(const RJP_value* member); size_t rjp_member_name_length(const RJP_value* member);
//Search for an object member with given key //Search for an object member with given key
RJP_search_res rjp_search_member(const RJP_value* object, const char* search, size_t skip); RJP_value* rjp_search_member(const RJP_value* object, const char* search);
//Search for first occurance of multiple keys. Returns first occurance of each. //Search for first occurance of multiple keys. Returns first occurance of each.
//Assumes dest is large enough to hold maximum num items. //Assumes dest is large enough to hold maximum num items.
size_t rjp_search_members(const RJP_value* object, size_t num, const char* const* searches, RJP_search_res* dest, size_t skip); size_t rjp_search_members(const RJP_value* object, size_t num, const char* const* searches, RJP_value** dest);
//Search for multiple occurances of multiple keys. Returns pointer to list of matches.
//Returned pointer must be freed using rjp_free
RJP_search_res* rjp_search_members_multi(const RJP_value* object, size_t num, const char* const* searches, size_t* rsize, size_t skip);
//Access first element of a json array //Access first element of a json array
RJP_value* rjp_get_element(const RJP_value* array); RJP_value* rjp_get_element(const RJP_value* array);
//Access next element of a json array given the previous element //Access next element of a json array given the previous element

View File

@ -39,15 +39,8 @@ typedef struct RJP_array_element{
struct RJP_value value; struct RJP_value value;
struct RJP_array_element* next; struct RJP_array_element* next;
}RJP_array_element; }RJP_array_element;
//A member of an object
typedef struct RJP_object_member{
struct RJP_value value;
struct RJP_string name;
struct RJP_object_member* next;
}RJP_object_member;
void irjp_add_element(RJP_array* j); void irjp_add_element(RJP_array* j);
void irjp_add_member(RJP_object* j, const char* str, size_t len);
void irjp_add_member_no_alloc(RJP_object* j, char* str, size_t len); void irjp_add_member_no_alloc(RJP_object* j, char* str, size_t len);
void irjp_delete_value(RJP_value* root);
#endif #endif

View File

@ -22,14 +22,15 @@ struct RJP_tree_node{
unsigned color:1; unsigned color:1;
}; };
RJP_tree_node* irjp_new_node(RJP_object_member value);
RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member value, int* status); RJP_tree_node* irjp_new_node(RJP_object_member* value);
RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, RJP_object_member value, int* status); RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, int* status);
RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, RJP_object_member value); RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, const char* key, int* status);
RJP_tree_node* irjp_copy_tree(RJP_tree_node* root); 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); void irjp_free_tree(RJP_tree_node* root);
int irjp_init_object_iterator(RJP_object_iterator* it, RJP_tree_node* root); int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root);
void irjp_delete_object_iterator(RJP_object_iterator* it); void irjp_delete_object_iterator(RJP_object_iterator* it);
RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it); RJP_tree_node* irjp_object_iterator_next(RJP_object_iterator* it);
RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it); RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it);

View File

@ -18,6 +18,7 @@
#include "rjp_internal.h" #include "rjp_internal.h"
#include "strings.h" #include "strings.h"
#include "tree.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -35,14 +36,6 @@ void rjp_free(void* data){
free(data); free(data);
} }
static void irjp_copy_object(RJP_value* dest, const RJP_value* src){
dest->object.members = dest->object.last = 0;
for(RJP_value* curr = rjp_get_member(src);curr;curr = rjp_next_member(curr)){
RJP_value copy_mem;
rjp_copy_value(&copy_mem, curr);
rjp_add_member(dest, rjp_member_name(curr), rjp_member_name_length(curr), copy_mem);
}
}
static void irjp_copy_array(RJP_value* dest, const RJP_value* src){ static void irjp_copy_array(RJP_value* dest, const RJP_value* src){
dest->array.elements = dest->array.last = 0; dest->array.elements = dest->array.last = 0;
for(RJP_value* curr = rjp_get_element(src);curr;curr = rjp_next_element(curr)){ for(RJP_value* curr = rjp_get_element(src);curr;curr = rjp_next_element(curr)){
@ -57,7 +50,8 @@ void rjp_copy_value(RJP_value* dest, const RJP_value* src){
switch(src->type){ switch(src->type){
case rjp_json_object: case rjp_json_object:
irjp_copy_object(dest, src); irjp_free_tree(dest->object.root);
dest->object.root = irjp_copy_tree(src->object.root);
break; break;
case rjp_json_array: case rjp_json_array:
irjp_copy_array(dest, src); irjp_copy_array(dest, src);
@ -79,13 +73,12 @@ void rjp_copy_value(RJP_value* dest, const RJP_value* src){
}; };
} }
static void irjp_free_object_recurse(RJP_value* root);
static void irjp_free_array(RJP_value* root){ static void irjp_free_array(RJP_value* root){
RJP_array_element* arr = root->array.elements; RJP_array_element* arr = root->array.elements;
for(RJP_array_element* i = arr;i != NULL;i = arr){ for(RJP_array_element* i = arr;i != NULL;i = arr){
arr = arr->next; arr = arr->next;
if(i->value.type == rjp_json_object){ if(i->value.type == rjp_json_object){
irjp_free_object_recurse(&i->value); irjp_free_tree(i->value.object.root);
}else if(i->value.type == rjp_json_array){ }else if(i->value.type == rjp_json_array){
irjp_free_array(&i->value); irjp_free_array(&i->value);
}else if(i->value.type == rjp_json_string){ }else if(i->value.type == rjp_json_string){
@ -94,32 +87,18 @@ static void irjp_free_array(RJP_value* root){
free(i); free(i);
} }
} }
//Recursively free JSON objects
static void irjp_free_object_recurse(RJP_value* root){
RJP_object_member* next;
for(RJP_object_member* m = root->object.members;m;m = next){
next = m->next;
if(m->value.type == rjp_json_object)
irjp_free_object_recurse(&m->value);
else if(m->value.type == rjp_json_string)
free(m->value.string.value);
else if(m->value.type == rjp_json_array)
irjp_free_array(&m->value);
if(m->name.value)
free(m->name.value);
free(m);
}
}
//Same as recurse but also frees root node void irjp_delete_value(RJP_value* root){
if((root->type) == rjp_json_object)
irjp_free_tree(root->object.root);
else if((root->type) == rjp_json_array)
irjp_free_array(root);
else if((root->type) == rjp_json_string)
rjp_free(root->string.value);
}
void rjp_free_value(RJP_value* root){ void rjp_free_value(RJP_value* root){
if(!root) if(!root)
return; return;
irjp_delete_value(root);
if((root->type) == rjp_json_object)
irjp_free_object_recurse(root);
else if((root->type) == rjp_json_array)
irjp_free_array(root);
free(root); free(root);
} }

141
src/rjp.c
View File

@ -17,6 +17,7 @@
*/ */
#include "rjp_internal.h" #include "rjp_internal.h"
#include "tree.h"
#include <string.h> //strncpy, strlen #include <string.h> //strncpy, strlen
@ -30,49 +31,31 @@ void irjp_add_element(RJP_array* j){
j->last = j->last->next; j->last = j->last->next;
} }
} }
//create member of the object as a linked list member and assign a name with name allocation
void irjp_add_member(RJP_object* j, const char* str, size_t len){
++j->num_members;
if(!j->members){
j->members = rjp_calloc(1, sizeof(RJP_object_member));
j->last = j->members;
}else{
j->last->next = rjp_calloc(1, sizeof(RJP_object_member));
j->last = j->last->next;
}
j->last->name.value = rjp_alloc(len + 1);
strncpy(j->last->name.value, str, len);
j->last->name.value[len] = 0;
j->last->name.length = len;
}
void irjp_add_member_no_alloc(RJP_object* j, char* str, size_t len){
++j->num_members;
if(!j->members){
j->members = rjp_calloc(1, sizeof(RJP_object_member));
j->last = j->members;
}else{
j->last->next = rjp_calloc(1, sizeof(RJP_object_member));
j->last = j->last->next;
}
j->last->name.value = str;
j->last->name.length = len;
}
RJP_value* rjp_add_member(RJP_value* dest, const char* key, size_t keylen, RJP_value value){ RJP_value* rjp_add_member(RJP_value* dest, const char* key, size_t keylen, RJP_value value){
if(!keylen) if(!keylen)
keylen = strlen(key); keylen = strlen(key);
irjp_add_member(&dest->object, key, keylen); ++dest->object.num_members;
dest->object.last->value = value; RJP_object_member mem;
dest->object.last->value.parent = dest; mem.name.value = rjp_alloc(keylen+1);
return &dest->object.last->value; strncpy(mem.name.value, key, keylen);
mem.name.value[keylen] = 0;
mem.name.length = keylen;
mem.value = value;
int status;
return &irjp_tree_insert_value(dest->object.root, &mem, &status)->data.value;
} }
RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, size_t keylen, RJP_value value){ RJP_value* rjp_add_member_no_alloc(RJP_value* dest, char* key, size_t keylen, RJP_value value){
if(!keylen) if(!keylen)
keylen = strlen(key); keylen = strlen(key);
irjp_add_member_no_alloc(&dest->object, key, keylen); RJP_object_member mem;
dest->object.last->value = value; mem.name.value = key;
dest->object.last->value.parent = dest; mem.name.length = keylen;
return &dest->object.last->value; mem.value = value;
int status;
return &irjp_tree_insert_value(dest->object.root, &mem, &status)->data.value;
} }
RJP_value* rjp_add_element(RJP_value* dest, RJP_value value){ RJP_value* rjp_add_element(RJP_value* dest, RJP_value value){
irjp_add_element(&dest->array); irjp_add_element(&dest->array);
@ -140,12 +123,16 @@ RJP_value rjp_array(void){
} }
RJP_value* rjp_get_member(const RJP_value* object){ RJP_value* rjp_get_member(RJP_object_iterator* it){
return &object->object.members->value; return &it->current->data.value;
} }
RJP_value* rjp_next_member(const RJP_value* member){ RJP_object_iterator rjp_get_object_iterator(const RJP_value* object){
//polymorphism RJP_object_iterator it;
return (RJP_value*)(((RJP_object_member*)member)->next); irjp_init_object_iterator(&it, object->object.root);
return it;
}
void rjp_object_iterator_next(RJP_object_iterator* it){
irjp_object_iterator_next(it);
} }
size_t rjp_num_members(const RJP_value* object){ size_t rjp_num_members(const RJP_value* object){
return object->object.num_members; return object->object.num_members;
@ -157,75 +144,27 @@ size_t rjp_member_name_length(const RJP_value* member){
return ((RJP_object_member*)member)->name.length; return ((RJP_object_member*)member)->name.length;
} }
RJP_search_res rjp_search_member(const RJP_value* object, const char* search, size_t skip){ RJP_value* rjp_search_member(const RJP_value* object, const char* search){
RJP_value* member = rjp_get_member(object); RJP_tree_node* n = irjp_tree_search_value(object->object.root, search);
size_t i = 0; if(!n)
for(;i < skip && member;member = rjp_next_member(member),++i); return NULL;
return &n->data.value;
for(;member;member = rjp_next_member(member),++i){
if(!strcmp(((RJP_object_member*)member)->name.value, search)){
return (RJP_search_res){member, 0, i};
}
}
return (RJP_search_res){0};
} }
size_t rjp_search_members(const RJP_value* object, size_t num, const char* const* searches, RJP_search_res* dest, size_t skip){ size_t rjp_search_members(const RJP_value* object, size_t num, const char* const* searches, RJP_value** dest){
for(size_t i = 0;i < num;++i){
dest[i] = (RJP_search_res){0};
}
RJP_value* member = rjp_get_member(object);
size_t objindex = 0;
for(;objindex < skip && member;member = rjp_next_member(member),++objindex);
size_t matches = 0; size_t matches = 0;
for(;member;member = rjp_next_member(member),++objindex){ for(size_t i = 0;i < num;++i){
for(size_t i = 0;i < num;++i){ RJP_tree_node* n = irjp_tree_search_value(object->object.root, searches[i]);
if(dest[i].value != NULL) if(!n){
continue; dest[i] = NULL;
if(!strcmp(((RJP_object_member*)member)->name.value, searches[i])){ }else{
dest[i].value = member; dest[i] = &n->data.value;
dest[i].searchindex = i; ++matches;
dest[i].objindex = objindex;
++matches;
break;
}
} }
} }
return matches; return matches;
} }
RJP_search_res* rjp_search_members_multi(const RJP_value* object, size_t num, const char* const* searches, size_t* rsize, size_t skip){
RJP_search_res* ret = rjp_alloc(num*sizeof(RJP_search_res));
size_t ret_size = num;
size_t j = 0;
RJP_value* member = rjp_get_member(object);
size_t objindex = 0;
for(;objindex < skip && member;member = rjp_next_member(member),++objindex);
for(;member;member = rjp_next_member(member),++objindex){
for(size_t i = 0;i < num;++i){
if(!strcmp(((RJP_object_member*)member)->name.value, searches[i])){
ret[j].value = member;
ret[j].searchindex = i;
ret[j].objindex = objindex;
++j;
if(j == ret_size){
ret_size *= 2;
ret = rjp_realloc(ret, ret_size*sizeof(RJP_search_res));
}
break;
}
}
}
if(rsize)
*rsize = j;
if(j == 0){
rjp_free(ret);
return NULL;
}
return ret;
}
RJP_value* rjp_get_element(const RJP_value* array){ RJP_value* rjp_get_element(const RJP_value* array){
return &array->array.elements->value; return &array->array.elements->value;

View File

@ -21,6 +21,7 @@
#include "strings.h" #include "strings.h"
#include "rjp_internal.h" #include "rjp_internal.h"
#include "tree.h"
#include <stdio.h> //fprintf #include <stdio.h> //fprintf
#include <stdlib.h> //malloc, free #include <stdlib.h> //malloc, free
@ -325,33 +326,43 @@ size_t irjp_array_strlen_pretty(const RJP_value* arr, int depth){
size_t irjp_object_strlen(const RJP_value* root){ size_t irjp_object_strlen(const RJP_value* root){
size_t count = 2; //{} size_t count = 2; //{}
const RJP_object* root_obj = &root->object; RJP_object_iterator it;
const RJP_object_member* member_list = root_obj->members; irjp_init_object_iterator(&it, root->object.root);
for(;member_list;member_list = member_list->next){ RJP_tree_node* current = irjp_object_iterator_current(&it);
if(member_list->name.length == 0 || member_list->name.value[0] == 0) while(current){
RJP_object_member* mem = &current->data;
if(mem->name.length == 0 || mem->name.value[0] == 0){
irjp_delete_object_iterator(&it);
return 0; return 0;
count += member_list->name.length + 3; //"": }
count += irjp_value_strlen(&member_list->value); count += mem->name.length + 3; //"":
if(member_list->next) count += irjp_value_strlen(&mem->value);
if((current = irjp_object_iterator_next(&it)))
++count; //, ++count; //,
} }
irjp_delete_object_iterator(&it);
return count; return count;
} }
size_t irjp_object_strlen_pretty(const RJP_value* root, int depth){ size_t irjp_object_strlen_pretty(const RJP_value* root, int depth){
size_t count = 3 + depth; //{\n\t} size_t count = 3 + depth; //{\n\t}
++depth; ++depth;
const RJP_object* root_obj = &root->object; RJP_object_iterator it;
const RJP_object_member* member_list = root_obj->members; irjp_init_object_iterator(&it, root->object.root);
for(;member_list;member_list = member_list->next){ RJP_tree_node* current = irjp_object_iterator_current(&it);
if(member_list->name.length == 0 || member_list->name.value[0] == 0) while(current){
RJP_object_member* mem = &current->data;
if(mem->name.length == 0 || mem->name.value[0] == 0){
irjp_delete_object_iterator(&it);
return 0; return 0;
count += member_list->name.length + 4; //"":space }
count += irjp_value_strlen_pretty(&member_list->value, depth); count += mem->name.length + 4; //"":space
count += irjp_value_strlen_pretty(&mem->value, depth);
count += depth; //tabs count += depth; //tabs
++count; //newline ++count; //newline
if(member_list->next) if((current = irjp_object_iterator_next(&it)))
++count; //, ++count; //,
} }
irjp_delete_object_iterator(&it);
return count; return count;
} }

View File

@ -5,30 +5,14 @@
#include <stdio.h> #include <stdio.h>
#include "strings.h" #include "strings.h"
#include "rjp_internal.h"
#define BLACK 0 #define BLACK 0
#define RED 1 #define RED 1
//TMP
#define rjp_malloc malloc
#define rjp_free free
#define rjp_free_value(x)
#define irjp_strcpy(dest, src) do{(dest)->value = rjp_malloc((src)->length + 1);strcpy((dest)->value, (src)->value);(dest)->value[(src)->length] = 0;(dest)->length = (src)->length;}while(0);
#define rjp_copy_value(dest, src) ((dest)->integer = (src)->integer)
#define RJP_TREE_ITERATOR_STACK_START_SIZE 32 #define RJP_TREE_ITERATOR_STACK_START_SIZE 32
//Internal use only structs
typedef struct RJP_tree_stack{
RJP_tree_node** data;
int size;
int pos;
}RJP_tree_stack;
typedef struct RJP_object_iterator{
RJP_tree_stack stack;
RJP_tree_node* current;
}RJP_object_iterator;
//Forward declare static functions //Forward declare static functions
static inline RJP_tree_node* irjp_grandparent(RJP_tree_node* n); static inline RJP_tree_node* irjp_grandparent(RJP_tree_node* n);
static inline RJP_tree_node* irjp_sibling(RJP_tree_node* n); static inline RJP_tree_node* irjp_sibling(RJP_tree_node* n);
@ -40,8 +24,8 @@ 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(RJP_tree_node* src, RJP_tree_node* parent); static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent);
static RJP_tree_node* irjp_copy_node(RJP_tree_node* root, RJP_tree_node* parent); static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent);
static void irjp_free_node(RJP_tree_node* node); static void irjp_free_node(RJP_tree_node* node);
static void irjp_delete_node(RJP_tree_node* node); static void irjp_delete_node(RJP_tree_node* node);
@ -131,24 +115,24 @@ 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(RJP_object_member value){ RJP_tree_node* irjp_new_node(RJP_object_member* value){
RJP_tree_node* node = rjp_malloc(sizeof(RJP_tree_node)); RJP_tree_node* node = rjp_alloc(sizeof(RJP_tree_node));
node->data.name = value.name; node->data.name = value->name;
node->data.value = value.value; node->data.value = value->value;
node->parent = node->left = node->right = NULL; node->parent = node->left = node->right = NULL;
return node; return node;
} }
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(RJP_tree_node* src, RJP_tree_node* parent){ static RJP_tree_node* irjp_clone_node(const RJP_tree_node* src, RJP_tree_node* parent){
RJP_tree_node* dest = rjp_malloc(sizeof(RJP_tree_node)); RJP_tree_node* dest = rjp_alloc(sizeof(RJP_tree_node));
rjp_copy_value(&dest->data.value, &src->data.value); rjp_copy_value(&dest->data.value, &src->data.value);
irjp_strcpy(&dest->data.name, &src->data.name); irjp_strcpy(&dest->data.name, &src->data.name);
dest->parent = parent; dest->parent = parent;
return dest; return dest;
} }
static RJP_tree_node* irjp_copy_node(RJP_tree_node* root, RJP_tree_node* parent){ static RJP_tree_node* irjp_copy_node(const RJP_tree_node* root, RJP_tree_node* parent){
if(!root){ if(!root){
return NULL; return NULL;
} }
@ -163,14 +147,14 @@ static void irjp_free_node(RJP_tree_node* node){
} }
static void irjp_delete_node(RJP_tree_node* node){ static void irjp_delete_node(RJP_tree_node* node){
rjp_free(node->data.name.value); rjp_free(node->data.name.value);
rjp_free_value(&node->data.value); irjp_delete_value(&node->data.value);
} }
/* TREE STACK */ /* TREE STACK */
//Stack construction / destruction //Stack construction / destruction
static int irjp_init_tree_stack(RJP_tree_stack* stack){ static int irjp_init_tree_stack(RJP_tree_stack* stack){
stack->data = rjp_malloc(sizeof(RJP_tree_node*)*RJP_TREE_ITERATOR_STACK_START_SIZE); stack->data = rjp_alloc(sizeof(RJP_tree_node*)*RJP_TREE_ITERATOR_STACK_START_SIZE);
stack->size = RJP_TREE_ITERATOR_STACK_START_SIZE; stack->size = RJP_TREE_ITERATOR_STACK_START_SIZE;
stack->pos = 0; stack->pos = 0;
return 0; return 0;
@ -180,7 +164,7 @@ static void irjp_delete_tree_stack(RJP_tree_stack* stack){
} }
static void irjp_resize_tree_stack(RJP_tree_stack* stack){ static void irjp_resize_tree_stack(RJP_tree_stack* stack){
int newsize = stack->size*2; int newsize = stack->size*2;
RJP_tree_node** newdata = rjp_malloc(sizeof(RJP_tree_node*)*newsize); RJP_tree_node** newdata = rjp_alloc(sizeof(RJP_tree_node*)*newsize);
for(int i = 0;i < stack->size;++i){ for(int i = 0;i < stack->size;++i){
newdata[i] = stack->data[i]; newdata[i] = stack->data[i];
} }
@ -203,9 +187,9 @@ static RJP_tree_node* irjp_peek_tree_stack(RJP_tree_stack* stack){
/* TREE ITERATOR */ /* TREE ITERATOR */
//Iterator construction / destruction //Iterator construction / destruction
int irjp_init_object_iterator(RJP_object_iterator* it, RJP_tree_node* root){ int irjp_init_object_iterator(RJP_object_iterator* it, const RJP_tree_node* root){
irjp_init_tree_stack(&it->stack); irjp_init_tree_stack(&it->stack);
it->current = root; it->current = (RJP_tree_node*)root;
while(it->current){ while(it->current){
irjp_push_tree_stack(&it->stack, it->current); irjp_push_tree_stack(&it->stack, it->current);
it->current = it->current->left; it->current = it->current->left;
@ -230,7 +214,7 @@ RJP_tree_node* irjp_object_iterator_current(RJP_object_iterator* it){
/* TREE */ /* TREE */
//Tree construction / destruction //Tree construction / destruction
RJP_tree_node* irjp_copy_tree(RJP_tree_node* root){ RJP_tree_node* irjp_copy_tree(const RJP_tree_node* root){
return irjp_copy_node(root, NULL); return irjp_copy_node(root, NULL);
} }
void irjp_free_tree(RJP_tree_node* root){ void irjp_free_tree(RJP_tree_node* root){
@ -241,7 +225,7 @@ void irjp_free_tree(RJP_tree_node* root){
irjp_free_node(root); irjp_free_node(root);
} }
//Tree operations //Tree operations
RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member value, int* status){ RJP_tree_node* irjp_tree_insert_value(RJP_tree_node* root, RJP_object_member* value, int* status){
*status = RJP_TREE_SUCCESS; *status = RJP_TREE_SUCCESS;
if(!root){ if(!root){
root = irjp_new_node(value); root = irjp_new_node(value);
@ -318,9 +302,9 @@ static RJP_tree_node* irjp_tree_repair(RJP_tree_node* node){
} }
} }
RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, RJP_object_member value){ RJP_tree_node* irjp_tree_search_value(RJP_tree_node* root, const char* key){
while(root != NULL){ while(root != NULL){
int cmpval = strcmp(value.name.value, root->data.name.value); int cmpval = strcmp(key, root->data.name.value);
if(cmpval < 0){ if(cmpval < 0){
root = root->left; root = root->left;
}else if(cmpval > 0){ }else if(cmpval > 0){
@ -398,12 +382,12 @@ void irjp_dbg_print_tree_bfs(RJP_tree_node* root){
#undef pop #undef pop
#undef push #undef push
RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, RJP_object_member value, int* status){ RJP_tree_node* irjp_tree_remove_value(RJP_tree_node* root, const char* key, int* status){
if(!root){ if(!root){
*status = RJP_TREE_ERR_NULL_ROOT; *status = RJP_TREE_ERR_NULL_ROOT;
return root; return root;
} }
RJP_tree_node* n = irjp_tree_search_value(root, value); RJP_tree_node* n = irjp_tree_search_value(root, key);
if(!n){ if(!n){
*status = RJP_TREE_ERR_NOT_FOUND; *status = RJP_TREE_ERR_NOT_FOUND;
return root; return root;