Add pretty printing

This commit is contained in:
rexy712 2019-10-29 13:34:42 -07:00
parent 0df7efabb7
commit 688dd22c73
4 changed files with 136 additions and 32 deletions

View File

@ -34,6 +34,10 @@ extern "C"{
#define RJP_float double
#endif
//used with rjp_to_json
#define RJP_FORMAT_NONE 0
#define RJP_FORMAT_PRETTY 1
//type of data
typedef enum RJP_type{
json_object = 0,
@ -190,7 +194,7 @@ size_t rjp_dump_object(const RJP_value* root, char* dest);
//Convert RJP_array to json string
size_t rjp_dump_array(const RJP_value* arr, char* dest);
//Convert root rjp value into json string
char* rjp_to_json(const RJP_value* root);
char* rjp_to_json(const RJP_value* root, int pretty);
#ifdef __cplusplus
}

View File

@ -27,6 +27,7 @@ char* irjp_parse_string(RJP_value* root, const char* str, int* inclen, int* len,
size_t irjp_array_strlen(const RJP_value* arr);
size_t irjp_object_strlen(const RJP_value* root);
size_t irjp_value_strlen(const RJP_value* root);
size_t irjp_value_strlen_pretty(const RJP_value* root, int depth);
void irjp_strcpy(RJP_string* dest, const RJP_string* src);
#endif

View File

@ -66,6 +66,77 @@ static size_t irjp_write_value(char* dest, const RJP_value* val){
};
return ret;
}
static size_t irjp_write_value_pretty(char* dest, const RJP_value* val, int depth);
static size_t irjp_dump_array_pretty(const RJP_value* arr, char* dest, int depth){
const RJP_array* array = &arr->array;
const RJP_array_element* element_list = array->elements;
size_t pos = 2;
sprintf(dest, "[\n");
for(;element_list;element_list = element_list->next){
for(int i = 0;i < (depth+1);++i)
pos += sprintf(dest+pos, "\t");
pos += irjp_write_value_pretty(dest+pos, &element_list->value, depth+1);
if(element_list->next)
pos += sprintf(dest+pos, ",");
pos += sprintf(dest+pos, "\n");
}
for(int i = 0;i < depth;++i)
pos += sprintf(dest+pos, "\t");
pos += sprintf(dest+pos, "]");
return pos;
}
static size_t irjp_dump_object_pretty(const RJP_value* root, char* dest, int depth){
const RJP_object* root_obj = &root->object;
const RJP_object_member* member_list = root_obj->members;
size_t pos = 2;
sprintf(dest, "{\n");
for(;member_list;member_list = member_list->next){
for(int i = 0;i < (depth+1);++i)
pos += sprintf(dest+pos, "\t");
pos += sprintf(dest+pos, "\"%s\": ", member_list->name.value);
pos += irjp_write_value_pretty(dest+pos, &member_list->value, depth+1);
if(member_list->next)
pos += sprintf(dest+pos, ",");
pos += sprintf(dest+pos, "\n");
}
for(int i = 0;i < depth;++i)
pos += sprintf(dest+pos, "\t");
pos += sprintf(dest+pos, "}");
return pos;
}
static size_t irjp_write_value_pretty(char* dest, const RJP_value* val, int depth){
size_t ret;
switch(val->type){
case json_integer:
ret = sprintf(dest, "%" PRId64, val->integer);
break;
case json_dfloat:
ret = sprintf(dest, "%lf", val->dfloat);
break;
case json_boolean:
ret = sprintf(dest, val->boolean ? "true" : "false");
break;
case json_null:
ret = sprintf(dest, "null");
break;
case json_string:;
ret = sprintf(dest, "\"%s\"", val->string.value);
break;
case json_array:
ret = irjp_dump_array_pretty(val, dest, depth);
break;
case json_object:
ret = irjp_dump_object_pretty(val, dest, depth);
break;
default:
ret = 0;
break;
};
return ret;
}
size_t rjp_dump_array(const RJP_value* arr, char* dest){
const RJP_array* array = &arr->array;
@ -103,16 +174,19 @@ size_t rjp_dump_object(const RJP_value* root, char* dest){
return pos;
}
char* rjp_to_json(const RJP_value* root){
char* rjp_to_json(const RJP_value* root, int pretty){
if(!root)
return NULL;
size_t len = irjp_value_strlen(root);
size_t len = pretty ? irjp_value_strlen_pretty(root, 0) : irjp_value_strlen(root);
if(!len)
return NULL;
char* tmp = rjp_alloc(len + 1);
tmp[len] = 0;
irjp_write_value(tmp, root);
if(pretty)
irjp_write_value_pretty(tmp, root, 0);
else
irjp_write_value(tmp, root);
return tmp;
}

View File

@ -302,33 +302,23 @@ size_t irjp_array_strlen(const RJP_value* arr){
const RJP_array* array = &arr->array;
const RJP_array_element* element_list = array->elements;
for(;element_list;element_list = element_list->next){
switch(element_list->value.type){
case json_integer:
count += snprintf(NULL, 0, "%" PRId64, element_list->value.integer);
break;
case json_dfloat:
count += snprintf(NULL, 0, "%lf", element_list->value.dfloat);
break;
case json_boolean:
count += element_list->value.boolean ? 4 : 5;
break;
case json_null:
count += 4;
break;
case json_string:
count += element_list->value.string.length;
break;
case json_array:
count += irjp_array_strlen(&element_list->value);
break;
case json_object:
count += irjp_object_strlen(&element_list->value);
break;
};
count += irjp_value_strlen(&element_list->value);
if(element_list->next)
++count;
else
break;
++count; //,
}
return count;
}
size_t irjp_array_strlen_pretty(const RJP_value* arr, int depth){
size_t count = 3 + depth; //[\n\t]
++depth;
const RJP_array* array = &arr->array;
const RJP_array_element* element_list = array->elements;
for(;element_list;element_list = element_list->next){
count += irjp_value_strlen_pretty(&element_list->value, depth);
count += depth; //tabs
++count; //newline
if(element_list->next)
++count; //,
}
return count;
}
@ -344,8 +334,23 @@ size_t irjp_object_strlen(const RJP_value* root){
count += irjp_value_strlen(&member_list->value);
if(member_list->next)
++count; //,
else
break;
}
return count;
}
size_t irjp_object_strlen_pretty(const RJP_value* root, int depth){
size_t count = 3 + depth; //{\n\t}
++depth;
const RJP_object* root_obj = &root->object;
const RJP_object_member* member_list = root_obj->members;
for(;member_list;member_list = member_list->next){
if(member_list->name.length == 0 || member_list->name.value[0] == 0)
return 0;
count += member_list->name.length + 4; //"":space
count += irjp_value_strlen_pretty(&member_list->value, depth);
count += depth; //tabs
++count; //newline
if(member_list->next)
++count; //,
}
return count;
}
@ -370,3 +375,23 @@ size_t irjp_value_strlen(const RJP_value* root){
return 0;
};
}
size_t irjp_value_strlen_pretty(const RJP_value* root, int depth){
switch(root->type){
case json_integer:
return snprintf(NULL, 0, "%" PRId64, root->integer);
case json_dfloat:
return snprintf(NULL, 0, "%lf", root->dfloat);
case json_boolean:
return root->boolean ? 4 : 5; //true, false
case json_null:
return 4;
case json_string:
return rjp_escape_strlen(root->string.value) + 2; //"";
case json_array:
return irjp_array_strlen_pretty(root, depth);
case json_object:
return irjp_object_strlen_pretty(root, depth);
default:
return 0;
};
}