summaryrefslogtreecommitdiffstats
path: root/src/sbus/sbus_codegen
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-04-23 03:01:21 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-05-22 17:36:20 +0200
commit90e04eae7e54ec892a6f239783df94dab5d1ed9a (patch)
tree78f6b1d72e26f079c8888238742614126ce67535 /src/sbus/sbus_codegen
parent1319e71fd1680ca4864afe0b1aca2b8c8e4a1ee4 (diff)
downloadsssd-90e04eae7e54ec892a6f239783df94dab5d1ed9a.tar.gz
sssd-90e04eae7e54ec892a6f239783df94dab5d1ed9a.tar.xz
sssd-90e04eae7e54ec892a6f239783df94dab5d1ed9a.zip
SBUS: Implement org.freedesktop.DBus.Properties.Get for primitive types
This patch implements type-safe getters for primitive types and their arrays. The patch includes unit tests of all supported types and arrays of these types. All getter are synchronous. The getters never fail, instead, they return a default or 'not defined' value. Making the getters synchronous and always returning a value will make it significantly easier to implement the GetAll method. Reviewed-by: Stef Walter <stefw@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src/sbus/sbus_codegen')
-rwxr-xr-xsrc/sbus/sbus_codegen114
1 files changed, 74 insertions, 40 deletions
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index 96248a628..a8f91b784 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -187,6 +187,16 @@ 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 getter_name(self):
+ return "%s_get_%s" % (self.iface.c_name(), self.c_name())
+ def getter_invoker_name(self):
+ return "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
class Interface(Base):
def __init__(self, name):
@@ -237,6 +247,9 @@ def method_function_pointer(meth, name, with_names=False):
with_names and "data" or "",
method_arg_types(meth.in_args, with_names))
+def property_handlers(prop):
+ return prop.getter_signature(prop.getter_name())
+
def forward_method_invoker(signature, args):
out("")
out("/* invokes a handler with a '%s' DBus signature */", signature)
@@ -280,49 +293,36 @@ def source_method_invoker(signature, args):
def source_getter_invoker(prop):
out("")
- out("/* invokes a getter with a '%s' DBus type */", type)
- out("static int invoke_%s_getter(struct sbus_request *request, struct sbus_interface *intf, void *function_ptr)", prop.type)
+ if prop.is_array:
+ out("/* invokes a getter with an array of '%s' DBus type */", prop.dbus_type)
+ else:
+ out("/* invokes a getter with a '%s' DBus type */", prop.dbus_type)
+ out("static int %s(struct sbus_request *dbus_req, void *function_ptr)",
+ prop.getter_invoker_name())
out("{")
- out(" DBusError error = DBUS_ERROR_INIT;")
- out(" int ret;")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.is_array:
- out(" %s *arg_%d;", arg.dbus_type, i)
- out(" int len_%d;", i)
- else:
- out(" %s arg_%d;", arg.dbus_type, i)
- out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args))
+ 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)
out("")
- out(" if (!dbus_message_get_args(request->message, &error,")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.is_array:
- out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,",
- arg.dbus_constant, i, i)
- else:
- out(" %s, &arg_%d,", arg.dbus_constant, i)
- out(" DBUS_TYPE_INVALID)) {")
- out(" ret = sbus_request_fail_and_finish(request, error.name, error.message);")
- out(" dbus_error_free(&error);")
- out(" return ret;")
- out(" }")
+ out(" %s", prop.getter_signature("handler"), new_line=False)
+ out(" = function_ptr;")
out("")
- out(" ret = (handler)(request, intf", new_line=False)
- for i in range(0, len(args)):
- arg = args[i]
- out(",\n arg_%d", i, new_line=False)
- if arg.is_array:
- out(",\n len_%d", i, new_line=False)
+ out(" (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val", new_line=False)
+ if prop.is_array:
+ out(", &prop_len", new_line=False)
out(");")
- out("")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.type in ["as", "ao"]:
- out(" dbus_free_string_array((char **)arg_%d);", i)
- out(" return ret;")
+ out("")
+ out(" out_val = prop_val;")
+ if prop.is_array:
+ out(" return sbus_request_return_array_as_variant(dbus_req, %s, (uint8_t*)out_val, prop_len, sizeof(%s));", prop.dbus_constant, prop.sssd_type)
+ else:
+ out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant)
out("}")
def forward_method_invokers(ifaces):
@@ -342,6 +342,27 @@ def source_method_invokers(invokers):
for (signature, meth) in invokers.items():
source_method_invoker(signature, meth.in_args)
+def forward_prop_invoker(prop):
+ out("static int %s(struct sbus_request *dbus_req, void *function_ptr);",
+ prop.getter_invoker_name())
+
+def forward_prop_invokers(ifaces):
+ invokers = { }
+ for iface in ifaces:
+ for prop in iface.properties:
+ if not prop.is_basic:
+ continue
+ if prop.type in invokers:
+ continue
+ forward_prop_invoker(prop)
+ invokers[prop.type] = prop
+ return invokers
+
+def source_prop_invokers(invokers):
+ for (type, prop) in invokers.items():
+ if prop.readable:
+ source_getter_invoker(prop)
+
def source_finisher(meth):
out("")
out("int %s_finish(struct sbus_request *req%s)",
@@ -438,6 +459,7 @@ def source_signals(iface, signals):
def source_properties(iface, properties):
out("")
out("/* property info for %s */", iface.name)
+
out("const struct sbus_property_meta %s__properties[] = {", iface.c_name())
for prop in properties:
out(" {")
@@ -451,6 +473,14 @@ def source_properties(iface, properties):
out(" SBUS_PROPERTY_WRITABLE,")
else:
assert False, "should not be reached"
+ if prop.readable:
+ out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name())
+ out(" %s,", prop.getter_invoker_name())
+ else:
+ out(" 0, /* not readable */")
+ out(" NULL, /* no invoker */")
+ out(" 0, /* not writable */")
+ out(" NULL, /* no invoker */")
out(" },")
out(" { NULL, }")
out("};")
@@ -491,7 +521,8 @@ def generate_source(ifaces, filename, include_header=None):
if include_header:
out("#include \"%s\"", os.path.basename(include_header))
- invokers = forward_method_invokers(ifaces)
+ meth_invokers = forward_method_invokers(ifaces)
+ prop_invokers = forward_prop_invokers(ifaces)
for iface in ifaces:
@@ -510,7 +541,8 @@ def generate_source(ifaces, filename, include_header=None):
# The sbus_interface structure
source_interface(iface)
- source_method_invokers(invokers)
+ source_method_invokers(meth_invokers)
+ source_prop_invokers(prop_invokers)
def header_finisher(iface, meth):
if meth.use_raw_handler():
@@ -529,6 +561,8 @@ def header_vtable(iface, methods):
# All methods
for meth in iface.methods:
out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True))
+ for prop in iface.properties:
+ out(" %s;", property_handlers(prop))
out("};")
@@ -584,7 +618,7 @@ def generate_header(ifaces, filename):
out(" */")
for iface in ifaces:
- if iface.methods:
+ if iface.methods or iface.properties:
header_vtable(iface, iface.methods)
for meth in iface.methods:
header_finisher(iface, meth)