From 3627ad7d7c905cc5f8c9650bc97dbfc848a8629f Mon Sep 17 00:00:00 2001 From: Dan Staples Date: Fri, 7 Feb 2014 20:47:06 -0500 Subject: [PATCH] updated and added printing functions for lists and trees to output fully formatted JSON-style nested objects --- src/list.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/list.h | 14 +++++++++ src/tree.c | 91 +++++++++++++++++++++++++++++++++++++++++++++--------- src/tree.h | 7 +++++ 4 files changed, 188 insertions(+), 15 deletions(-) diff --git a/src/list.c b/src/list.c index a022078..c78c505 100644 --- a/src/list.c +++ b/src/list.c @@ -442,6 +442,12 @@ co_list_raw(char *output, const size_t olen, const co_obj_t *list) CHECK(read >= 0, "Failed to dump object."); CHECK(read + written < olen, "Data too large for buffer."); } + else if ((CO_TYPE(next->value) == _tree16) || (CO_TYPE(next->value) == _tree32)) + { + read = co_tree_raw(out, olen - written, next->value); + CHECK(read >= 0, "Failed to dump object."); + CHECK(read + written < olen, "Data too large for buffer."); + } else { read = co_obj_raw(&in, next->value); @@ -504,3 +510,88 @@ co_list_import(co_obj_t **list, const char *input, const size_t ilen) error: return -1; } + +static co_obj_t * +_co_list_print_i(co_obj_t *list, co_obj_t *current, void *_indent) +{ + if (current == list) return NULL; + + char *val = NULL; + int indent = *(int*)_indent; + + if ((CO_TYPE(current) == _tree16) || (CO_TYPE(current) == _tree32)) + { + co_tree_print_indent(current, indent); + } + else if ((CO_TYPE(current) == _list16) || (CO_TYPE(current) == _list32)) + { + co_list_print_indent(current, indent); + } + else + { + for (int i = 0; i < indent; i++) printf(" "); + co_obj_data(&val,current); + switch(CO_TYPE(current)) + { + case _float32: + case _float64: + printf("%f",*(float*)val); + break; + case _uint8: + case _int8: + printf("%d",*(int8_t*)val); + break; + case _uint16: + case _int16: + printf("%d",*(int16_t*)val); + break; + case _uint32: + case _int32: + printf("%ld",*(long*)val); + break; + case _uint64: + case _int64: + printf("%lld",*(long long*)val); + break; + case _str8: + case _str16: + case _str32: + printf("\"%s\"",val); + break; + case _bin8: + case _bin16: + case _bin32: + printf("%x",*(unsigned int*)val); + } + } + if (co_list_get_last(list) != current) + printf(","); + printf("\n"); + + return NULL; +} + +void +co_list_print_indent(co_obj_t *list, int indent) +{ + for (int i = 0; i < indent; i++) printf(" "); + printf("[\n"); + indent++; + co_list_parse(list, _co_list_print_i, &indent); + indent--; + for (int i = 0; i < indent; i++) printf(" "); + printf("]"); + if (!indent) printf("\n"); +} + +int +co_list_print(co_obj_t *list) +{ + CHECK_MEM(list); + + co_list_print_indent(list,0); + + return 1; +error: + return 0; +} diff --git a/src/list.h b/src/list.h index 0296e3a..c007f39 100644 --- a/src/list.h +++ b/src/list.h @@ -140,4 +140,18 @@ size_t co_list_raw(char *output, const size_t olen, const co_obj_t *list); * @param ilen length of input buffer */ size_t co_list_import(co_obj_t **list, const char *input, const size_t ilen); + +/** + * @brief print list with indent + * @param list list object to print + * @param indent level of indent + */ +void co_list_print_indent(co_obj_t *list, int indent); + +/** + * @brief print list + * @param list list object to print + */ +int co_list_print(co_obj_t *list); + #endif diff --git a/src/tree.c b/src/tree.c index 5504979..d98f51a 100644 --- a/src/tree.c +++ b/src/tree.c @@ -704,44 +704,105 @@ co_tree_import(co_obj_t **tree, const char *input, const size_t ilen) } static inline void -_co_tree_print_r(co_obj_t *tree, _treenode_t *current, int *count) +_co_tree_print_r(co_obj_t *tree, _treenode_t *current, int *count, int indent) { CHECK(IS_TREE(tree), "Recursion target is not a tree."); if(current == NULL) return; + char *key = NULL; - char *value = NULL; + char *val = NULL; + if(co_node_value(current) != NULL) { (*count)++; co_obj_data(&key, co_node_key(current)); - co_obj_data(&value, co_node_value(current)); - //CHECK(IS_STR(key) && IS_STR(value), "Incorrect types for profile."); - if(*count < co_tree_length(tree)) + co_obj_t *value = co_node_value(current); + + for (int i = 0; i < indent; i++) printf(" "); + printf("\"%s\": ",key); + + if ((CO_TYPE(value) == _tree16) || (CO_TYPE(value) == _tree32)) { - printf(" \"%s\": \"%s\", ", key, value); + printf("\n"); + for (int i = 0; i < indent; i++) printf(" "); + printf(" {\n"); + int new_count = 0; + _co_tree_print_r((co_obj_t*)value, co_tree_root((co_obj_t*)value),&new_count, indent+2); + for (int i = 0; i < indent; i++) printf(" "); + printf(" }"); + } + else if ((CO_TYPE(value) == _list16) || (CO_TYPE(value) == _list32)) + { + printf("\n"); + co_list_print_indent((co_obj_t*)value,indent+1); } else { - printf(" \"%s\": \"%s\" ", key, value); + co_obj_data(&val,value); + switch(CO_TYPE(value)) + { + case _float32: + case _float64: + printf("%f",*(float*)val); + break; + case _uint8: + case _int8: + printf("%d",*(int8_t*)val); + break; + case _uint16: + case _int16: + printf("%d",*(int16_t*)val); + break; + case _uint32: + case _int32: + printf("%ld",*(long*)val); + break; + case _uint64: + case _int64: + printf("%lld",*(long long*)val); + break; + case _str8: + case _str16: + case _str32: + printf("\"%s\"",val); + break; + case _bin8: + case _bin16: + case _bin32: + printf("%x",*(unsigned int*)val); + } } + if(*count < co_tree_length(tree)) + printf(","); + printf("\n"); } - _co_tree_print_r(tree, current->low, count); - _co_tree_print_r(tree, current->equal, count); - _co_tree_print_r(tree, current->high, count); - return; + _co_tree_print_r(tree, current->low, count, indent); + _co_tree_print_r(tree, current->equal, count, indent); + _co_tree_print_r(tree, current->high, count, indent); + return; error: return; } +void +co_tree_print_indent(co_obj_t *tree, int indent) +{ + int count = 0; + + for (int i = 0; i < indent; i++) printf(" "); + printf("{\n"); + _co_tree_print_r(tree, co_tree_root(tree), &count, indent+1); + for (int i = 0; i < indent; i++) printf(" "); + printf("}"); + if (!indent) printf("\n"); +} + int co_tree_print(co_obj_t *tree) { CHECK_MEM(tree); - int count = 0; - printf("{"); - _co_tree_print_r(tree, co_tree_root(tree), &count); - printf("}\n"); + co_tree_print_indent(tree,0); return 1; error: diff --git a/src/tree.h b/src/tree.h index e12ff28..ef8db4f 100644 --- a/src/tree.h +++ b/src/tree.h @@ -192,6 +192,13 @@ size_t co_tree_raw(char *output, const size_t olen, const co_obj_t *tree); */ size_t co_tree_import(co_obj_t **tree, const char *input, const size_t ilen); +/** + * @brief print tree with indent + * @param tree tree object to print + * @param indent level of indent + */ +void co_tree_print_indent(co_obj_t *tree, int indent); + /** * @brief print tree * @param tree tree object to print