[RFC PATCH 1/8] dbus: setters and getters API for properties.
by Andrew Zaborowski
These setters and getters are not used yet.
(I will split all of the patches by directories when submitting a final
version, this is just for the ease of reviewing)
---
ell/dbus-service.c | 28 ++++++------------
ell/dbus-service.h | 27 ++++++++++++-----
examples/dbus-service.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++--
unit/test-dbus-service.c | 16 +++++++++-
4 files changed, 118 insertions(+), 30 deletions(-)
diff --git a/ell/dbus-service.c b/ell/dbus-service.c
index e082226..77310c6 100644
--- a/ell/dbus-service.c
+++ b/ell/dbus-service.c
@@ -61,6 +61,8 @@ struct _dbus_signal {
};
struct _dbus_property {
+ l_dbus_property_get_cb_t getter;
+ l_dbus_property_set_cb_t setter;
uint32_t flags;
unsigned char name_len;
char metainfo[];
@@ -191,7 +193,7 @@ void _dbus_property_introspection(struct _dbus_property *info,
l_string_append_printf(buf, "\t\t<property name=\"%s\" type=\"%s\" ",
info->metainfo, signature);
- if (info->flags & L_DBUS_PROPERTY_FLAG_WRITABLE)
+ if (info->setter)
l_string_append(buf, "access=\"readwrite\"");
else
l_string_append(buf, "access=\"read\"");
@@ -375,7 +377,9 @@ LIB_EXPORT bool l_dbus_interface_signal(struct l_dbus_interface *interface,
LIB_EXPORT bool l_dbus_interface_property(struct l_dbus_interface *interface,
const char *name, uint32_t flags,
- const char *signature)
+ const char *signature,
+ l_dbus_property_get_cb_t getter,
+ l_dbus_property_set_cb_t setter)
{
unsigned int metainfo_len;
struct _dbus_property *info;
@@ -384,7 +388,7 @@ LIB_EXPORT bool l_dbus_interface_property(struct l_dbus_interface *interface,
if (!_dbus_valid_method(name))
return false;
- if (unlikely(!signature))
+ if (unlikely(!signature || !getter))
return false;
if (!_dbus_valid_signature(signature))
@@ -397,6 +401,8 @@ LIB_EXPORT bool l_dbus_interface_property(struct l_dbus_interface *interface,
info = l_malloc(sizeof(*info) + metainfo_len);
info->flags = flags;
info->name_len = strlen(name);
+ info->getter = getter;
+ info->setter = setter;
p = stpcpy(info->metainfo, name) + 1;
strcpy(p, signature);
@@ -406,22 +412,6 @@ LIB_EXPORT bool l_dbus_interface_property(struct l_dbus_interface *interface,
return true;
}
-LIB_EXPORT bool l_dbus_interface_ro_property(struct l_dbus_interface *interface,
- const char *name,
- const char *signature)
-{
- return l_dbus_interface_property(interface, name, 0, signature);
-}
-
-LIB_EXPORT bool l_dbus_interface_rw_property(struct l_dbus_interface *interface,
- const char *name,
- const char *signature)
-{
- return l_dbus_interface_property(interface, name,
- L_DBUS_PROPERTY_FLAG_WRITABLE,
- signature);
-}
-
struct l_dbus_interface *_dbus_interface_new(const char *name)
{
struct l_dbus_interface *interface;
diff --git a/ell/dbus-service.h b/ell/dbus-service.h
index ce53082..a1e526e 100644
--- a/ell/dbus-service.h
+++ b/ell/dbus-service.h
@@ -46,13 +46,28 @@ enum l_dbus_signal_flag {
enum l_dbus_property_flag {
L_DBUS_PROPERTY_FLAG_DEPRECATED = 1,
- L_DBUS_PROPERTY_FLAG_WRITABLE = 2,
};
typedef struct l_dbus_message *(*l_dbus_interface_method_cb_t) (struct l_dbus *,
struct l_dbus_message *message,
void *user_data);
+typedef void (*l_dbus_property_complete_cb_t) (struct l_dbus *,
+ struct l_dbus_message *,
+ struct l_dbus_message *error);
+
+typedef void (*l_dbus_property_set_cb_t) (struct l_dbus *,
+ struct l_dbus_message *message,
+ struct l_dbus_message_iter *new_value,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data);
+
+typedef void (*l_dbus_property_get_cb_t) (struct l_dbus *,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data);
+
bool l_dbus_interface_method(struct l_dbus_interface *interface,
const char *name, uint32_t flags,
l_dbus_interface_method_cb_t cb,
@@ -65,13 +80,9 @@ bool l_dbus_interface_signal(struct l_dbus_interface *interface,
bool l_dbus_interface_property(struct l_dbus_interface *interface,
const char *name, uint32_t flags,
- const char *signature);
-bool l_dbus_interface_ro_property(struct l_dbus_interface *interface,
- const char *name,
- const char *signature);
-bool l_dbus_interface_rw_property(struct l_dbus_interface *interface,
- const char *name,
- const char *signature);
+ const char *signature,
+ l_dbus_property_get_cb_t getter,
+ l_dbus_property_set_cb_t setter);
#ifdef __cplusplus
}
diff --git a/examples/dbus-service.c b/examples/dbus-service.c
index 40c1646..e4e5fa7 100644
--- a/examples/dbus-service.c
+++ b/examples/dbus-service.c
@@ -187,6 +187,77 @@ static struct l_dbus_message *test_method_call(struct l_dbus *dbus,
return reply;
}
+static void test_string_getter(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data)
+{
+ struct test_data *test = user_data;
+
+ l_dbus_message_builder_append_basic(builder, 's', test->string);
+
+ complete(dbus, message, NULL);
+}
+
+static void test_string_setter(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_iter *new_value,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data)
+{
+ const char *strvalue;
+ struct test_data *test = user_data;
+
+ if (!l_dbus_message_iter_get_variant(new_value, "s", &strvalue)) {
+ complete(dbus, message, l_dbus_message_new_error(message,
+ "org.test.InvalidArguments",
+ "String value expected"));
+ return;
+ }
+
+ l_info("New String value: %s", strvalue);
+ l_free(test->string);
+ test->string = l_strdup(strvalue);
+
+ complete(dbus, message, NULL);
+}
+
+static void test_int_getter(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data)
+{
+ struct test_data *test = user_data;
+
+ l_dbus_message_builder_append_basic(builder, 'u', &test->integer);
+
+ complete(dbus, message, NULL);
+}
+
+static void test_int_setter(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_iter *new_value,
+ l_dbus_property_complete_cb_t complete,
+ void *user_data)
+{
+ uint32_t u;
+ struct test_data *test = user_data;
+
+ if (!l_dbus_message_iter_get_variant(new_value, "u", &u)) {
+ complete(dbus, message, l_dbus_message_new_error(message,
+ "org.test.InvalidArguments",
+ "Integer value expected"));
+ return;
+ }
+
+ l_info("New Integer value: %u", u);
+ test->integer = u;
+
+ complete(dbus, message, NULL);
+}
+
static void setup_test_interface(struct l_dbus_interface *interface)
{
l_dbus_interface_method(interface, "GetProperties", 0,
@@ -201,8 +272,10 @@ static void setup_test_interface(struct l_dbus_interface *interface)
l_dbus_interface_signal(interface, "PropertyChanged", 0,
"sv", "name", "value");
- l_dbus_interface_rw_property(interface, "String", "s");
- l_dbus_interface_rw_property(interface, "Integer", "u");
+ l_dbus_interface_property(interface, "String", 0, "s",
+ test_string_getter, test_string_setter);
+ l_dbus_interface_property(interface, "Integer", 0, "u",
+ test_int_getter, test_int_setter);
}
int main(int argc, char *argv[])
diff --git a/unit/test-dbus-service.c b/unit/test-dbus-service.c
index 7452269..d0bf174 100644
--- a/unit/test-dbus-service.c
+++ b/unit/test-dbus-service.c
@@ -315,6 +315,19 @@ static void test_dbus_object_tree_dispatch(const void *test_data)
_dbus_object_tree_free(tree);
}
+static void test_property_getter(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ l_dbus_property_complete_cb_t complete,
+ void *if_user_data)
+{
+ const uint8_t answer = 42;
+
+ l_dbus_message_builder_append_basic(builder, 'y', &answer);
+
+ complete(dbus, message, NULL);
+}
+
int main(int argc, char *argv[])
{
int ret;
@@ -333,7 +346,8 @@ int main(int argc, char *argv[])
l_dbus_interface_signal(interface, "Changed", 0, "b", "new_value");
- l_dbus_interface_rw_property(interface, "Bar", "y");
+ l_dbus_interface_property(interface, "Bar", 0, "y",
+ test_property_getter, NULL);
l_test_add("Test Frobate Introspection", test_introspect_method,
&frobate_test);
--
2.5.0
5 years, 2 months
[PATCH 1/2] util: Fix skipped characters in strsplit functions
by Mat Martineau
l_strsplit and l_strsplit_sep were skipping an extra character after
each delimiter because len was incremented after being set to 0 but
before the next iteration of the loop began. This caused problems with
trailing and consecutive delimiters.
---
ell/util.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/ell/util.c b/ell/util.c
index 5bd7b3b..f920895 100644
--- a/ell/util.c
+++ b/ell/util.c
@@ -293,9 +293,15 @@ LIB_EXPORT char **l_strsplit(const char *str, const char sep)
ret = l_new(char *, len + 1);
- for (i = 0, p = str, len = 0; p[len]; len++) {
- if (p[len] != sep)
+ i = 0;
+ p = str;
+ len = 0;
+
+ while (p[len]) {
+ if (p[len] != sep) {
+ len += 1;
continue;
+ }
ret[i++] = l_strndup(p, len);
p += len + 1;
@@ -347,9 +353,15 @@ LIB_EXPORT char **l_strsplit_set(const char *str, const char *separators)
ret = l_new(char *, len + 1);
- for (i = 0, p = str, len = 0; p[len]; len++) {
- if (sep_table[(unsigned char) p[len]] != true)
+ i = 0;
+ p = str;
+ len = 0;
+
+ while (p[len]) {
+ if (sep_table[(unsigned char) p[len]] != true) {
+ len += 1;
continue;
+ }
ret[i++] = l_strndup(p, len);
p += len + 1;
--
2.7.0
5 years, 3 months
[PATCH] util: Fix skipped characters in strsplit functions
by Mat Martineau
l_strsplit and l_strsplit_sep were skipping an extra character after
each delimiter because len was incremented after being set to 0 but
before the next iteration of the loop began. This caused problems with
trailing and consecutive delimiters. Added strings with varying
delimiters to tests and made sure len is set back to 0.
---
ell/util.c | 36 ++++++++++++++++++++++--------------
unit/test-string.c | 32 +++++++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/ell/util.c b/ell/util.c
index 5bd7b3b..d1e7079 100644
--- a/ell/util.c
+++ b/ell/util.c
@@ -293,13 +293,17 @@ LIB_EXPORT char **l_strsplit(const char *str, const char sep)
ret = l_new(char *, len + 1);
- for (i = 0, p = str, len = 0; p[len]; len++) {
- if (p[len] != sep)
- continue;
-
- ret[i++] = l_strndup(p, len);
- p += len + 1;
- len = 0;
+ i = 0;
+ p = str;
+ len = 0;
+ while (p[len]) {
+ if (p[len] != sep) {
+ len++;
+ } else {
+ ret[i++] = l_strndup(p, len);
+ p += len + 1;
+ len = 0;
+ }
}
ret[i++] = l_strndup(p, len);
@@ -347,13 +351,17 @@ LIB_EXPORT char **l_strsplit_set(const char *str, const char *separators)
ret = l_new(char *, len + 1);
- for (i = 0, p = str, len = 0; p[len]; len++) {
- if (sep_table[(unsigned char) p[len]] != true)
- continue;
-
- ret[i++] = l_strndup(p, len);
- p += len + 1;
- len = 0;
+ i = 0;
+ p = str;
+ len = 0;
+ while (p[len]) {
+ if (sep_table[(unsigned char) p[len]] != true) {
+ len++;
+ } else {
+ ret[i++] = l_strndup(p, len);
+ p += len + 1;
+ len = 0;
+ }
}
ret[i++] = l_strndup(p, len);
diff --git a/unit/test-string.c b/unit/test-string.c
index 388e90f..d2f8bd4 100644
--- a/unit/test-string.c
+++ b/unit/test-string.c
@@ -124,6 +124,22 @@ static void test_strsplit(const void *test_data)
assert(!strcmp(strv[2], "bz"));
assert(strv[3] == NULL);
l_strfreev(strv);
+
+ l_strsplit(":bar:bz", ':');
+ assert(strv);
+ assert(!strcmp(strv[0], ""));
+ assert(!strcmp(strv[1], "bar"));
+ assert(!strcmp(strv[2], "bz"));
+ assert(strv[3] == NULL);
+ l_strfreev(strv);
+
+ l_strsplit("Foo:bar:", ':');
+ assert(strv);
+ assert(!strcmp(strv[0], "Foo"));
+ assert(!strcmp(strv[1], "bar"));
+ assert(!strcmp(strv[2], ""));
+ assert(strv[3] == NULL);
+ l_strfreev(strv);
}
static void test_strsplit_set(const void *test_data)
@@ -137,6 +153,20 @@ static void test_strsplit_set(const void *test_data)
assert(!strcmp(strv[3], "Blu"));
assert(strv[4] == NULL);
l_strfreev(strv);
+
+ strv = l_strsplit_set("Foo:bar,Baz Blu,:,Fee:Fie ", ":, ");
+ assert(strv);
+ assert(!strcmp(strv[0], "Foo"));
+ assert(!strcmp(strv[1], "bar"));
+ assert(!strcmp(strv[2], "Baz"));
+ assert(!strcmp(strv[3], "Blu"));
+ assert(!strcmp(strv[4], ""));
+ assert(!strcmp(strv[5], ""));
+ assert(!strcmp(strv[6], "Fee"));
+ assert(!strcmp(strv[7], "Fie"));
+ assert(!strcmp(strv[8], ""));
+ assert(strv[9] == NULL);
+ l_strfreev(strv);
}
static void test_joinv(const void *test_data)
@@ -175,7 +205,7 @@ int main(int argc, char *argv[])
l_test_add("append_fixed test 2", test_fixed, &fixed_test2);
l_test_add("append_fixed test 3", test_fixed, &fixed_test3);
- l_test_add("strplit", test_strsplit, NULL);
+ l_test_add("strsplit", test_strsplit, NULL);
l_test_add("strsplit_set", test_strsplit_set, NULL);
l_test_add("joinv", test_joinv, NULL);
--
2.7.0
5 years, 3 months