removed main function and some debug stuff. removed reversal functions
This commit is contained in:
parent
b125c35f25
commit
cfab198821
@ -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
168
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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user