diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-08-24 18:55:58 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-08-27 18:42:28 +0200 |
commit | aae2b488d084cf2af9a552a55e1d9cc614f2a12a (patch) | |
tree | c5aae783e9b099b00d62e1172d890726bf50355e /src/libsystemd/sd-bus/bus-util.c | |
parent | f1566e63da92cee5cbc0074df9cd9a8dc078a62e (diff) |
bus: split bus_map_all_properties into multiple helpers
The bus_map_all_properties() helper calls
org.freedesktop.DBus.Properties.GetAll() on a given target and parses the
result according to a given property-table. This simplifies dealing with
DBus.Properties significantly. However, the function is blocking and thus
not really useful in many situations.
This patch extracts the core of this function and adds two new helpers
which directly take dbus-messages as arguments. This way, you can issue
asynchronous requests and parse the result via these helpers:
bus_message_map_all_properties():
This is the same as bus_map_all_properties() but takes the result
message from a GetAll() request as argument. You can thus issue an
asynchronous GetAll() request and then use this helper once you got
the result.
bus_message_map_properties_changed():
This function takes a signal-message that was retrieved via a
PropertiesChanged signal and then parses it like if you retrieved
it via GetAll(). Furthermore, this function returns the number of
matched properties that got invalidated by the PropertiesChanged
signal, but didn't carry the new value. This way, the caller can
issue a new GetAll() request and then parse the result.
The old function bus_map_all_properties() is functionally unchanged, but
now uses bus_message_map_all_properties() internally.
Diffstat (limited to 'src/libsystemd/sd-bus/bus-util.c')
-rw-r--r-- | src/libsystemd/sd-bus/bus-util.c | 93 |
1 files changed, 72 insertions, 21 deletions
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c index c97bf7d99d..aed3889b12 100644 --- a/src/libsystemd/sd-bus/bus-util.c +++ b/src/libsystemd/sd-bus/bus-util.c @@ -974,32 +974,17 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_ return r; } -int bus_map_all_properties(sd_bus *bus, - const char *destination, - const char *path, - const struct bus_properties_map *map, - void *userdata) { - _cleanup_bus_message_unref_ sd_bus_message *m = NULL; +int bus_message_map_all_properties(sd_bus *bus, + sd_bus_message *m, + const struct bus_properties_map *map, + void *userdata) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(bus); - assert(destination); - assert(path); + assert(m); assert(map); - r = sd_bus_call_method( - bus, - destination, - path, - "org.freedesktop.DBus.Properties", - "GetAll", - &error, - &m, - "s", ""); - if (r < 0) - return r; - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); if (r < 0) return r; @@ -1052,7 +1037,73 @@ int bus_map_all_properties(sd_bus *bus, return r; } - return r; + return sd_bus_message_exit_container(m); +} + +int bus_message_map_properties_changed(sd_bus *bus, + sd_bus_message *m, + const struct bus_properties_map *map, + void *userdata) { + const char *member; + int r, invalidated, i; + + assert(bus); + assert(m); + assert(map); + + /* skip interface, but allow callers to do that themselves */ + sd_bus_message_skip(m, "s"); + + r = bus_message_map_all_properties(bus, m, map, userdata); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s"); + if (r < 0) + return r; + + invalidated = 0; + while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0) + for (i = 0; map[i].member; i++) + if (streq(map[i].member, member)) { + ++invalidated; + break; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + return invalidated; +} + +int bus_map_all_properties(sd_bus *bus, + const char *destination, + const char *path, + const struct bus_properties_map *map, + void *userdata) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + assert(bus); + assert(destination); + assert(path); + assert(map); + + r = sd_bus_call_method( + bus, + destination, + path, + "org.freedesktop.DBus.Properties", + "GetAll", + &error, + &m, + "s", ""); + if (r < 0) + return r; + + return bus_message_map_all_properties(bus, m, map, userdata); } int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) { |