Add pretty printing
This commit is contained in:
parent
0df7efabb7
commit
688dd22c73
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
80
src/output.c
80
src/output.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user