diff --git a/docs/changes.md b/docs/changes.md index 69592fe08..fedf0764b 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,5 +1,9 @@ # 最新动态 +2024/07/30 + * 增加函数 named_value_icompare/named_value_icompare_by_name + * object_default支持属性名大小写不敏感比较。 + 2024/07/24 * 修复assets_manager_unref接口删除资源错误的问题(感谢雨欣提供补丁) diff --git a/src/tkc/named_value.c b/src/tkc/named_value.c index e0859e165..24ea6b862 100644 --- a/src/tkc/named_value.c +++ b/src/tkc/named_value.c @@ -139,3 +139,16 @@ int32_t named_value_compare(named_value_t* nv, const named_value_t* other) { return tk_str_cmp(nv->name, other->name); } + + +int32_t named_value_icompare(named_value_t* nv, const named_value_t* other) { + return_value_if_fail(nv != NULL && other != NULL, -1); + + return tk_stricmp(nv->name, other->name); +} + +int32_t named_value_icompare_by_name(named_value_t* nv, const char* name) { + return_value_if_fail(nv != NULL && name != NULL, -1); + + return tk_stricmp(nv->name, name); +} diff --git a/src/tkc/named_value.h b/src/tkc/named_value.h index ad044cd6a..dbd009de8 100644 --- a/src/tkc/named_value.h +++ b/src/tkc/named_value.h @@ -172,6 +172,31 @@ int32_t named_value_compare(named_value_t* nv, const named_value_t* other); */ int32_t named_value_compare_by_name(named_value_t* nv, const char* name); + +/** + * @method named_value_icompare + * + * 大小写不敏感比较。 + * + * @param {named_value_t*} nv named_value对象。 + * @param {const named_value_t*} other named_value对象。 + * + * @return {int32_t} 返回RET_OK表示成功,否则表示失败。 + */ +int32_t named_value_icompare(named_value_t* nv, const named_value_t* other); + +/** + * @method named_value_icompare_by_name + * + * 大小写不敏感比较。 + * + * @param {named_value_t*} nv named_value对象。 + * @param {const char*} name 名称。 + * + * @return {int32_t} 返回RET_OK表示成功,否则表示失败。 + */ +int32_t named_value_icompare_by_name(named_value_t* nv, const char* name); + /** * @method named_value_destroy * diff --git a/src/tkc/object_default.c b/src/tkc/object_default.c index 54ed39a9c..a4679e7a9 100644 --- a/src/tkc/object_default.c +++ b/src/tkc/object_default.c @@ -24,6 +24,22 @@ #include "tkc/utils.h" #include "tkc/object_default.h" +static tk_compare_t object_default_get_cmp(object_default_t* o) { + if (o->name_case_insensitive) { + return (tk_compare_t)named_value_icompare; + } else { + return (tk_compare_t)named_value_compare; + } +} + +static tk_compare_t object_default_get_cmp_by_name(object_default_t* o) { + if (o->name_case_insensitive) { + return (tk_compare_t)named_value_icompare_by_name; + } else { + return (tk_compare_t)named_value_compare_by_name; + } +} + static value_t* object_default_find_prop_by_name(tk_object_t* obj, const char* name) { named_value_t* nv = NULL; object_default_t* o = OBJECT_DEFAULT(obj); @@ -34,7 +50,7 @@ static value_t* object_default_find_prop_by_name(tk_object_t* obj, const char* n return_value_if_fail(index < o->props.size, NULL); nv = (named_value_t*)(o->props.elms[index]); } else { - nv = darray_bsearch(&(o->props), (tk_compare_t)named_value_compare_by_name, (void*)name); + nv = darray_bsearch(&(o->props), object_default_get_cmp_by_name(o), (void*)name); } return nv != NULL ? &(nv->value) : NULL; @@ -71,7 +87,7 @@ static ret_t object_default_remove_prop(tk_object_t* obj, const char* name) { } } - index = darray_bsearch_index(&(o->props), (tk_compare_t)named_value_compare_by_name, (void*)name); + index = darray_bsearch_index(&(o->props), object_default_get_cmp_by_name(o), (void*)name); if (index >= 0) { return darray_remove_index(&(o->props), index); } else { @@ -172,7 +188,7 @@ static ret_t object_default_set_prop(tk_object_t* obj, const char* name, const v } else { named_value_t* nv = named_value_create_ex(name, v); return_value_if_fail(nv != NULL, RET_OOM); - ret = darray_sorted_insert(&(o->props), nv, (tk_compare_t)named_value_compare, FALSE); + ret = darray_sorted_insert(&(o->props), nv, object_default_get_cmp(o), FALSE); if (ret != RET_OK) { named_value_destroy(nv); } @@ -332,6 +348,15 @@ ret_t object_default_set_keep_prop_type(tk_object_t* obj, bool_t keep_prop_type) return RET_OK; } +ret_t object_default_set_name_case_insensitive(tk_object_t* obj, bool_t name_case_insensitive) { + object_default_t* o = OBJECT_DEFAULT(obj); + return_value_if_fail(o != NULL, RET_BAD_PARAMS); + + o->name_case_insensitive = name_case_insensitive; + + 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 2f1a702a4..f37e98939 100644 --- a/src/tkc/object_default.h +++ b/src/tkc/object_default.h @@ -68,6 +68,7 @@ typedef struct _object_default_t { bool_t enable_path; /*设置属性值不改变属性的类型*/ bool_t keep_prop_type; + bool_t name_case_insensitive; } object_default_t; /** @@ -143,6 +144,16 @@ ret_t object_default_clear_props(tk_object_t* obj); */ ret_t object_default_set_keep_prop_type(tk_object_t* obj, bool_t keep_prop_type); +/** + * @method object_default_set_name_case_insensitive + * 设置属性名是否大小写不敏感。 + * @annotation ["scriptable"] + * @param {tk_object_t*} obj 对象。 + * @param {bool_t} name_case_insensitive 属性名是否大小写不敏感。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t object_default_set_name_case_insensitive(tk_object_t* obj, bool_t name_case_insensitive); + /** * @method object_default_find_prop * diff --git a/tests/object_default_test.cc b/tests/object_default_test.cc index a91d25b0e..f4a536d34 100644 --- a/tests/object_default_test.cc +++ b/tests/object_default_test.cc @@ -764,3 +764,23 @@ TEST(ObjectDefault, set_proo_str_with_format) { TK_OBJECT_UNREF(obj); } + +TEST(ObjectDefault, case_insensitive) { + value_t v; + tk_object_t* obj = object_default_create(); + object_default_t* o = OBJECT_DEFAULT(obj); + + object_default_set_name_case_insensitive(obj, TRUE); + ASSERT_EQ(tk_object_set_prop(obj, "abc", value_set_int(&v, 50)), RET_OK); + ASSERT_EQ(o->props.size, 1u); + + ASSERT_EQ(tk_object_set_prop(obj, "ABC", value_set_int(&v, 150)), RET_OK); + ASSERT_EQ(o->props.size, 1u); + + ASSERT_EQ(tk_object_get_prop_int(obj, "abc", 0), 150); + + ASSERT_EQ(tk_object_remove_prop(obj, "aBC"), RET_OK); + ASSERT_EQ(o->props.size, 0u); + + TK_OBJECT_UNREF(obj); +}