add object_get_prop_by_path

This commit is contained in:
lixianjing 2019-09-19 14:11:22 +08:00
parent d875b44f0c
commit cb5cd61d99
6 changed files with 181 additions and 19 deletions

View File

@ -2,6 +2,8 @@
* 2019/09/19
* 修改"color\_component" "digit\_clock" "mutable\_image"的注释支持designer编辑感谢大恒提供补丁
* 增加object\_array
* 增加object\_get\_prop\_by\_path
* 2019/09/18
* 增加iostream\_mem。

View File

@ -90,10 +90,10 @@ object_t* object_ref(object_t* obj) {
return obj;
}
ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
static ret_t object_get_prop_by_name(object_t* obj, const char* name, value_t* v) {
ret_t ret = RET_NOT_FOUND;
return_value_if_fail(obj != NULL && obj->vt != NULL, RET_BAD_PARAMS);
return_value_if_fail(name != NULL && v != NULL, RET_BAD_PARAMS);
return_value_if_fail(obj != NULL && obj->vt != NULL && obj->ref_count >= 0, RET_BAD_PARAMS);
value_set_int(v, 0);
if (obj->vt->get_prop != NULL) {
@ -103,6 +103,51 @@ ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
return ret;
}
ret_t object_get_prop_by_path(object_t* obj, const char* name, value_t* v) {
char* p = NULL;
uint32_t len = 0;
char path[MAX_PATH + 1];
ret_t ret = RET_NOT_FOUND;
return_value_if_fail(obj != NULL && obj->vt != NULL, RET_BAD_PARAMS);
return_value_if_fail(name != NULL && v != NULL, RET_BAD_PARAMS);
len = strlen(name);
return_value_if_fail(len <= MAX_PATH, RET_BAD_PARAMS);
memcpy(path, name, len + 1);
name = path;
do {
p = strchr(name, '.');
if (p != NULL) {
*p = '\0';
}
if (object_get_prop_by_name(obj, name, v) != RET_OK) {
break;
}
if (p == NULL) {
ret = RET_OK;
break;
}
if (v->type == VALUE_TYPE_OBJECT) {
obj = value_object(v);
} else {
break;
}
name = p + 1;
} while (p != NULL);
return ret;
}
ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
return object_get_prop_by_name(obj, name, v);
}
const char* object_get_prop_str(object_t* obj, const char* name) {
value_t v;
if (object_get_prop(obj, name, &v) == RET_OK) {

View File

@ -465,6 +465,18 @@ ret_t object_exec(object_t* obj, const char* name, const char* args);
*/
ret_t object_notify_changed(object_t* obj);
/**
* @method object_get_prop_by_path
* path属性的值
*
* @param {object_t*} obj object对象
* @param {const char*} path path.
* @param {value_t*} v
*
* @return {ret_t} RET_OK表示成功
*/
ret_t object_get_prop_by_path(object_t* obj, const char* path, value_t* v);
#define OBJECT(obj) ((object_t*)(obj))
END_C_DECLS

View File

@ -112,6 +112,7 @@ static ret_t object_array_remove_prop(object_t* obj, const char* name) {
ret_t ret = RET_NOT_FOUND;
int32_t index = tk_atoi(name);
object_array_t* o = OBJECT_ARRAY(obj);
return_value_if_fail(isdigit(*name), RET_NOT_FOUND);
if (index >= 0 && index < o->props_size) {
value_t* iter = o->props + index;
@ -129,7 +130,7 @@ static ret_t object_array_set_prop(object_t* obj, const char* name, const value_
int32_t index = tk_atoi(name);
return_value_if_fail(object_array_extend(obj) == RET_OK, RET_OOM);
if (index >= 0 && index < o->props_size) {
if (isdigit(*name) && index >= 0 && index < o->props_size) {
value_t* iter = o->props + index;
value_reset(iter);
ret = value_deep_copy(iter, v);
@ -149,7 +150,7 @@ static ret_t object_array_get_prop(object_t* obj, const char* name, value_t* v)
if (tk_str_eq(name, "length") || tk_str_eq(name, "size")) {
value_set_int(v, o->props_size);
ret = RET_OK;
} else {
} else if (isdigit(*name)) {
int32_t index = tk_atoi(name);
if (index >= 0 && index < o->props_size) {
value_t* iter = o->props + index;

View File

@ -1,4 +1,5 @@
#include "tkc/utils.h"
#include "tkc/object_default.h"
#include "tkc/object_array.h"
#include "gtest/gtest.h"
#include <stdlib.h>
@ -126,7 +127,7 @@ TEST(ObjectArray, dup) {
ASSERT_EQ(object_set_prop(obj, "-1", value_set_int(&v, 3)), RET_OK);
dup = object_array_clone(OBJECT_ARRAY(obj));
log = "";
object_foreach_prop(dup, visit_dump, &log);
ASSERT_EQ(log, "0123");
@ -135,3 +136,49 @@ TEST(ObjectArray, dup) {
object_unref(dup);
}
TEST(ObjectArray, path) {
value_t v;
object_t* clone = NULL;
object_t* root = object_default_create();
object_t* obja = object_array_create();
object_t* obja1 = object_default_create();
object_t* obja2 = object_default_create();
object_t* objb = object_array_create();
object_t* objb1 = object_default_create();
object_t* objb2 = object_default_create();
ASSERT_EQ(object_set_prop_object(root, "a", obja), RET_OK);
ASSERT_EQ(object_set_prop_object(root, "b", objb), RET_OK);
ASSERT_EQ(object_set_prop_object(obja, "-1", obja1), RET_OK);
ASSERT_EQ(object_set_prop_int(obja1, "value", 456), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "a.0.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 456);
ASSERT_EQ(object_set_prop_object(obja, "-1", obja2), RET_OK);
ASSERT_EQ(object_set_prop_int(obja2, "value", 56), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "a.1.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 56);
ASSERT_EQ(object_set_prop_object(objb, "-1", objb1), RET_OK);
ASSERT_EQ(object_set_prop_int(objb1, "value", 56), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "b.0.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 56);
ASSERT_EQ(object_set_prop_object(objb, "-1", objb2), RET_OK);
ASSERT_EQ(object_set_prop_int(objb2, "value", 156), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "b.1.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 156);
ASSERT_NE(object_get_prop_by_path(root, "a.a.value", &v), RET_OK);
ASSERT_NE(object_get_prop_by_path(root, "b.a.value", &v), RET_OK);
ASSERT_NE(object_get_prop_by_path(root, "c.value", &v), RET_OK);
object_unref(root);
object_unref(obja);
object_unref(obja1);
object_unref(obja2);
object_unref(objb);
object_unref(objb1);
object_unref(objb2);
}

View File

@ -29,7 +29,7 @@ static ret_t visit_dump(void* ctx, const void* data) {
return RET_OK;
}
TEST(ObejectDefault, events) {
TEST(ObjectDefault, events) {
value_t v;
string log;
object_t* obj = object_default_create();
@ -47,7 +47,7 @@ TEST(ObejectDefault, events) {
ASSERT_EQ(log, "6:6:8:8:destroy:");
}
TEST(ObejectDefault, basic) {
TEST(ObjectDefault, basic) {
value_t v;
string log;
object_t* obj = object_default_create();
@ -189,7 +189,7 @@ static ret_t visit_test_busy(void* ctx, const void* data) {
return RET_OK;
}
TEST(ObejectDefault, visis_remove) {
TEST(ObjectDefault, visis_remove) {
value_t v;
string log;
object_t* obj = object_default_create();
@ -226,7 +226,7 @@ TEST(ObejectDefault, visis_remove) {
object_unref(obj);
}
TEST(ObejectDefault, random) {
TEST(ObjectDefault, random) {
value_t v;
string log;
char name[32];
@ -248,7 +248,7 @@ TEST(ObejectDefault, random) {
object_unref(obj);
}
TEST(ObejectDefault, set_name) {
TEST(ObjectDefault, set_name) {
object_t* obj = object_default_create();
object_set_name(obj, "abc");
@ -260,7 +260,7 @@ TEST(ObejectDefault, set_name) {
object_unref(obj);
}
TEST(ObejectDefault, set_prop_int) {
TEST(ObjectDefault, set_prop_int) {
object_t* obj = object_default_create();
ASSERT_EQ(object_set_prop_int(obj, "int", 123), RET_OK);
@ -269,7 +269,7 @@ TEST(ObejectDefault, set_prop_int) {
object_unref(obj);
}
TEST(ObejectDefault, set_prop_float) {
TEST(ObjectDefault, set_prop_float) {
object_t* obj = object_default_create();
ASSERT_EQ(object_set_prop_float(obj, "float", 123), RET_OK);
@ -278,7 +278,7 @@ TEST(ObejectDefault, set_prop_float) {
object_unref(obj);
}
TEST(ObejectDefault, copy_prop) {
TEST(ObjectDefault, copy_prop) {
object_t* src = object_default_create();
object_t* obj = object_default_create();
@ -294,7 +294,7 @@ TEST(ObejectDefault, copy_prop) {
object_unref(obj);
}
TEST(ObejectDefault, set_prop_str) {
TEST(ObjectDefault, set_prop_str) {
object_t* obj = object_default_create();
ASSERT_EQ(object_set_prop_str(obj, "str", "123"), RET_OK);
@ -303,7 +303,7 @@ TEST(ObejectDefault, set_prop_str) {
object_unref(obj);
}
TEST(ObejectDefault, exec) {
TEST(ObjectDefault, exec) {
object_t* obj = object_default_create();
ASSERT_EQ(object_can_exec(obj, "test", "123"), FALSE);
@ -312,7 +312,7 @@ TEST(ObejectDefault, exec) {
object_unref(obj);
}
TEST(ObejectDefault, has_prop) {
TEST(ObjectDefault, has_prop) {
object_t* obj = object_default_create();
ASSERT_EQ(object_set_prop_float(obj, "a", 123), RET_OK);
@ -322,7 +322,7 @@ TEST(ObejectDefault, has_prop) {
object_unref(obj);
}
TEST(ObejectDefault, expr_number) {
TEST(ObjectDefault, expr_number) {
value_t v;
object_t* obj = object_default_create();
@ -337,7 +337,7 @@ TEST(ObejectDefault, expr_number) {
object_unref(obj);
}
TEST(ObejectDefault, expr_str) {
TEST(ObjectDefault, expr_str) {
value_t v;
object_t* obj = object_default_create();
@ -350,7 +350,7 @@ TEST(ObejectDefault, expr_str) {
object_unref(obj);
}
TEST(ObejectDefault, clone) {
TEST(ObjectDefault, clone) {
value_t v;
object_t* clone = NULL;
object_t* obj = object_default_create();
@ -366,3 +366,58 @@ TEST(ObejectDefault, clone) {
object_unref(obj);
object_unref(clone);
}
TEST(ObjectDefault, path) {
value_t v;
object_t* clone = NULL;
object_t* root = object_default_create();
object_t* obja = object_default_create();
object_t* obja1 = object_default_create();
object_t* obja2 = object_default_create();
object_t* objb = object_default_create();
object_t* objb1 = object_default_create();
object_t* objb2 = object_default_create();
ASSERT_EQ(object_set_prop_object(root, "a", obja), RET_OK);
ASSERT_EQ(object_set_prop_object(root, "b", objb), RET_OK);
ASSERT_EQ(object_set_prop_int(obja, "value", 123), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "a.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 123);
ASSERT_EQ(object_set_prop_int(objb, "value", 123), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "b.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 123);
ASSERT_EQ(object_set_prop_object(obja, "1", obja1), RET_OK);
ASSERT_EQ(object_set_prop_int(obja1, "value", 456), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "a.1.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 456);
ASSERT_EQ(object_set_prop_object(obja, "2", obja2), RET_OK);
ASSERT_EQ(object_set_prop_int(obja2, "value", 56), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "a.2.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 56);
ASSERT_EQ(object_set_prop_object(objb, "1", objb1), RET_OK);
ASSERT_EQ(object_set_prop_int(objb1, "value", 56), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "b.1.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 56);
ASSERT_EQ(object_set_prop_object(objb, "2", objb2), RET_OK);
ASSERT_EQ(object_set_prop_int(objb2, "value", 156), RET_OK);
ASSERT_EQ(object_get_prop_by_path(root, "b.2.value", &v), RET_OK);
ASSERT_EQ(value_int(&v), 156);
ASSERT_NE(object_get_prop_by_path(root, "a.a.value", &v), RET_OK);
ASSERT_NE(object_get_prop_by_path(root, "b.a.value", &v), RET_OK);
ASSERT_NE(object_get_prop_by_path(root, "c.value", &v), RET_OK);
object_unref(root);
object_unref(obja);
object_unref(obja1);
object_unref(obja2);
object_unref(objb);
object_unref(objb1);
object_unref(objb2);
}