diff options
author | Pavel Březina <pbrezina@redhat.com> | 2015-03-18 13:01:07 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-05-22 15:57:05 +0200 |
commit | ac744223411099a862a747e7168a30255c003bf7 (patch) | |
tree | 3205b9f9f5efcc420988f61380a62be32abc3eff | |
parent | 10a28f461c25d788ff4dcffefa881e7aa724a25d (diff) | |
download | sssd-ac744223411099a862a747e7168a30255c003bf7.tar.gz sssd-ac744223411099a862a747e7168a30255c003bf7.tar.xz sssd-ac744223411099a862a747e7168a30255c003bf7.zip |
sbus: add a{sas} get invoker
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rwxr-xr-x | src/sbus/sbus_codegen | 32 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_invokers.c | 118 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_invokers.h | 4 | ||||
-rw-r--r-- | src/tests/sbus_codegen_tests.c | 157 | ||||
-rwxr-xr-x | src/tests/sbus_codegen_tests.xml | 8 | ||||
-rw-r--r-- | src/tests/sbus_codegen_tests_generated.c | 23 | ||||
-rw-r--r-- | src/tests/sbus_codegen_tests_generated.h | 63 |
7 files changed, 372 insertions, 33 deletions
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen index 7d2127508..93eb9f1c1 100755 --- a/src/sbus/sbus_codegen +++ b/src/sbus/sbus_codegen @@ -125,12 +125,15 @@ class Typed(Base): self.type = type self.is_basic = False self.is_array = False + self.is_dictionary = False self.dbus_constant = None self.dbus_type = None self.sssd_type = None if type[0] == 'a': type = type[1:] self.is_array = True + if "{" in type: + self.is_dictionary = True if type in BASIC_TYPES: (self.dbus_constant, self.dbus_type, self.sssd_type) = BASIC_TYPES[type] # If types are not identical, we can't do array (yet) @@ -192,16 +195,29 @@ class Property(Typed): raise DBusXmlException('Invalid access type %s'%self.access) def fq_c_name(self): return "%s_%s" % (self.iface.c_name(), self.c_name()) + def get_invoker_name(self): + type = self.type + type = type.replace("{", "DO") + type = type.replace("}", "DE") + return type + def get_invoker_signature(self, name): + sig = "void (*%s)(struct sbus_request *, void *data, " % (name) + if self.is_dictionary: + sig += "hash_table_t **" + elif self.is_array: + sig += "%s**, int *" % (self.sssd_type) + else: + sig += "%s*" % (self.sssd_type) + sig += ")" + return sig + + def getter_name(self): return "get_%s" % self.c_name() def getter_invoker_name(self): - return "sbus_invoke_get_%s" % self.type - def getter_signature(self, name): - sig = "void (*%s)(struct sbus_request *, void *data, %s *" % (name, self.sssd_type) - if self.is_array: - sig += " *, int *" - sig += ")" - return sig + return "sbus_invoke_get_%s" % self.get_invoker_name() + def getter_signature(self): + return self.get_invoker_signature(self.getter_name()) class Interface(Base): def __init__(self, name): @@ -253,7 +269,7 @@ def method_function_pointer(meth, name, with_names=False): method_arg_types(meth.in_args, with_names)) def property_handlers(prop): - return prop.getter_signature(prop.getter_name()) + return prop.getter_signature() def forward_method_invoker(signature, args): out("") diff --git a/src/sbus/sssd_dbus_invokers.c b/src/sbus/sssd_dbus_invokers.c index df9104f63..f4d4ba3a6 100644 --- a/src/sbus/sssd_dbus_invokers.c +++ b/src/sbus/sssd_dbus_invokers.c @@ -303,6 +303,124 @@ int sbus_invoke_get_ao(DBusMessageIter *iter, DBUS_TYPE_OBJECT_PATH, iter); } +int sbus_invoke_get_aDOsasDE(DBusMessageIter *iter, + struct sbus_request *sbus_req, + void *function_ptr) +{ + void (*handler_fn)(struct sbus_request *, void *, hash_table_t **); + DBusMessageIter it_array; + DBusMessageIter it_dict; + DBusMessageIter it_values; + hash_table_t *table; + struct hash_iter_context_t *table_iter = NULL; + hash_entry_t *entry; + const char **values; + dbus_bool_t dbret; + errno_t ret; + int i; + + handler_fn = function_ptr; + handler_fn(sbus_req, sbus_req->intf->handler_data, &table); + + dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + /* iterate over keys */ + + if (table == NULL) { + dbret = dbus_message_iter_close_container(iter, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + ret = EOK; + goto done; + } + + table_iter = new_hash_iter_context(table); + while ((entry = table_iter->next(table_iter)) != NULL) { + if (entry->key.type != HASH_KEY_STRING || entry->key.str == NULL + || entry->value.type != HASH_VALUE_PTR + || entry->value.ptr == NULL) { + continue; + } + + dbret = dbus_message_iter_open_container(&it_array, + DBUS_TYPE_DICT_ENTRY, NULL, + &it_dict); + if (!dbret) { + ret = EIO; + goto done; + } + + /* append key as dict entry key */ + + dbret = dbus_message_iter_append_basic(&it_dict, + DBUS_TYPE_STRING, + &entry->key.str); + if (!dbret) { + ret = EIO; + goto done; + } + + /* iterate over values */ + + dbret = dbus_message_iter_open_container(&it_dict, + DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, + &it_values); + if (!dbret) { + ret = EIO; + goto done; + } + + values = entry->value.ptr; + for (i = 0; values[i] != NULL; i++) { + /* append value into array */ + dbret = dbus_message_iter_append_basic(&it_values, + DBUS_TYPE_STRING, + &values[i]); + if (!dbret) { + ret = EIO; + goto done; + } + } + + dbret = dbus_message_iter_close_container(&it_dict, &it_values); + if (!dbret) { + ret = EIO; + goto done; + } + + dbret = dbus_message_iter_close_container(&it_array, &it_dict); + if (!dbret) { + ret = EIO; + goto done; + } + } + + dbret = dbus_message_iter_close_container(iter, &it_array); + if (!dbret) { + ret = EIO; + goto done; + } + + ret = EOK; + +done: + talloc_free(table_iter); + return ret; +} + void sbus_invoke_get(struct sbus_request *sbus_req, const char *type, sbus_get_invoker_fn invoker_fn, diff --git a/src/sbus/sssd_dbus_invokers.h b/src/sbus/sssd_dbus_invokers.h index 8fd498594..6f7f2540e 100644 --- a/src/sbus/sssd_dbus_invokers.h +++ b/src/sbus/sssd_dbus_invokers.h @@ -109,6 +109,10 @@ int sbus_invoke_get_ao(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); +int sbus_invoke_get_aDOsasDE(DBusMessageIter *iter, + struct sbus_request *sbus_req, + void *function_ptr); + void sbus_invoke_get(struct sbus_request *sbus_req, const char *type, sbus_get_invoker_fn invoker_fn, diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c index e0b4b1d1a..9e9be52e8 100644 --- a/src/tests/sbus_codegen_tests.c +++ b/src/tests/sbus_codegen_tests.c @@ -539,6 +539,62 @@ void pilot_get_path_array_handler(struct sbus_request *dbus_req, array_getter_body(pilot_path_array, arr_out, arr_len); } +void special_get_array_dict_sas(struct sbus_request *sbus_req, + void *data, + hash_table_t **_out) +{ + hash_table_t *table; + hash_key_t key; + hash_value_t value; + char **values; + errno_t ret; + int hret; + + *_out = NULL; + + ret = sss_hash_create(sbus_req, 10, &table); + ck_assert_int_eq(ret, EOK); + + values = talloc_zero_array(table, char *, 3); + ck_assert(values != NULL); + + values[0] = talloc_strdup(values, "hello1"); + values[1] = talloc_strdup(values, "world1"); + + ck_assert(values[0] != NULL); + ck_assert(values[1] != NULL); + + key.type = HASH_KEY_STRING; + key.str = talloc_strdup(table, "key1"); + + value.type = HASH_VALUE_PTR; + value.ptr = values; + + hret = hash_enter(table, &key, &value); + ck_assert_int_eq(hret, HASH_SUCCESS); + + values = talloc_zero_array(table, char *, 3); + ck_assert(values != NULL); + + values[0] = talloc_strdup(values, "hello2"); + values[1] = talloc_strdup(values, "world2"); + + ck_assert(values[0] != NULL); + ck_assert(values[1] != NULL); + + key.type = HASH_KEY_STRING; + key.str = talloc_strdup(table, "key2"); + ck_assert(key.str != NULL); + + value.type = HASH_VALUE_PTR; + value.ptr = values; + + hash_enter(table, &key, &value); + ck_assert_int_eq(hret, HASH_SUCCESS); + + *_out = table; +} + struct test_pilot pilot_iface = { { &test_pilot_meta, 0 }, .Eject = eject_handler, @@ -570,6 +626,11 @@ struct test_pilot pilot_iface = { .get_object_path_array = pilot_get_path_array_handler, }; +struct test_special special_iface = { + { &test_special_meta, 0}, + .get_array_dict_sas = special_get_array_dict_sas +}; + static int pilot_test_server_init(struct sbus_connection *server, void *unused) { int ret; @@ -581,6 +642,17 @@ static int pilot_test_server_init(struct sbus_connection *server, void *unused) return EOK; } +static int special_test_server_init(struct sbus_connection *server, void *unused) +{ + int ret; + + ret = sbus_conn_register_iface(server, &special_iface.vtable, + "/test/special", "Crash into the billboard"); + ck_assert_int_eq(ret, EOK); + + return EOK; +} + START_TEST(test_marshal_basic_types) { unsigned char arg_byte = 11; @@ -1043,6 +1115,90 @@ START_TEST(test_get_basic_array_types) } END_TEST +START_TEST(test_get_array_dict_sas) +{ + TALLOC_CTX *ctx; + DBusConnection *client; + DBusMessage *reply; + DBusMessageIter it_variant; + DBusMessageIter it_array; + DBusMessageIter it_dict; + DBusMessageIter it_dict_entry; + DBusMessageIter it_values; + DBusError error = DBUS_ERROR_INIT; + const char *prop = "array_dict_sas"; + dbus_bool_t dbret; + const char *value; + const char *hash_content[2][2] = {{"hello1", "world1"}, + {"hello2", "world2"}}; + const char **exp_values; + int i; + + ctx = talloc_new(NULL); + ck_assert(ctx != NULL); + + client = test_dbus_setup_mock(ctx, NULL, special_test_server_init, NULL); + ck_assert(client != NULL); + + reply = test_dbus_call_sync(client, + "/test/special", + DBUS_PROPERTIES_INTERFACE, + "Get", + &error, + DBUS_TYPE_STRING, &test_special_meta.name, + DBUS_TYPE_STRING, &prop, + DBUS_TYPE_INVALID); + ck_assert(reply != NULL); + + dbret = dbus_message_iter_init(reply, &it_variant); + ck_assert(dbret == TRUE); + + ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_variant), DBUS_TYPE_VARIANT); + dbus_message_iter_recurse(&it_variant, &it_array); + + /* array */ + ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_array), DBUS_TYPE_ARRAY); + ck_assert_int_eq(dbus_message_iter_get_element_type(&it_array), DBUS_TYPE_DICT_ENTRY); + + /* dict entry */ + + /* first item */ + dbus_message_iter_recurse(&it_array, &it_dict); + for (i = 0; i < 2; i++) { + dbus_message_iter_recurse(&it_dict, &it_dict_entry); + ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_STRING); + + dbus_message_iter_get_basic(&it_dict_entry, &value); + ck_assert(value != NULL); + if (strcmp(value, "key1") == 0) { + exp_values = hash_content[0]; + } else if (strcmp(value, "key2") == 0) { + exp_values = hash_content[1]; + } else { + ck_abort_msg("Invalid key! %s", value); + } + + dbret = dbus_message_iter_next(&it_dict_entry); + ck_assert(dbret == TRUE); + + ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_ARRAY); + ck_assert_int_eq(dbus_message_iter_get_element_type(&it_dict_entry), DBUS_TYPE_STRING); + + dbus_message_iter_recurse(&it_dict_entry, &it_values); + + dbus_message_iter_get_basic(&it_values, &value); + ck_assert(value != NULL); + ck_assert_str_eq(value, exp_values[0]); + + dbret = dbus_message_iter_next(&it_values); + dbus_message_iter_get_basic(&it_values, &value); + ck_assert(value != NULL); + ck_assert_str_eq(value, exp_values[1]); + dbus_message_iter_next(&it_dict); + } +} +END_TEST + struct prop_test { const char *name; bool handled; @@ -1356,6 +1512,7 @@ TCase *create_handler_tests(void) tcase_add_test(tc, test_get_basic_types); tcase_add_test(tc, test_getall_basic_types); tcase_add_test(tc, test_get_basic_array_types); + tcase_add_test(tc, test_get_array_dict_sas); return tc; } diff --git a/src/tests/sbus_codegen_tests.xml b/src/tests/sbus_codegen_tests.xml index 90e274254..4813dcc04 100755 --- a/src/tests/sbus_codegen_tests.xml +++ b/src/tests/sbus_codegen_tests.xml @@ -136,7 +136,15 @@ <property name="double_array" type="ad" access="read"/> <property name="string_array" type="as" access="read"/> <property name="object_path_array" type="ao" access="read"/> + </interface> + + <!-- + Special property types not suitable for group automatic tests. + --> + <interface name="com.planetexpress.Special"> + <annotation value="test_special" name="org.freedesktop.DBus.GLib.CSymbol"/> + <property name="array_dict_sas" type="a{sas}" access="read"/> </interface> </node> diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c index fc69b77b3..3a5db43c5 100644 --- a/src/tests/sbus_codegen_tests_generated.c +++ b/src/tests/sbus_codegen_tests_generated.c @@ -463,6 +463,29 @@ const struct sbus_interface_meta test_pilot_meta = { sbus_invoke_get_all, /* GetAll invoker */ }; +/* property info for com.planetexpress.Special */ +const struct sbus_property_meta test_special__properties[] = { + { + "array_dict_sas", /* name */ + "a{sas}", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct test_special, get_array_dict_sas), + sbus_invoke_get_aDOsasDE, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { NULL, } +}; + +/* interface info for com.planetexpress.Special */ +const struct sbus_interface_meta test_special_meta = { + "com.planetexpress.Special", /* name */ + NULL, /* no methods */ + NULL, /* no signals */ + test_special__properties, + sbus_invoke_get_all, /* GetAll invoker */ +}; + /* invokes a handler with a 'bu' DBus signature */ static int invoke_bu_method(struct sbus_request *dbus_req, void *function_ptr) { diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h index d573615ec..27049cd32 100644 --- a/src/tests/sbus_codegen_tests_generated.h +++ b/src/tests/sbus_codegen_tests_generated.h @@ -48,6 +48,10 @@ #define TEST_PILOT_STRING_ARRAY "string_array" #define TEST_PILOT_OBJECT_PATH_ARRAY "object_path_array" +/* constants for com.planetexpress.Special */ +#define TEST_SPECIAL "com.planetexpress.Special" +#define TEST_SPECIAL_ARRAY_DICT_SAS "array_dict_sas" + /* ------------------------------------------------------------------------ * DBus handlers * @@ -72,7 +76,7 @@ struct com_planetexpress_Ship { int (*MoveUniverse)(struct sbus_request *req, void *data, bool arg_smoothly, uint32_t arg_speed_factor); int (*crash_now)(struct sbus_request *req, void *data, const char *arg_where); sbus_msg_handler_fn Land; - void (*get_Color)(struct sbus_request *, void *data, const char * *); + void (*get_Color)(struct sbus_request *, void *data, const char **); }; /* finish function for MoveUniverse */ @@ -86,30 +90,30 @@ struct test_pilot { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Blink)(struct sbus_request *req, void *data, uint32_t arg_duration); int (*Eject)(struct sbus_request *req, void *data, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array); - void (*get_FullName)(struct sbus_request *, void *data, const char * *); - void (*get_byte)(struct sbus_request *, void *data, uint8_t *); - void (*get_boolean)(struct sbus_request *, void *data, bool *); - void (*get_int16)(struct sbus_request *, void *data, int16_t *); - void (*get_uint16)(struct sbus_request *, void *data, uint16_t *); - void (*get_int32)(struct sbus_request *, void *data, int32_t *); - void (*get_uint32)(struct sbus_request *, void *data, uint32_t *); - void (*get_int64)(struct sbus_request *, void *data, int64_t *); - void (*get_uint64)(struct sbus_request *, void *data, uint64_t *); - void (*get_double)(struct sbus_request *, void *data, double *); - void (*get_string)(struct sbus_request *, void *data, const char * *); - void (*get_object_path)(struct sbus_request *, void *data, const char * *); - void (*get_null_string)(struct sbus_request *, void *data, const char * *); - void (*get_null_path)(struct sbus_request *, void *data, const char * *); - void (*get_byte_array)(struct sbus_request *, void *data, uint8_t * *, int *); - void (*get_int16_array)(struct sbus_request *, void *data, int16_t * *, int *); - void (*get_uint16_array)(struct sbus_request *, void *data, uint16_t * *, int *); - void (*get_int32_array)(struct sbus_request *, void *data, int32_t * *, int *); - void (*get_uint32_array)(struct sbus_request *, void *data, uint32_t * *, int *); - void (*get_int64_array)(struct sbus_request *, void *data, int64_t * *, int *); - void (*get_uint64_array)(struct sbus_request *, void *data, uint64_t * *, int *); - void (*get_double_array)(struct sbus_request *, void *data, double * *, int *); - void (*get_string_array)(struct sbus_request *, void *data, const char * * *, int *); - void (*get_object_path_array)(struct sbus_request *, void *data, const char * * *, int *); + void (*get_FullName)(struct sbus_request *, void *data, const char **); + void (*get_byte)(struct sbus_request *, void *data, uint8_t*); + void (*get_boolean)(struct sbus_request *, void *data, bool*); + void (*get_int16)(struct sbus_request *, void *data, int16_t*); + void (*get_uint16)(struct sbus_request *, void *data, uint16_t*); + void (*get_int32)(struct sbus_request *, void *data, int32_t*); + void (*get_uint32)(struct sbus_request *, void *data, uint32_t*); + void (*get_int64)(struct sbus_request *, void *data, int64_t*); + void (*get_uint64)(struct sbus_request *, void *data, uint64_t*); + void (*get_double)(struct sbus_request *, void *data, double*); + void (*get_string)(struct sbus_request *, void *data, const char **); + void (*get_object_path)(struct sbus_request *, void *data, const char **); + void (*get_null_string)(struct sbus_request *, void *data, const char **); + void (*get_null_path)(struct sbus_request *, void *data, const char **); + void (*get_byte_array)(struct sbus_request *, void *data, uint8_t**, int *); + void (*get_int16_array)(struct sbus_request *, void *data, int16_t**, int *); + void (*get_uint16_array)(struct sbus_request *, void *data, uint16_t**, int *); + void (*get_int32_array)(struct sbus_request *, void *data, int32_t**, int *); + void (*get_uint32_array)(struct sbus_request *, void *data, uint32_t**, int *); + void (*get_int64_array)(struct sbus_request *, void *data, int64_t**, int *); + void (*get_uint64_array)(struct sbus_request *, void *data, uint64_t**, int *); + void (*get_double_array)(struct sbus_request *, void *data, double**, int *); + void (*get_string_array)(struct sbus_request *, void *data, const char ***, int *); + void (*get_object_path_array)(struct sbus_request *, void *data, const char ***, int *); }; /* finish function for Blink */ @@ -118,6 +122,12 @@ int test_pilot_Blink_finish(struct sbus_request *req, bool arg_crashed); /* finish function for Eject */ int test_pilot_Eject_finish(struct sbus_request *req, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array); +/* vtable for com.planetexpress.Special */ +struct test_special { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + void (*get_array_dict_sas)(struct sbus_request *, void *data, hash_table_t **); +}; + /* ------------------------------------------------------------------------ * DBus Interface Metadata * @@ -134,4 +144,7 @@ extern const struct sbus_interface_meta com_planetexpress_Ship_meta; /* interface info for com.planetexpress.Pilot */ extern const struct sbus_interface_meta test_pilot_meta; +/* interface info for com.planetexpress.Special */ +extern const struct sbus_interface_meta test_special_meta; + #endif /* __SBUS_CODEGEN_TESTS_XML__ */ |