chiark / gitweb /
bus: split bus_map_all_properties into multiple helpers
authorDavid Herrmann <dh.herrmann@gmail.com>
Sun, 24 Aug 2014 16:55:58 +0000 (18:55 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Wed, 27 Aug 2014 16:42:28 +0000 (18:42 +0200)
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.

src/libsystemd/sd-bus/bus-util.c
src/libsystemd/sd-bus/bus-util.h

index c97bf7d99d04ba775d66158512b3f39592f5b221..aed3889b121819a255545e254fb6799f6904e5d3 100644 (file)
@@ -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) {
index faf1775809b53aef72a004c452d72cfbcd0ea79f..696daa1f0329fda3a348db4234e8e8d68201b942 100644 (file)
@@ -46,6 +46,14 @@ struct bus_properties_map {
 
 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
 
+int bus_message_map_all_properties(sd_bus *bus,
+                                   sd_bus_message *m,
+                                   const struct bus_properties_map *map,
+                                   void *userdata);
+int bus_message_map_properties_changed(sd_bus *bus,
+                                       sd_bus_message *m,
+                                       const struct bus_properties_map *map,
+                                       void *userdata);
 int bus_map_all_properties(sd_bus *bus,
                            const char *destination,
                            const char *path,