From dd71b729e8b1eca9f7e0caf0fca0e69ea6b67882 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Sat, 29 Jun 2019 21:55:41 +0100 Subject: [PATCH] Export functionality to build an array of objects This makes it possible to call GetDevices in an async D-Bus call, and easily construct an array of objects from the return value. --- libfwupd/fwupd-client.c | 96 +++----------------------------- libfwupd/fwupd-device-private.h | 3 +- libfwupd/fwupd-device.c | 63 +++++++++++++++++++-- libfwupd/fwupd-release-private.h | 3 +- libfwupd/fwupd-release.c | 44 +++++++++++++-- libfwupd/fwupd-remote-private.h | 3 +- libfwupd/fwupd-remote.c | 41 ++++++++++++-- libfwupd/fwupd.map | 8 +++ 8 files changed, 151 insertions(+), 110 deletions(-) diff --git a/libfwupd/fwupd-client.c b/libfwupd/fwupd-client.c index b3b8aeee9..1e444b88c 100644 --- a/libfwupd/fwupd-client.c +++ b/libfwupd/fwupd-client.c @@ -252,88 +252,6 @@ fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **e return TRUE; } -static GPtrArray * -fwupd_client_parse_releases_from_variant (GVariant *val) -{ - GPtrArray *array = NULL; - gsize sz; - g_autoptr(GVariant) untuple = NULL; - - array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - untuple = g_variant_get_child_value (val, 0); - sz = g_variant_n_children (untuple); - for (guint i = 0; i < sz; i++) { - FwupdRelease *rel; - g_autoptr(GVariant) data = NULL; - data = g_variant_get_child_value (untuple, i); - rel = fwupd_release_from_variant (data); - if (rel == NULL) - continue; - g_ptr_array_add (array, rel); - } - return array; -} - -static GPtrArray * -fwupd_client_parse_devices_from_variant (GVariant *val) -{ - GPtrArray *array = NULL; - gsize sz; - g_autoptr(GVariant) untuple = NULL; - g_autoptr(GHashTable) devices_by_id = NULL; - - array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - devices_by_id = g_hash_table_new (g_str_hash, g_str_equal); - untuple = g_variant_get_child_value (val, 0); - sz = g_variant_n_children (untuple); - for (guint i = 0; i < sz; i++) { - FwupdDevice *dev; - g_autoptr(GVariant) data = NULL; - data = g_variant_get_child_value (untuple, i); - dev = fwupd_device_from_variant (data); - if (dev == NULL) - continue; - g_ptr_array_add (array, dev); - if (fwupd_device_get_id (dev) != NULL) { - g_hash_table_insert (devices_by_id, - (gpointer) fwupd_device_get_id (dev), - (gpointer) dev); - } - } - - /* set the parent on each child */ - for (guint i = 0; i < array->len; i++) { - FwupdDevice *dev = g_ptr_array_index (array, i); - const gchar *parent_id = fwupd_device_get_parent_id (dev); - if (parent_id != NULL) { - FwupdDevice *dev_tmp; - dev_tmp = g_hash_table_lookup (devices_by_id, parent_id); - fwupd_device_set_parent (dev, dev_tmp); - } - } - - return array; -} - -static GPtrArray * -fwupd_client_parse_remotes_from_data (GVariant *devices) -{ - GPtrArray *remotes = NULL; - gsize sz; - g_autoptr(GVariant) untuple = NULL; - - remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); - untuple = g_variant_get_child_value (devices, 0); - sz = g_variant_n_children (untuple); - for (guint i = 0; i < sz; i++) { - g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i); - FwupdRemote *remote = fwupd_remote_from_variant (data); - g_ptr_array_add (remotes, remote); - } - - return remotes; -} - static void fwupd_client_fixup_dbus_error (GError *error) { @@ -406,7 +324,7 @@ fwupd_client_get_devices (FwupdClient *client, GCancellable *cancellable, GError fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_devices_from_variant (val); + return fwupd_device_array_from_variant (val); } /** @@ -448,7 +366,7 @@ fwupd_client_get_history (FwupdClient *client, GCancellable *cancellable, GError fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_devices_from_variant (val); + return fwupd_device_array_from_variant (val); } /** @@ -537,7 +455,7 @@ fwupd_client_get_releases (FwupdClient *client, const gchar *device_id, fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_releases_from_variant (val); + return fwupd_release_array_from_variant (val); } /** @@ -582,7 +500,7 @@ fwupd_client_get_downgrades (FwupdClient *client, const gchar *device_id, fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_releases_from_variant (val); + return fwupd_release_array_from_variant (val); } /** @@ -627,7 +545,7 @@ fwupd_client_get_upgrades (FwupdClient *client, const gchar *device_id, fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_releases_from_variant (val); + return fwupd_release_array_from_variant (val); } static void @@ -1193,7 +1111,7 @@ fwupd_client_get_details (FwupdClient *client, const gchar *filename, } /* return results */ - return fwupd_client_parse_devices_from_variant (helper->val); + return fwupd_device_array_from_variant (helper->val); } /** @@ -1410,7 +1328,7 @@ fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError fwupd_client_fixup_dbus_error (*error); return NULL; } - return fwupd_client_parse_remotes_from_data (val); + return fwupd_remote_array_from_variant (val); } /** diff --git a/libfwupd/fwupd-device-private.h b/libfwupd/fwupd-device-private.h index 8dac3b849..814e7a98a 100644 --- a/libfwupd/fwupd-device-private.h +++ b/libfwupd/fwupd-device-private.h @@ -13,7 +13,8 @@ G_BEGIN_DECLS -FwupdDevice *fwupd_device_from_variant (GVariant *data); +FwupdDevice *fwupd_device_from_variant (GVariant *value); +GPtrArray *fwupd_device_array_from_variant (GVariant *value); GVariant *fwupd_device_to_variant (FwupdDevice *device); GVariant *fwupd_device_to_variant_full (FwupdDevice *device, FwupdDeviceFlags flags); diff --git a/libfwupd/fwupd-device.c b/libfwupd/fwupd-device.c index f1cc91931..98c1a8913 100644 --- a/libfwupd/fwupd-device.c +++ b/libfwupd/fwupd-device.c @@ -1968,30 +1968,30 @@ fwupd_device_set_from_variant_iter (FwupdDevice *device, GVariantIter *iter) /** * fwupd_device_from_variant: - * @data: a #GVariant + * @value: a #GVariant * * Creates a new device using packed data. * - * Returns: (transfer full): a new #FwupdDevice, or %NULL if @data was invalid + * Returns: (transfer full): a new #FwupdDevice, or %NULL if @value was invalid * * Since: 1.0.0 **/ FwupdDevice * -fwupd_device_from_variant (GVariant *data) +fwupd_device_from_variant (GVariant *value) { FwupdDevice *dev = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; /* format from GetDetails */ - type_string = g_variant_get_type_string (data); + type_string = g_variant_get_type_string (value); if (g_strcmp0 (type_string, "(a{sv})") == 0) { dev = fwupd_device_new (); - g_variant_get (data, "(a{sv})", &iter); + g_variant_get (value, "(a{sv})", &iter); fwupd_device_set_from_variant_iter (dev, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { dev = fwupd_device_new (); - g_variant_get (data, "a{sv}", &iter); + g_variant_get (value, "a{sv}", &iter); fwupd_device_set_from_variant_iter (dev, iter); } else { g_warning ("type %s not known", type_string); @@ -1999,6 +1999,57 @@ fwupd_device_from_variant (GVariant *data) return dev; } +/** + * fwupd_device_array_from_variant: + * @value: a #GVariant + * + * Creates an array of new devices using packed data. + * + * Returns: (transfer container) (element-type FwupdDevice): devices, or %NULL if @value was invalid + * + * Since: 1.2.10 + **/ +GPtrArray * +fwupd_device_array_from_variant (GVariant *value) +{ + GPtrArray *array = NULL; + gsize sz; + g_autoptr(GVariant) untuple = NULL; + g_autoptr(GHashTable) devices_by_id = NULL; + + array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + devices_by_id = g_hash_table_new (g_str_hash, g_str_equal); + untuple = g_variant_get_child_value (value, 0); + sz = g_variant_n_children (untuple); + for (guint i = 0; i < sz; i++) { + FwupdDevice *dev; + g_autoptr(GVariant) data = NULL; + data = g_variant_get_child_value (untuple, i); + dev = fwupd_device_from_variant (data); + if (dev == NULL) + continue; + g_ptr_array_add (array, dev); + if (fwupd_device_get_id (dev) != NULL) { + g_hash_table_insert (devices_by_id, + (gpointer) fwupd_device_get_id (dev), + (gpointer) dev); + } + } + + /* set the parent on each child */ + for (guint i = 0; i < array->len; i++) { + FwupdDevice *dev = g_ptr_array_index (array, i); + const gchar *parent_id = fwupd_device_get_parent_id (dev); + if (parent_id != NULL) { + FwupdDevice *dev_tmp; + dev_tmp = g_hash_table_lookup (devices_by_id, parent_id); + fwupd_device_set_parent (dev, dev_tmp); + } + } + + return array; +} + /** * fwupd_device_compare: * @device1: a #FwupdDevice diff --git a/libfwupd/fwupd-release-private.h b/libfwupd/fwupd-release-private.h index b79954cec..1e8768832 100644 --- a/libfwupd/fwupd-release-private.h +++ b/libfwupd/fwupd-release-private.h @@ -13,7 +13,8 @@ G_BEGIN_DECLS -FwupdRelease *fwupd_release_from_variant (GVariant *data); +FwupdRelease *fwupd_release_from_variant (GVariant *value); +GPtrArray *fwupd_release_array_from_variant (GVariant *value); GVariant *fwupd_release_to_variant (FwupdRelease *release); void fwupd_release_to_json (FwupdRelease *release, JsonBuilder *builder); diff --git a/libfwupd/fwupd-release.c b/libfwupd/fwupd-release.c index 6a9cd6468..92e7ab4ec 100644 --- a/libfwupd/fwupd-release.c +++ b/libfwupd/fwupd-release.c @@ -1529,30 +1529,30 @@ fwupd_release_set_from_variant_iter (FwupdRelease *release, GVariantIter *iter) /** * fwupd_release_from_variant: - * @data: a #GVariant + * @value: a #GVariant * * Creates a new release using packed data. * - * Returns: (transfer full): a new #FwupdRelease, or %NULL if @data was invalid + * Returns: (transfer full): a new #FwupdRelease, or %NULL if @value was invalid * * Since: 1.0.0 **/ FwupdRelease * -fwupd_release_from_variant (GVariant *data) +fwupd_release_from_variant (GVariant *value) { FwupdRelease *rel = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; /* format from GetDetails */ - type_string = g_variant_get_type_string (data); + type_string = g_variant_get_type_string (value); if (g_strcmp0 (type_string, "(a{sv})") == 0) { rel = fwupd_release_new (); - g_variant_get (data, "(a{sv})", &iter); + g_variant_get (value, "(a{sv})", &iter); fwupd_release_set_from_variant_iter (rel, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { rel = fwupd_release_new (); - g_variant_get (data, "a{sv}", &iter); + g_variant_get (value, "a{sv}", &iter); fwupd_release_set_from_variant_iter (rel, iter); } else { g_warning ("type %s not known", type_string); @@ -1560,6 +1560,38 @@ fwupd_release_from_variant (GVariant *data) return rel; } +/** + * fwupd_release_array_from_variant: + * @value: a #GVariant + * + * Creates an array of new releases using packed data. + * + * Returns: (transfer container) (element-type FwupdRelease): releases, or %NULL if @value was invalid + * + * Since: 1.2.10 + **/ +GPtrArray * +fwupd_release_array_from_variant (GVariant *value) +{ + GPtrArray *array = NULL; + gsize sz; + g_autoptr(GVariant) untuple = NULL; + + array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + untuple = g_variant_get_child_value (value, 0); + sz = g_variant_n_children (untuple); + for (guint i = 0; i < sz; i++) { + FwupdRelease *rel; + g_autoptr(GVariant) data = NULL; + data = g_variant_get_child_value (untuple, i); + rel = fwupd_release_from_variant (data); + if (rel == NULL) + continue; + g_ptr_array_add (array, rel); + } + return array; +} + /** * fwupd_release_new: * diff --git a/libfwupd/fwupd-remote-private.h b/libfwupd/fwupd-remote-private.h index acf5b42d3..0fec51e22 100644 --- a/libfwupd/fwupd-remote-private.h +++ b/libfwupd/fwupd-remote-private.h @@ -10,7 +10,8 @@ G_BEGIN_DECLS -FwupdRemote *fwupd_remote_from_variant (GVariant *data); +FwupdRemote *fwupd_remote_from_variant (GVariant *value); +GPtrArray *fwupd_remote_array_from_variant (GVariant *value); GVariant *fwupd_remote_to_variant (FwupdRemote *self); gboolean fwupd_remote_load_from_filename (FwupdRemote *self, const gchar *filename, diff --git a/libfwupd/fwupd-remote.c b/libfwupd/fwupd-remote.c index 2bc80d47e..ff4283bb1 100644 --- a/libfwupd/fwupd-remote.c +++ b/libfwupd/fwupd-remote.c @@ -1212,30 +1212,30 @@ fwupd_remote_finalize (GObject *obj) /** * fwupd_remote_from_variant: - * @data: a #GVariant + * @value: a #GVariant * * Creates a new remote using packed data. * - * Returns: (transfer full): a new #FwupdRemote, or %NULL if @data was invalid + * Returns: (transfer full): a new #FwupdRemote, or %NULL if @value was invalid * * Since: 1.0.0 **/ FwupdRemote * -fwupd_remote_from_variant (GVariant *data) +fwupd_remote_from_variant (GVariant *value) { FwupdRemote *rel = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; - type_string = g_variant_get_type_string (data); + type_string = g_variant_get_type_string (value); if (g_strcmp0 (type_string, "(a{sv})") == 0) { rel = fwupd_remote_new (); - g_variant_get (data, "(a{sv})", &iter); + g_variant_get (value, "(a{sv})", &iter); fwupd_remote_set_from_variant_iter (rel, iter); fwupd_remote_set_from_variant_iter (rel, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { rel = fwupd_remote_new (); - g_variant_get (data, "a{sv}", &iter); + g_variant_get (value, "a{sv}", &iter); fwupd_remote_set_from_variant_iter (rel, iter); } else { g_warning ("type %s not known", type_string); @@ -1243,6 +1243,35 @@ fwupd_remote_from_variant (GVariant *data) return rel; } +/** + * fwupd_remote_array_from_variant: + * @value: a #GVariant + * + * Creates an array of new devices using packed data. + * + * Returns: (transfer container) (element-type FwupdRemote): remotes, or %NULL if @value was invalid + * + * Since: 1.2.10 + **/ +GPtrArray * +fwupd_remote_array_from_variant (GVariant *value) +{ + GPtrArray *remotes = NULL; + gsize sz; + g_autoptr(GVariant) untuple = NULL; + + remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + untuple = g_variant_get_child_value (value, 0); + sz = g_variant_n_children (untuple); + for (guint i = 0; i < sz; i++) { + g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i); + FwupdRemote *remote = fwupd_remote_from_variant (data); + g_ptr_array_add (remotes, remote); + } + + return remotes; +} + /** * fwupd_remote_new: * diff --git a/libfwupd/fwupd.map b/libfwupd/fwupd.map index b56aa892b..f7456b53d 100644 --- a/libfwupd/fwupd.map +++ b/libfwupd/fwupd.map @@ -363,3 +363,11 @@ LIBFWUPD_1.2.9 { fwupd_version_format_to_string; local: *; } LIBFWUPD_1.2.8; + +LIBFWUPD_1.2.10 { + global: + fwupd_device_array_from_variant; + fwupd_release_array_from_variant; + fwupd_remote_array_from_variant; + local: *; +} LIBFWUPD_1.2.9;