removed main function and some debug stuff. removed reversal functions

This commit is contained in:
rexy712 2018-11-25 06:57:32 -08:00
parent b125c35f25
commit cfab198821
2 changed files with 66 additions and 142 deletions

View File

@ -51,12 +51,14 @@ struct JSON_string{
//keep a linked list of all members of a given object
struct JSON_object{
struct JSON_object_member* members;
struct JSON_object_member* last;
size_t num_members;
};
//keep array plus length
struct JSON_array{
struct JSON_array_element* elements;
struct JSON_array_element* last;
size_t num_elements;
};
@ -86,9 +88,43 @@ struct JSON_object_member{
struct JSON_object_member* next;
};
void free_json(struct JSON_value* root);
struct JSON_value* parse_json(const char* str);
//read in json and convert to easy to work with format
struct JSON_value* rjp_parse(const char* str);
//deallocate a json handle
void rjp_free(struct JSON_value* root);
struct JSON_object_member* rjp_get_members(struct JSON_object* j);
struct JSON_object_member* rjp_next_member(struct JSON_object_member* j);
struct JSON_object* rjp_member_parent(struct JSON_object_member* j);
struct JSON_value* rjp_get_member_value(struct JSON_object_member* j);
enum JSON_type rjp_get_member_type(struct JSON_object_member* j);
enum JSON_type rjp_get_value_type(struct JSON_value* j);
//initialize an empty json handle (outputting to string would result in '{}')
struct JSON_value* rjp_init_json(void);
//initialize an empty json object
struct JSON_object* rjp_init_object(void);
//initialize an empty json array
struct JSON_array* rjp_init_array(void);
//add a member to a json object
struct JSON_value* rjp_add_member(struct JSON_object* dest, const char* key, size_t keylen, struct JSON_value* value);
//add an element to a json array
struct JSON_value* rjp_add_element(struct JSON_array* dest, struct JSON_value* value);
struct JSON_value* rjp_init_integer(long i);
struct JSON_value* rjp_init_dfloat(double d);
struct JSON_value* rjp_init_boolean(char b);
struct JSON_value* rjp_init_string(const char* str, size_t len);
/*struct JSON_value* root = rjp_init_json();
rjp_add_member(root, "intel_backlight", 15, rjp_init_integer(100));
rjp_free(root);
//{intel_backlight:100}
*/
#ifdef __cplusplus
}
#endif

168
src/rjp.c
View File

