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.
This commit is contained in:
Richard Hughes 2019-06-29 21:55:41 +01:00
parent 13fd21d806
commit dd71b729e8
8 changed files with 151 additions and 110 deletions

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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:
*

View File

@ -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,

View File

@ -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:
*

View File

@ -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;