From 4f7f714e118e95896fac5239c7a8b529c39a4758 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 21 May 2014 21:29:15 +0200 Subject: SBUS: Implement org.freedesktop.DBus.Properties.GetAll for primitive types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements the GetAll method of the org.freedesktop.DBus.Properties interface by iterating over the available getters and putting all the results into a single getter. The patch includes a unit test that exercies all currently supported array types. Reviewed-by: Pavel Březina Reviewed-by: Lukáš Slebodník --- src/sbus/sbus_codegen | 100 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 9 deletions(-) (limited to 'src/sbus/sbus_codegen') diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen index 6507753f2..15a6cadac 100755 --- a/src/sbus/sbus_codegen +++ b/src/sbus/sbus_codegen @@ -291,6 +291,21 @@ def source_method_invoker(signature, args): out(");") out("}") +def source_prop_types(prop, type_prefix=False): + prefix = "%s_" % prop.type if type_prefix else "" + if prop.is_array: + out(" %s *%sprop_val;", prop.sssd_type, prefix) + out(" int %sprop_len;", prefix) + out(" %s *%sout_val;", prop.dbus_type, prefix) + else: + out(" %s %sprop_val;", prop.sssd_type, prefix) + out(" %s %sout_val;", prop.dbus_type, prefix) + +def source_prop_handler(prop, type_prefix=False): + prefix = "%s_" % prop.type if type_prefix else "" + out(" %s", prop.getter_signature("%shandler" % prefix), new_line=False) + out(";") + def source_getter_invoker(prop): out("") if prop.is_array: @@ -300,13 +315,9 @@ def source_getter_invoker(prop): out("static int %s(struct sbus_request *dbus_req, void *function_ptr)", prop.getter_invoker_name()) out("{") - if prop.is_array: - out(" %s *prop_val;", prop.sssd_type) - out(" int prop_len;") - out(" %s *out_val;", prop.dbus_type) - else: - out(" %s prop_val;", prop.sssd_type) - out(" %s out_val;", prop.dbus_type) + + source_prop_types(prop) + out("") out(" %s", prop.getter_signature("handler"), new_line=False) out(" = function_ptr;") @@ -330,6 +341,73 @@ def source_getter_invoker(prop): out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant) out("}") +def source_getall_invoker(iface, prop_invokers): + out("") + out("/* invokes GetAll for the '%s' interface */", iface.name) + out("static int invoke_%s_get_all(struct sbus_request *dbus_req, void *function_ptr)", + iface.c_name()) + out("{") + out(" DBusMessage *reply;") + out(" dbus_bool_t dbret;") + out(" DBusMessageIter iter;") + out(" DBusMessageIter iter_dict;") + if iface.properties: + out(" int ret;") + out(" struct sbus_interface *intf = dbus_req->intf;") + out(" const struct sbus_property_meta *property;") + + iface_types = [ p.type for p in iface.properties ] + for prop in [ p for p in prop_invokers.values() if p.type in iface_types ]: + source_prop_types(prop, type_prefix=True) + source_prop_handler(prop, type_prefix=True) + out("") + + out(" reply = dbus_message_new_method_return(dbus_req->message);") + out(" if (!reply) return ENOMEM;") + out(" dbus_message_iter_init_append(reply, &iter);") + out(" dbret = dbus_message_iter_open_container(") + out(" &iter, DBUS_TYPE_ARRAY,") + out(" DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING") + out(" DBUS_TYPE_STRING_AS_STRING") + out(" DBUS_TYPE_VARIANT_AS_STRING") + out(" DBUS_DICT_ENTRY_END_CHAR_AS_STRING,") + out(" &iter_dict);") + out(" if (!dbret) return ENOMEM;") + out("") + + for prop in iface.properties: + out(" property = sbus_meta_find_property(intf->vtable->meta, \"%s\");", prop.c_name()) + out(" if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) {") + out(" %s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);", prop.type) + out(" if (%s_handler) {", prop.type) + out(" (%s_handler)(dbus_req, dbus_req->intf->instance_data, &%s_prop_val", prop.type, prop.type, new_line=False) + if prop.is_array: + out(", &%s_prop_len", prop.type, new_line=False) + out(");") + if prop.type == "s": + out(" %s_out_val = %s_prop_val == NULL ? \"\" : %s_prop_val;", + prop.type, prop.type, prop.type) + elif prop.type == "o": + out(" %s_out_val = %s_prop_val == NULL ? \"/\" : %s_prop_val;", + prop.type, prop.type, prop.type) + else: + out(" %s_out_val = %s_prop_val;", prop.type, prop.type) + if prop.is_array: + out(" ret = sbus_add_array_as_variant_to_dict(&iter_dict, \"%s\", %s, (uint8_t*)%s_out_val, %s_prop_len, sizeof(%s));", prop.c_name(), prop.dbus_constant, prop.type, prop.type, prop.sssd_type) + else: + out(" ret = sbus_add_variant_to_dict(&iter_dict, \"%s\", %s, &%s_out_val);", prop.c_name(), prop.dbus_constant, prop.type) + out(" if (ret != EOK) return ret;") + out(" }") + out(" }") + out("") + + out(" dbret = dbus_message_iter_close_container(&iter, &iter_dict);") + out(" if (!dbret) return ENOMEM;") + out("") + + out(" return sbus_request_finish(dbus_req, reply);") + out("}") + def forward_method_invokers(ifaces): invokers = { } for iface in ifaces: @@ -509,9 +587,10 @@ def source_interface(iface): else: out(" NULL, /* no signals */") if iface.properties: - out(" %s__properties", iface.c_name()) + out(" %s__properties,", iface.c_name()) else: - out(" NULL, /* no propetries */") + out(" NULL, /* no properties */") + out(" invoke_%s_get_all, /* GetAll invoker */", iface.c_name()) out("};") def generate_source(ifaces, filename, include_header=None): @@ -543,6 +622,9 @@ def generate_source(ifaces, filename, include_header=None): if iface.properties: source_properties(iface, iface.properties) + # always generate getall, for interfaces without properties + # let's return an empty array + source_getall_invoker(iface, prop_invokers) # The sbus_interface structure source_interface(iface) -- cgit