@ -61,23 +61,31 @@ MAYBE_UNUSED static void add_member(struct JSON_value* j, const char* str, size_
//add an element to an array
static void add_element(struct JSON_value* j){
++j->array.num_elements;
struct JSON_array_element* prev = j->array.elements;
j->array.elements = calloc(1, sizeof(struct JSON_array_element));
j->array.elements->next = prev;
if(!j->array.elements){
j->array.elements = calloc(1, sizeof(struct JSON_array_element));
j->array.last = j->array.elements;
}else{
j->array.last->next = calloc(1, sizeof(struct JSON_array_element));
j->array.last = j->array.last->next;
}
}
//create member of the object as a linked list member and assign a name with no name allocation
static void add_member_no_alloc(struct JSON_value* j, char* str, size_t len){
++j->object.num_members;
struct JSON_object_member* prev = j->object.members;
j->object.members = calloc(1, sizeof(struct JSON_object_member));
j->object.members->name.value = str;
j->object.members->name.length = len;
j->object.members->next = prev;
if(!j->object.members){
j->object.members = calloc(1, sizeof(struct JSON_object_member));
j->object.last = j->object.members;
}else{
j->object.last->next = calloc(1, sizeof(struct JSON_object_member));
j->object.last = j->object.last->next;
}
j->object.last->name.value = str;
j->object.last->name.length = len;
}
static struct JSON_value* add_element_to_array(struct JSON_value* curr, struct JSON_state* state, struct JSON_value* element){
struct JSON_value* tmp = &curr->object.members->value;
for(int i = state->in_array-1;i > 0;--i, tmp = &tmp->array.elements->value);
for(int i = state->in_array-1;i > 0;--i, tmp = &tmp->array.last->value);
add_element(tmp);
tmp->array.elements->value = *element;
return &tmp->array.elements->value;
@ -143,34 +151,6 @@ static struct JSON_value* add_null(struct JSON_value* curr, struct JSON_state* s
return &curr->object.members->value;
}
static void reverse_array_order(struct JSON_value* curr){
struct JSON_array_element* tmp = curr->object.members->value.array.elements;
struct JSON_array_element* next = tmp->next;
struct JSON_array_element* new_start = next;
tmp->next = NULL;
while(new_start){
next = next->next;
new_start->next = tmp;
tmp = new_start;
new_start = next;
}
curr->object.members->value.array.elements = tmp;
}
//since we save everything in reverse order, swap it around so it's all good
static void reverse_object_order(struct JSON_value* curr){
struct JSON_object_member* tmp = curr->object.members;
struct JSON_object_member* next = tmp->next;
curr->object.members = next;
tmp->next = NULL;
while(curr->object.members){
next = next->next;
curr->object.members->next = tmp;
tmp = curr->object.members;
curr->object.members = next;
}
curr->object.members = tmp;
}
static void free_json_recurse(struct JSON_value* root);
static void free_json_array(struct JSON_value* root){
@ -204,7 +184,9 @@ static void free_json_recurse(struct JSON_value* root){
}
}
//Same as recurse but also frees root node
void free_json(struct JSON_value* root){
void rjp_free(struct JSON_value* root){
if(!root)
return;
free_json_recurse(root);
free(root);
}
@ -216,7 +198,7 @@ MAYBE_UNUSED static int is_array_empty(struct JSON_value* curr){
}
#define syntax_error(msg, row, column)\
do{fprintf(stderr, "Syntax error! %s (%i:%i)\n", msg, row, column);free_json(root);return NULL;}while(0)
do{fprintf(stderr, "Syntax error! %s (%i:%i)\n", msg, row, column);rjp_free(root);return NULL;}while(0)
//Convert escape sequences in strings
static char* parse_string(struct JSON_value* root, const char* str, int* len, int* row, int* column){
@ -276,7 +258,7 @@ static char* parse_string(struct JSON_value* root, const char* str, int* len, in
}
#define MAX_DEPTH 16
struct JSON_value* parse_json(const char* str){
struct JSON_value* rjp_parse(const char* str){
struct JSON_value* root = 0;
struct JSON_value* curr = 0;
int row = 1, column = 0;
@ -367,13 +349,11 @@ struct JSON_value* parse_json(const char* str){
if(top->in_array){
syntax_error("Unexpected end of object within array!", row, column);
}
reverse_object_order(curr);
curr = curr->parent;
if(top != state_stack)
--top;
//end of array
}else if(c == ']' && top->in_array){
reverse_array_order(curr);
--top->in_array;
//unrecognized character
}else if(!is_whitespace(c)){
@ -477,113 +457,21 @@ struct JSON_value* parse_json(const char* str){
#undef syntax_error
struct JSON_object_member* get_members(struct JSON_object* j){
struct JSON_object_member* rjp_get_members(struct JSON_object* j){
return j->members;
}
struct JSON_object_member* next_member(struct JSON_object_member* j){
struct JSON_object_member* rjp_next_member(struct JSON_object_member* j){
return j->next;
}
struct JSON_object* member_parent(struct JSON_object_member* j){
struct JSON_object* rjp_member_parent(struct JSON_object_member* j){
return &j->value.parent->object;
}
struct JSON_value* get_member_value(struct JSON_object_member* j){
struct JSON_value* rjp_get_member_value(struct JSON_object_member* j){
return &j->value;
}
enum JSON_type get_member_type(struct JSON_object_member* j){
enum JSON_type rjp_get_member_type(struct JSON_object_member* j){
return j->value.type;
}
enum JSON_type get_value_type(struct JSON_value* j){
enum JSON_type rjp_get_value_type(struct JSON_value* j){
return j->type;
}
void dump_json(struct JSON_object* root_obj);
void dump_array(struct JSON_array* root){
struct JSON_array_element* element_list = root->elements;
for(;element_list != NULL;element_list = element_list->next){
switch(element_list->value.type){
case json_integer:
printf("integer: %li\n", element_list->value.integer);
break;
case json_dfloat:
printf("double: %lf\n", element_list->value.dfloat);
break;
case json_boolean:
printf("boolean: %i\n", element_list->value.boolean);
break;
case json_null:
printf("null\n");
break;
case json_string:
printf("string: %s\n", element_list->value.string.value);
break;
case json_array:
printf("array\n");
dump_array(&element_list->value.array);
break;
case json_object:
printf("object\n");
dump_json(&element_list->value.object);
break;
};
}
}
void dump_json(struct JSON_object* root_obj){
struct JSON_object_member* member_list = get_members(root_obj);
for(;member_list != NULL;member_list = next_member(member_list)){
switch(get_member_type(member_list)){
case json_integer:
printf("integer: %li\n", member_list->value.integer);
break;
case json_dfloat:
printf("double: %lf\n", member_list->value.dfloat);
break;
case json_boolean:
printf("boolean: %i\n", member_list->value.boolean);
break;
case json_null:
printf("null\n");
break;
case json_string:
printf("string: %s\n", member_list->value.string.value);
break;
case json_array:
printf("array\n");
dump_array(&member_list->value.array);
break;
case json_object:
printf("object\n");
dump_json(&member_list->value.object);
break;
};
}
}
int main(int argc, char** argv){
char* filename = "example.json";
if(argc > 1){
filename = argv[1];
}
FILE* fp = fopen(filename, "r");
if(!fp){
fprintf(stderr, "unable to open file\n");
return -1;
}
size_t filelength;
fseek(fp, 0, SEEK_END);
filelength = ftell(fp) + 1;
fseek(fp, 0, SEEK_SET);
char* str = calloc(1,filelength + 1);
if(!str)
fprintf(stderr, "Unable to allocate memory!");
fread(str, filelength, 1, fp);
fclose(fp);
struct JSON_value* root = parse_json(str);
struct JSON_object* root_obj = &root->object;
dump_json(root_obj);
free(str);
if(root)
free_json(root);
}