From 7a26cdac8362595156383d889aea63c81d3c0007 Mon Sep 17 00:00:00 2001 From: lixianjing Date: Thu, 23 Nov 2023 07:45:44 +0800 Subject: [PATCH] improve object default --- docs/changes.md | 3 ++ src/tkc/object_default.c | 87 ++++++++++++++++++++++++++++++++++-- src/tkc/object_default.h | 12 +++++ tests/object_default_test.cc | 21 +++++++++ 4 files changed, 120 insertions(+), 3 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index 94bd61af8..eb112cdf9 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,5 +1,8 @@ # 最新动态 +2023/11/23 + * object\_default支持设置属性时保持属性类型不变。 + 2023/11/21 * 修正了编译Win32平台时缺少inet_ntop函数定义的问题,还有几个文件缺少bom头的问题(感谢陈谭提供补丁) diff --git a/src/tkc/object_default.c b/src/tkc/object_default.c index 6963371b7..750900249 100644 --- a/src/tkc/object_default.c +++ b/src/tkc/object_default.c @@ -79,6 +79,75 @@ static ret_t object_default_remove_prop(tk_object_t* obj, const char* name) { } } +static ret_t value_deep_copy_keep_type(value_t* dst, value_t* src) { + ret_t ret = RET_OK; + return_value_if_fail(dst != NULL && src != NULL, RET_BAD_PARAMS); + + switch (dst->type) { + case VALUE_TYPE_BOOL: { + value_set_bool(dst, value_bool(src)); + break; + } + case VALUE_TYPE_INT8: { + value_set_int8(dst, value_int8(src)); + break; + } + case VALUE_TYPE_UINT8: { + value_set_uint8(dst, value_uint8(src)); + break; + } + case VALUE_TYPE_INT16: { + value_set_int16(dst, value_int16(src)); + break; + } + case VALUE_TYPE_UINT16: { + value_set_uint16(dst, value_uint16(src)); + break; + } + case VALUE_TYPE_INT32: { + value_set_int32(dst, value_int32(src)); + break; + } + case VALUE_TYPE_UINT32: { + value_set_uint32(dst, value_uint32(src)); + break; + } + case VALUE_TYPE_INT64: { + value_set_int64(dst, value_int64(src)); + break; + } + case VALUE_TYPE_UINT64: { + value_set_uint64(dst, value_uint64(src)); + break; + } + case VALUE_TYPE_FLOAT: { + value_set_float(dst, value_float(src)); + break; + } + case VALUE_TYPE_DOUBLE: { + value_set_double(dst, value_double(src)); + break; + } + case VALUE_TYPE_STRING: { + value_reset(dst); + value_dup_str(dst, value_str(src)); + break; + } + default: { + if (dst->type == src->type) { + value_reset(dst); + value_deep_copy(dst, src); + } else { + ret = RET_FAIL; + log_debug("not support type:%d\n", dst->type); + } + break; + } + } + + return ret; +} + static ret_t object_default_set_prop(tk_object_t* obj, const char* name, const value_t* v) { value_t* vv = NULL; ret_t ret = RET_NOT_FOUND; @@ -94,9 +163,12 @@ static ret_t object_default_set_prop(tk_object_t* obj, const char* name, const v vv = object_default_find_prop_by_name(obj, name); if (vv != NULL) { - ret = RET_OK; - value_reset(vv); - value_deep_copy(vv, v); + if (o->keep_prop_type) { + ret = value_deep_copy_keep_type(vv, v); + } else { + value_reset(vv); + ret = value_deep_copy(vv, v); + } } else { named_value_t* nv = named_value_create_ex(name, v); return_value_if_fail(nv != NULL, RET_OOM); @@ -251,6 +323,15 @@ tk_object_t* object_default_clone(object_default_t* o) { return dup; } +ret_t object_default_set_keep_prop_type(tk_object_t* obj, bool_t keep_prop_type) { + object_default_t* o = OBJECT_DEFAULT(obj); + return_value_if_fail(o != NULL, RET_BAD_PARAMS); + + o->keep_prop_type = keep_prop_type; + + return RET_OK; +} + object_default_t* object_default_cast(tk_object_t* obj) { return_value_if_fail(obj != NULL && obj->vt == &s_object_default_vtable, NULL); return (object_default_t*)(obj); diff --git a/src/tkc/object_default.h b/src/tkc/object_default.h index 3793f6c51..d17542b54 100644 --- a/src/tkc/object_default.h +++ b/src/tkc/object_default.h @@ -66,6 +66,8 @@ typedef struct _object_default_t { /*private*/ darray_t props; bool_t enable_path; + /*设置属性值不改变属性的类型*/ + bool_t keep_prop_type; } object_default_t; /** @@ -131,6 +133,16 @@ ret_t object_default_unref(tk_object_t* obj); */ ret_t object_default_clear_props(tk_object_t* obj); +/** + * @method object_default_set_keep_prop_type + * 设置属性值时不改变属性的类型。 + * @annotation ["scriptable"] + * @param {tk_object_t*} obj 对象。 + * @param {bool_t} keep_prop_type 不改变属性的类型。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t object_default_set_keep_prop_type(tk_object_t* obj, bool_t keep_prop_type); + /** * @method object_default_find_prop * diff --git a/tests/object_default_test.cc b/tests/object_default_test.cc index 829bdacd4..1aa95ccbf 100644 --- a/tests/object_default_test.cc +++ b/tests/object_default_test.cc @@ -731,3 +731,24 @@ TEST(ObjectDefault, to_json2) { TK_OBJECT_UNREF(detail); str_reset(&str); } + +TEST(ObjectDefault, keep_type) { + value_t v; + tk_object_t* obj = object_default_create(); + object_default_t* o = OBJECT_DEFAULT(obj); + object_default_set_keep_prop_type(obj, TRUE); + ASSERT_EQ(o->keep_prop_type, TRUE); + + tk_object_set_prop_int32(obj, "int32", 123); + ASSERT_EQ(tk_object_get_prop_int32(obj, "int32", 0), 123); + ASSERT_EQ(tk_object_get_prop(obj, "int32", &v), RET_OK); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + + tk_object_set_prop_float(obj, "int32", 456); + ASSERT_EQ(tk_object_get_prop(obj, "int32", &v), RET_OK); + ASSERT_EQ(v.type, VALUE_TYPE_INT32); + ASSERT_EQ(value_int32(&v), 456); + + TK_OBJECT_UNREF(obj); +} +