From cfab1988216cd8d68ca44eeec8bdcf72014f500a Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 25 Nov 2018 06:57:32 -0800 Subject: [PATCH] removed main function and some debug stuff. removed reversal functions --- include/rjp.h | 40 +++++++++++- src/rjp.c | 168 +++++++++----------------------------------------- 2 files changed, 66 insertions(+), 142 deletions(-) diff --git a/include/rjp.h b/include/rjp.h index f14ace8..07563bc 100644 --- a/include/rjp.h +++ b/include/rjp.h @@ -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 diff --git a/src/rjp.c b/src/rjp.c index 3f9a586..6fc5647 100644 --- a/src/rjp.c +++ b/src/rjp.c @@ -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); -}