improve conf json support indent

This commit is contained in:
lixianjing 2023-08-10 16:56:01 +08:00
parent 2291c39fd5
commit 39ef0ec844
4 changed files with 154 additions and 73 deletions

View File

@ -5,6 +5,7 @@
* 完善demoui text selector资源(感谢智明提供补丁)
* agge 模式增加 argb 和 abgr 的颜色支持(感谢智明提供补丁)
* 修复 awtk 使用 mingw 的时候,在 windows 下无法消除背后的 cmd 窗口(感谢智明提供补丁)
* 完善conf json支持按指定的方式缩进(感谢林福提供补丁)。
* 完善 event\_source\_manager\_default 让调用者有机会知道 select 是否失败(感谢林福提供补丁)。
2023/08/09

View File

@ -1,7 +1,7 @@
/**
* File: conf_json.c
* Author: AWTK Develop Team
* Brief: json
* Brief: json
*
* Copyright (c) 2020 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
@ -307,16 +307,20 @@ conf_doc_t* conf_doc_load_json(const char* data, int32_t size) {
return parser.doc;
}
static ret_t conf_json_save_node(conf_node_t* node, str_t* str, uint32_t level);
static ret_t conf_json_save_node_value(conf_node_t* node, str_t* str, uint32_t level);
static ret_t conf_json_save_node_children(conf_node_t* node, str_t* str, uint32_t level);
static ret_t conf_json_save_node(conf_node_t* node, str_t* str, uint32_t level, uint32_t indent);
static ret_t conf_json_save_node_value(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent);
static ret_t conf_json_save_node_children(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent);
static ret_t conf_json_save_node_value_object(conf_node_t* node, str_t* str, uint32_t level) {
return conf_json_save_node_children(node, str, level);
static ret_t conf_json_save_node_value_object(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
return conf_json_save_node_children(node, str, level, indent);
}
static ret_t conf_json_save_node_value_array(conf_node_t* node, str_t* str, uint32_t level) {
return conf_json_save_node_children(node, str, level);
static ret_t conf_json_save_node_value_array(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
return conf_json_save_node_children(node, str, level, indent);
}
static ret_t conf_json_save_node_value_simple(conf_node_t* node, str_t* str, uint32_t level) {
@ -356,87 +360,112 @@ static ret_t conf_json_save_node_value_simple(conf_node_t* node, str_t* str, uin
}
}
static ret_t conf_json_save_node_value(conf_node_t* node, str_t* str, uint32_t level) {
static ret_t conf_json_save_node_value(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
return_value_if_fail(node != NULL, RET_BAD_PARAMS);
if (node->node_type == CONF_NODE_OBJECT) {
return conf_json_save_node_value_object(node, str, level);
return conf_json_save_node_value_object(node, str, level, indent);
} else if (node->node_type == CONF_NODE_ARRAY) {
return conf_json_save_node_value_array(node, str, level);
return conf_json_save_node_value_array(node, str, level, indent);
} else {
return conf_json_save_node_value_simple(node, str, level);
}
}
static ret_t conf_json_write_indent(str_t* str, int32_t level) {
uint32_t i = 0;
if (level < 0) {
static ret_t conf_json_write_indent(str_t* str, int32_t level, uint32_t indent) {
if (level < 0 || indent == 0) {
return RET_OK;
}
for (i = 0; i < level; i++) {
return_value_if_fail(str_append(str, " ") == RET_OK, RET_OOM);
return str_append_n_chars(str, ' ', level * indent);
}
static ret_t conf_json_save_node(conf_node_t* node, str_t* str, uint32_t level, uint32_t indent) {
const char* name = conf_node_get_name(node);
if (indent > 0) {
return_value_if_fail(conf_json_write_indent(str, level, indent) == RET_OK, RET_OOM);
return_value_if_fail(str_append_more(str, "\"", name, "\" : ", NULL) == RET_OK, RET_OOM);
} else {
return_value_if_fail(str_append_more(str, "\"", name, "\":", NULL) == RET_OK, RET_OOM);
}
return RET_OK;
return conf_json_save_node_value(node, str, level, indent);
}
static ret_t conf_json_save_node(conf_node_t* node, str_t* str, uint32_t level) {
const char* name = conf_node_get_name(node);
return_value_if_fail(conf_json_write_indent(str, level) == RET_OK, RET_OOM);
return_value_if_fail(str_append_more(str, "\"", name, "\" : ", NULL) == RET_OK, RET_OOM);
return conf_json_save_node_value(node, str, level);
}
static ret_t conf_json_save_node_children_object(conf_node_t* node, str_t* str, uint32_t level) {
static ret_t conf_json_save_node_children_object(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
conf_node_t* iter = conf_node_get_first_child(node);
return_value_if_fail(node != NULL, RET_BAD_PARAMS);
return_value_if_fail(str_append(str, "{\n") == RET_OK, RET_OOM);
while (iter != NULL) {
return_value_if_fail(conf_json_save_node(iter, str, level + 1) == RET_OK, RET_OOM);
iter = iter->next;
if (iter != NULL) {
return_value_if_fail(str_append(str, ",\n") == RET_OK, RET_OOM);
}
if (indent > 0) {
return_value_if_fail(str_append(str, "{\n") == RET_OK, RET_OOM);
} else {
return_value_if_fail(str_append(str, "{") == RET_OK, RET_OOM);
}
return_value_if_fail(str_append(str, "\n") == RET_OK, RET_OOM);
return_value_if_fail(conf_json_write_indent(str, level) == RET_OK, RET_OOM);
while (iter != NULL) {
return_value_if_fail(conf_json_save_node(iter, str, level + 1, indent) == RET_OK, RET_OOM);
iter = iter->next;
if (iter != NULL) {
if (indent > 0) {
return_value_if_fail(str_append(str, ",\n") == RET_OK, RET_OOM);
} else {
return_value_if_fail(str_append(str, ",") == RET_OK, RET_OOM);
}
}
}
if (indent > 0) {
return_value_if_fail(str_append(str, "\n") == RET_OK, RET_OOM);
return_value_if_fail(conf_json_write_indent(str, level, indent) == RET_OK, RET_OOM);
}
return_value_if_fail(str_append(str, "}") == RET_OK, RET_OOM);
return RET_OK;
}
static ret_t conf_json_save_node_children_array(conf_node_t* node, str_t* str, uint32_t level) {
static ret_t conf_json_save_node_children_array(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
conf_node_t* iter = conf_node_get_first_child(node);
return_value_if_fail(node != NULL, RET_BAD_PARAMS);
return_value_if_fail(str_append(str, "[\n") == RET_OK, RET_OOM);
if (indent > 0) {
return_value_if_fail(str_append(str, "[\n") == RET_OK, RET_OOM);
} else {
return_value_if_fail(str_append(str, "[") == RET_OK, RET_OOM);
}
while (iter != NULL) {
return_value_if_fail(conf_json_write_indent(str, level + 1) == RET_OK, RET_OOM);
return_value_if_fail(conf_json_save_node_value(iter, str, level + 1) == RET_OK, RET_OOM);
return_value_if_fail(conf_json_write_indent(str, level + 1, indent) == RET_OK, RET_OOM);
return_value_if_fail(conf_json_save_node_value(iter, str, level + 1, indent) == RET_OK,
RET_OOM);
iter = iter->next;
if (iter != NULL) {
return_value_if_fail(str_append(str, ",\n") == RET_OK, RET_OOM);
if (indent > 0) {
return_value_if_fail(str_append(str, ",\n") == RET_OK, RET_OOM);
} else {
return_value_if_fail(str_append(str, ",") == RET_OK, RET_OOM);
}
}
}
return_value_if_fail(str_append(str, "\n") == RET_OK, RET_OOM);
return_value_if_fail(conf_json_write_indent(str, level) == RET_OK, RET_OOM);
if (indent > 0) {
return_value_if_fail(str_append(str, "\n") == RET_OK, RET_OOM);
return_value_if_fail(conf_json_write_indent(str, level, indent) == RET_OK, RET_OOM);
}
return_value_if_fail(str_append(str, "]") == RET_OK, RET_OOM);
return RET_OK;
}
static ret_t conf_json_save_node_children(conf_node_t* node, str_t* str, uint32_t level) {
static ret_t conf_json_save_node_children(conf_node_t* node, str_t* str, uint32_t level,
uint32_t indent) {
return_value_if_fail(node != NULL, RET_BAD_PARAMS);
if (node->node_type == CONF_NODE_OBJECT) {
return conf_json_save_node_children_object(node, str, level);
return conf_json_save_node_children_object(node, str, level, indent);
} else if (node->node_type == CONF_NODE_ARRAY) {
return conf_json_save_node_children_array(node, str, level);
return conf_json_save_node_children_array(node, str, level, indent);
} else {
assert(!"invalid type");
return RET_FAIL;
@ -447,7 +476,14 @@ ret_t conf_doc_save_json(conf_doc_t* doc, str_t* str) {
return_value_if_fail(doc != NULL && doc->root != NULL && str != NULL, RET_BAD_PARAMS);
str_set(str, "");
return conf_json_save_node_children(doc->root, str, 0);
return conf_json_save_node_children(doc->root, str, 0, 4);
}
ret_t conf_doc_save_json_ex(conf_doc_t* doc, str_t* str, uint32_t indent) {
return_value_if_fail(doc != NULL && doc->root != NULL && str != NULL, RET_BAD_PARAMS);
str_set(str, "");
return conf_json_save_node_children(doc->root, str, 0, indent);
}
static conf_doc_t* conf_doc_load_json_reader(data_reader_t* reader) {
@ -509,7 +545,7 @@ tk_object_t* conf_json_create(void) {
}
tk_object_t* conf_json_load_from_buff(const void* buff, uint32_t size, bool_t create_if_not_exist) {
char url[MAX_PATH+1] = {0};
char url[MAX_PATH + 1] = {0};
return_value_if_fail(buff != NULL, NULL);
data_reader_mem_build_url(buff, size, url);

View File

@ -1,7 +1,7 @@
/**
* File: json.h
* Author: AWTK Develop Team
* Brief: json
* Brief: json
*
* Copyright (c) 2020 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
@ -32,40 +32,40 @@ BEGIN_C_DECLS
* @class conf_json_t
* @parent tk_object_t
* @annotation ["fake"]
*
*
* conf json对象
*/
/**
* @method conf_json_create
* conf对象
* @method conf_json_create
* conf对象
* @annotation ["constructor"]
*
*
* @return {tk_object_t*}
*/
tk_object_t* conf_json_create(void);
/**
* @method conf_json_load
* URL加载JSON对象
* @method conf_json_load
* URL加载JSON对象
* @annotation ["constructor"]
*
*
* @param {const char*} url ()
* @param {bool_t} create_if_not_exist
*
* @param {bool_t} create_if_not_exist
*
* @return {tk_object_t*}
*/
tk_object_t* conf_json_load(const char* url, bool_t create_if_not_exist);
/**
* @method conf_json_load_from_buff
* JSON对象
* JSON对象
* @annotation ["constructor"]
*
*
* @param {const void*} buff
* @param {uint32_t} size
* @param {bool_t} create_if_not_exist
*
* @param {bool_t} create_if_not_exist
*
* @return {tk_object_t*}
*/
tk_object_t* conf_json_load_from_buff(const void* buff, uint32_t size, bool_t create_if_not_exist);
@ -73,10 +73,10 @@ tk_object_t* conf_json_load_from_buff(const void* buff, uint32_t size, bool_t cr
/**
* @method conf_json_save_to_buff
* obj保存为JSON格式到内存
*
*
* @param {tk_object_t*} obj doc对象
* @param {wbuffer_t*} wb (使wbuffer_deinit)
*
*
* @return {ret_t} RET_OK表示成功
*/
ret_t conf_json_save_to_buff(tk_object_t* obj, wbuffer_t* wb);
@ -85,38 +85,50 @@ ret_t conf_json_save_to_buff(tk_object_t* obj, wbuffer_t* wb);
* @method conf_json_save_as
* doc对象保存到指定URL
* @annotation ["static"]
*
*
* @param {tk_object_t*} obj doc对象
* @param {const char*} url
*
*
* @return {ret_t} RET_OK表示成功
*/
ret_t conf_json_save_as(tk_object_t* obj, const char* url);
/**
* @method conf_doc_load_json
*
* @method conf_doc_load_json
*
* @annotation ["global"]
*
*
* @param {const char*} data JSON数据
* @param {int32_t} size JSON数据长度
*
*
* @return {conf_doc_t*} doc对象
*/
conf_doc_t* conf_doc_load_json(const char* data, int32_t size);
/**
* @method conf_doc_save_json
*
* @method conf_doc_save_json
*
* @annotation ["global"]
*
*
* @param {conf_doc_t*} doc doc对象
* @param {str_t*} str
*
*
* @return {ret_t} RET_OK表示成功
*/
ret_t conf_doc_save_json(conf_doc_t* doc, str_t* str);
/**
* @method conf_doc_save_json_ex
*
*
* @param {conf_doc_t*} doc doc对象
* @param {str_t*} str
* @param {uint32_t} indent
*
* @return {ret_t} ret_t值
*/
ret_t conf_doc_save_json_ex(conf_doc_t* doc, str_t* str, uint32_t indent);
END_C_DECLS
#endif /*TK_CONF_JSON_H*/

View File

@ -664,3 +664,35 @@ TEST(Json, uint32) {
str_reset(&str);
TK_OBJECT_UNREF(conf);
}
TEST(ConfJson, save_json_ex) {
value_t v;
str_t str;
conf_doc_t* doc = conf_doc_create(100);
str_init(&str, 0);
ASSERT_EQ(conf_doc_set(doc, "[0].label", value_set_str(&v, "jim")), RET_OK);
ASSERT_EQ(conf_doc_set(doc, "[1].label", value_set_str(&v, "jim1")), RET_OK);
ASSERT_EQ(conf_doc_set(doc, "[2].label", value_set_str(&v, "jim2")), RET_OK);
ASSERT_EQ(conf_doc_set(doc, "[0].nodes.[0].name", value_set_str(&v, "timer")), RET_OK);
ASSERT_EQ(conf_doc_set(doc, "[0].nodes.[0].last_out", value_set_int(&v, 1111)), RET_OK);
ASSERT_EQ(conf_doc_set(doc, "[0].nodes.[1].last_out", value_set_int(&v, 1111)), RET_OK);
ASSERT_EQ(conf_doc_save_json_ex(doc, &str, 0), RET_OK);
log_info("\n%s\n\n", str.str);
ASSERT_STREQ(str.str,
"[{\"label\":\"jim\",\"nodes\":[{\"name\":\"timer\",\"last_out\":1111},{\"last_"
"out\":1111}]},{\"label\":\"jim1\"},{\"label\":\"jim2\"}]");
ASSERT_EQ(conf_doc_save_json_ex(doc, &str, 2), RET_OK);
log_info("\n%s\n\n", str.str);
ASSERT_STREQ(str.str,
"[\n {\n \"label\" : \"jim\",\n \"nodes\" : [\n {\n \"name\" : "
"\"timer\",\n \"last_out\" : 1111\n },\n {\n \"last_out\" : "
"1111\n }\n ]\n },\n {\n \"label\" : \"jim1\"\n },\n {\n "
"\"label\" : \"jim2\"\n }\n]");
conf_doc_destroy(doc);
str_reset(&str);
}