[Libosinfo] [libosinfo PATCH 24/31] os: Make devices functions more generic

Fabiano Fidêncio fidencio at redhat.com
Fri Nov 23 10:15:13 UTC 2018


As the Guest Features will follow the very same logic provided for
Guest Devices, let's take advantage of OsinfoLink and OsinfoLinkList
abstract classes and make the devices functions as generic as possible
so we can simply re-use everything when adding support for Guest
Features.

Signed-off-by: Fabiano Fidêncio <fidencio at redhat.com>
---
 osinfo/osinfo_os.c | 304 +++++++++++++++++++++++++++------------------
 1 file changed, 180 insertions(+), 124 deletions(-)

diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index 32b107c..7170984 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -78,9 +78,9 @@ enum {
 
 static void osinfo_os_finalize(GObject *object);
 
-static void osinfo_device_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED)
+static void osinfo_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED)
 {
-    g_object_unref(OSINFO_DEVICELINK(data));
+    g_object_unref(OSINFO_LINK(data));
 }
 
 static void
@@ -115,7 +115,7 @@ osinfo_os_finalize(GObject *object)
 {
     OsinfoOs *os = OSINFO_OS(object);
 
-    g_list_foreach(os->priv->deviceLinks, osinfo_device_link_free, NULL);
+    g_list_foreach(os->priv->deviceLinks, osinfo_link_free, NULL);
     g_list_free(os->priv->deviceLinks);
     g_object_unref(os->priv->medias);
     g_object_unref(os->priv->trees);
@@ -210,8 +210,8 @@ OsinfoOs *osinfo_os_new(const gchar *id)
 
 
 static gboolean
-add_entity_to_list_check(OsinfoEntity *ent1, /* OsinfoDeviceLink */
-                         OsinfoEntity *ent2, /* OsinfoDevice or OsinfoDevice Link */
+add_entity_to_list_check(OsinfoEntity *ent1, /* OsinfoLink */
+                         OsinfoEntity *ent2, /* OsinfoLink or its target*/
                          OsinfoFilter *filter,
                          gboolean include_unsupported)
 {
@@ -233,33 +233,35 @@ add_entity_to_list_check(OsinfoEntity *ent1, /* OsinfoDeviceLink */
 }
 
 
-static OsinfoDeviceList *
-osinfo_os_get_devices_internal(OsinfoOs *os,
+static void
+osinfo_os_get_targets_internal(OsinfoOs *os,
                                OsinfoFilter *filter,
-                               gboolean include_unsupported)
+                               gboolean include_unsupported,
+                               OsinfoList *list)
 {
-    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
-    g_return_val_if_fail(!filter || OSINFO_IS_FILTER(filter), NULL);
+    g_return_if_fail(OSINFO_IS_OS(os));
+    g_return_if_fail(!filter || OSINFO_IS_FILTER(filter));
 
-    OsinfoDeviceList *newList = osinfo_devicelist_new();
     GList *tmp = NULL;
 
-    tmp = os->priv->deviceLinks;
+    if (OSINFO_IS_DEVICELIST(list)) {
+        tmp = os->priv->deviceLinks;
+    } else {
+        g_return_if_reached();
+    }
 
     while (tmp) {
-        OsinfoDeviceLink *devlink = OSINFO_DEVICELINK(tmp->data);
-        OsinfoDevice *dev = OSINFO_DEVICE(osinfo_link_get_target(OSINFO_LINK(devlink)));
+        OsinfoLink *link = OSINFO_LINK(tmp->data);
+        OsinfoEntity *ent = osinfo_link_get_target(link);
 
-        if (add_entity_to_list_check(OSINFO_ENTITY(devlink),
-                                     OSINFO_ENTITY(dev),
+        if (add_entity_to_list_check(OSINFO_ENTITY(link),
+                                     ent,
                                      filter,
                                      include_unsupported))
-            osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(dev));
+            osinfo_list_add(list, ent);
 
         tmp = tmp->next;
     }
-
-    return newList;
 }
 
 
@@ -274,108 +276,140 @@ osinfo_os_get_devices_internal(OsinfoOs *os,
  */
 OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *os, OsinfoFilter *filter)
 {
-    return osinfo_os_get_devices_internal(os, filter, FALSE);
+    OsinfoDeviceList *devlist = osinfo_devicelist_new();
+
+    osinfo_os_get_targets_internal(os, filter, FALSE, OSINFO_LIST(devlist));
+    return devlist;
 }
 
-struct GetAllDevicesData {
+struct GetAllTargetsData {
     OsinfoFilter *filter;
-    OsinfoDeviceList *devices;
+    OsinfoList *targets;
 };
 
-static void get_all_devices_cb(OsinfoProduct *product, gpointer user_data)
+static void get_all_targets_cb(OsinfoProduct *product, gpointer user_data)
 {
-    OsinfoDeviceList *devices;
+    OsinfoList *targets;
     OsinfoList *tmp_list;
-    struct GetAllDevicesData *foreach_data = (struct GetAllDevicesData *)user_data;
+    OsinfoOs *os;
+    struct GetAllTargetsData *foreach_data = (struct GetAllTargetsData *)user_data;
 
     g_return_if_fail(OSINFO_IS_OS(product));
 
-    devices = osinfo_os_get_devices_internal(OSINFO_OS(product),
-                                             foreach_data->filter,
-                                             TRUE);
-    tmp_list = osinfo_list_new_union(OSINFO_LIST(foreach_data->devices),
-                                     OSINFO_LIST(devices));
-    g_object_unref(foreach_data->devices);
-    g_object_unref(devices);
-    foreach_data->devices = OSINFO_DEVICELIST(tmp_list);
-}
+    os = OSINFO_OS(product);
 
+    if (OSINFO_IS_DEVICELIST(foreach_data->targets)) {
+        targets = OSINFO_LIST(osinfo_devicelist_new());
+    } else {
+        g_return_if_reached();
+    }
 
-static OsinfoDeviceLinkList *
-osinfo_os_get_all_device_links_internal(OsinfoOs *os,
-                                        OsinfoFilter *filter,
-                                        gboolean include_unsupported);
+    osinfo_os_get_targets_internal(os,
+                                   foreach_data->filter,
+                                   TRUE,
+                                   OSINFO_LIST(targets));
+    tmp_list = osinfo_list_new_union(OSINFO_LIST(foreach_data->targets),
+                                     OSINFO_LIST(targets));
+    g_object_unref(foreach_data->targets);
+    g_object_unref(targets);
+    foreach_data->targets = tmp_list;
+}
 
 
-/**
- * osinfo_os_get_all_devices:
- * @os: an operating system
- * @filter: (allow-none)(transfer none): an optional device property filter
- *
- * Get all devices matching a given filter but unlike osinfo_os_get_devices
- * this function also retrieves devices from all derived and cloned operating
- * systems.
- *
- * Returns: (transfer full): A list of devices
- */
-OsinfoDeviceList *osinfo_os_get_all_devices(OsinfoOs *os, OsinfoFilter *filter)
+static OsinfoLinkList *
+osinfo_os_get_all_links_internal(OsinfoOs *os,
+                                 OsinfoFilter *filter,
+                                 gboolean include_unsupported,
+                                 OsinfoLinkList *links);
+
+static OsinfoList *
+osinfo_os_get_all_targets(OsinfoOs *os,
+                          OsinfoFilter *filter,
+                          gpointer user_data)
 {
-    struct GetAllDevicesData foreach_data = {
-        .filter = filter,
-        .devices = osinfo_devicelist_new()
-    };
-    OsinfoDeviceLinkList *devlinks;
-    OsinfoDeviceLinkList *unsupported_devlinks;
-    OsinfoDeviceList *unsupported_devs;
-    OsinfoDeviceList *new_list;
+    OsinfoLinkList *links;
+    OsinfoLinkList *tmp_links;
+    OsinfoLinkList *unsupported_links;
+    OsinfoList *unsupported_targets;
+    OsinfoList *new_list;
     OsinfoFilter *unsupported_filter;
     GList *list, *unsupported_list;
     GList *it;
+    struct GetAllTargetsData *data = (struct GetAllTargetsData *)user_data;
 
     osinfo_product_foreach_related(OSINFO_PRODUCT(os),
                                    OSINFO_PRODUCT_FOREACH_FLAG_DERIVES_FROM |
                                    OSINFO_PRODUCT_FOREACH_FLAG_CLONES,
-                                   get_all_devices_cb,
-                                   &foreach_data);
-
-    devlinks = osinfo_os_get_all_device_links_internal(os, filter, TRUE);
+                                   get_all_targets_cb,
+                                   data);
+
+    if (OSINFO_IS_DEVICELIST(data->targets)) {
+        links = OSINFO_LINKLIST(osinfo_devicelinklist_new());
+        tmp_links = OSINFO_LINKLIST(osinfo_devicelinklist_new());
+        unsupported_links = OSINFO_LINKLIST(osinfo_devicelinklist_new());
+        unsupported_targets = OSINFO_LIST(osinfo_devicelist_new());
+        new_list = OSINFO_LIST(osinfo_devicelist_new());
+    } else {
+        g_return_val_if_reached(NULL);
+    }
+    links = osinfo_os_get_all_links_internal(os, filter, TRUE, tmp_links);
 
     unsupported_filter = osinfo_filter_new();
     osinfo_filter_add_constraint(unsupported_filter,
                                  OSINFO_LINK_PROP_SUPPORTED,
                                  "false");
 
-    unsupported_devlinks = OSINFO_DEVICELINKLIST
-        (osinfo_list_new_filtered(OSINFO_LIST(devlinks), unsupported_filter));
+    unsupported_links = OSINFO_LINKLIST(osinfo_list_new_filtered(OSINFO_LIST(links),
+                                                                 unsupported_filter));
 
-    unsupported_devs = osinfo_devicelist_new();
-    osinfo_linklist_get_targets(OSINFO_LINKLIST(unsupported_devlinks),
+    osinfo_linklist_get_targets(unsupported_links,
                                 NULL,
-                                OSINFO_LIST(unsupported_devs));
+                                unsupported_targets);
 
-    list = osinfo_list_get_elements(OSINFO_LIST(foreach_data.devices));
-    unsupported_list = osinfo_list_get_elements(OSINFO_LIST(unsupported_devs));
+    list = osinfo_list_get_elements(OSINFO_LIST(data->targets));
+    unsupported_list = osinfo_list_get_elements(OSINFO_LIST(unsupported_targets));
 
-    new_list = osinfo_devicelist_new();
     for (it = list; it != NULL; it = it->next) {
-        OsinfoDevice *dev = OSINFO_DEVICE(it->data);
-        if (g_list_find(unsupported_list, dev))
+        OsinfoEntity *target = OSINFO_ENTITY(it->data);
+        if (g_list_find(unsupported_list, target))
             continue;
 
-        osinfo_list_add(OSINFO_LIST(new_list), OSINFO_ENTITY(dev));
+        osinfo_list_add(new_list, target);
     }
 
     g_list_free(list);
     g_list_free(unsupported_list);
-    g_object_unref(devlinks);
-    g_object_unref(unsupported_devlinks);
-    g_object_unref(unsupported_devs);
+    g_object_unref(links);
+    g_object_unref(unsupported_links);
+    g_object_unref(unsupported_targets);
     g_object_unref(unsupported_filter);
-    g_object_unref(foreach_data.devices);
+    g_object_unref(data->targets);
 
     return new_list;
 }
 
+
+/**
+ * osinfo_os_get_all_devices:
+ * @os: an operating system
+ * @filter: (allow-none)(transfer none): an optional device property filter
+ *
+ * Get all devices matching a given filter but unlike osinfo_os_get_devices
+ * this function also retrieves devices from all derived and cloned operating
+ * systems.
+ *
+ * Returns: (transfer full): A list of devices
+ */
+OsinfoDeviceList *osinfo_os_get_all_devices(OsinfoOs *os, OsinfoFilter *filter)
+{
+    struct GetAllTargetsData foreach_data = {
+        .filter = filter,
+        .targets = OSINFO_LIST(osinfo_devicelist_new()),
+    };
+
+    return OSINFO_DEVICELIST(osinfo_os_get_all_targets(os, filter, &foreach_data));
+}
+
 /**
  * osinfo_os_get_devices_by_property:
  * @os: an operating system
@@ -410,32 +444,34 @@ OsinfoDeviceList *osinfo_os_get_devices_by_property(OsinfoOs *os,
 }
 
 
-static OsinfoDeviceLinkList *
-osinfo_os_get_device_links_internal(OsinfoOs *os,
-                                    OsinfoFilter *filter,
-                                    gboolean include_unsupported)
+static void
+osinfo_os_get_links_internal(OsinfoOs *os,
+                             OsinfoFilter *filter,
+                             gboolean include_unsupported,
+                             OsinfoLinkList *list)
 {
-    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
-    g_return_val_if_fail(!filter || OSINFO_IS_FILTER(filter), NULL);
+    g_return_if_fail(OSINFO_IS_OS(os));
+    g_return_if_fail(!filter || OSINFO_IS_FILTER(filter));
 
-    OsinfoDeviceLinkList *newList = osinfo_devicelinklist_new();
     GList *tmp = NULL;
 
-    tmp = os->priv->deviceLinks;
+    if (OSINFO_IS_DEVICELINKLIST(list)) {
+        tmp = os->priv->deviceLinks;
+    } else {
+        g_return_if_reached();
+    }
 
     while (tmp) {
-        OsinfoDeviceLink *devlink = OSINFO_DEVICELINK(tmp->data);
+        OsinfoLink *link = OSINFO_LINK(tmp->data);
 
-        if (add_entity_to_list_check(OSINFO_ENTITY(devlink),
-                                     OSINFO_ENTITY(devlink),
+        if (add_entity_to_list_check(OSINFO_ENTITY(link),
+                                     OSINFO_ENTITY(link),
                                      filter,
                                      include_unsupported))
-            osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(devlink));
+            osinfo_list_add(OSINFO_LIST(list), OSINFO_ENTITY(link));
 
         tmp = tmp->next;
     }
-
-    return newList;
 }
 
 
@@ -451,73 +487,89 @@ osinfo_os_get_device_links_internal(OsinfoOs *os,
  */
 OsinfoDeviceLinkList *osinfo_os_get_device_links(OsinfoOs *os, OsinfoFilter *filter)
 {
-    return osinfo_os_get_device_links_internal(os, filter, FALSE);
+    OsinfoDeviceLinkList *list = osinfo_devicelinklist_new();
+    osinfo_os_get_links_internal(os,
+                                 filter,
+                                 FALSE,
+                                 OSINFO_LINKLIST(list));
+    return list;
 }
 
 
-struct GetAllDeviceLinksData {
+struct GetAllLinksData {
     OsinfoFilter *filter;
-    OsinfoDeviceLinkList *device_links;
+    OsinfoLinkList *links;
 };
 
-static void get_all_device_links_cb(OsinfoProduct *product, gpointer user_data)
+static void get_all_links_cb(OsinfoProduct *product, gpointer user_data)
 {
-    OsinfoDeviceLinkList *device_links;
+    OsinfoLinkList *links;
     OsinfoList *tmp_list;
-    struct GetAllDeviceLinksData *foreach_data;
+    struct GetAllLinksData *foreach_data;
 
     g_return_if_fail(OSINFO_IS_OS(product));
 
-    foreach_data = (struct GetAllDeviceLinksData *)user_data;
-    device_links = osinfo_os_get_device_links_internal(OSINFO_OS(product),
-                                                       foreach_data->filter,
-                                                       TRUE);
-    tmp_list = osinfo_list_new_union(OSINFO_LIST(foreach_data->device_links),
-                                     OSINFO_LIST(device_links));
-    g_object_unref(foreach_data->device_links);
-    g_object_unref(device_links);
-    foreach_data->device_links = OSINFO_DEVICELINKLIST(tmp_list);
+    foreach_data = (struct GetAllLinksData *)user_data;
+
+    if (OSINFO_IS_DEVICELINKLIST(foreach_data->links)) {
+        links = OSINFO_LINKLIST(osinfo_devicelinklist_new());
+    } else {
+        g_return_if_reached();
+    }
+    osinfo_os_get_links_internal(OSINFO_OS(product),
+                                 foreach_data->filter,
+                                 TRUE,
+                                 links);
+    tmp_list = osinfo_list_new_union(OSINFO_LIST(foreach_data->links),
+                                     OSINFO_LIST(links));
+    g_object_unref(foreach_data->links);
+    g_object_unref(links);
+    foreach_data->links = OSINFO_LINKLIST(tmp_list);
 }
 
-static OsinfoDeviceLinkList *
-osinfo_os_get_all_device_links_internal(OsinfoOs *os,
-                                        OsinfoFilter *filter,
-                                        gboolean include_unsupported)
+static OsinfoLinkList *
+osinfo_os_get_all_links_internal(OsinfoOs *os,
+                                 OsinfoFilter *filter,
+                                 gboolean include_unsupported,
+                                 OsinfoLinkList *links)
 {
-    struct GetAllDeviceLinksData foreach_data = {
+    struct GetAllLinksData foreach_data = {
         .filter = filter,
-        .device_links = osinfo_devicelinklist_new()
+        .links = links
     };
-    OsinfoDeviceLinkList *devlinks;
+    OsinfoLinkList *new_links;
     GList *list, *it;
 
     osinfo_product_foreach_related(OSINFO_PRODUCT(os),
                                    OSINFO_PRODUCT_FOREACH_FLAG_DERIVES_FROM |
                                    OSINFO_PRODUCT_FOREACH_FLAG_CLONES,
-                                   get_all_device_links_cb,
+                                   get_all_links_cb,
                                    &foreach_data);
 
     if (include_unsupported)
-        return foreach_data.device_links;
-
-    devlinks = osinfo_devicelinklist_new();
+        return foreach_data.links;
 
-    list = osinfo_list_get_elements(OSINFO_LIST(foreach_data.device_links));
+    if (OSINFO_IS_DEVICELINKLIST(foreach_data.links)) {
+        new_links = OSINFO_LINKLIST(osinfo_devicelinklist_new());
+    } else {
+        g_return_val_if_reached(NULL);
+    }
+    list = osinfo_list_get_elements(OSINFO_LIST(foreach_data.links));
     for (it = list; it != NULL; it = it->next) {
-        OsinfoDeviceLink *devlink = OSINFO_DEVICELINK(it->data);
+        OsinfoLink *link = OSINFO_LINK(it->data);
 
-        if (!osinfo_entity_get_param_value_boolean_with_default(OSINFO_ENTITY(devlink),
+        if (!osinfo_entity_get_param_value_boolean_with_default(OSINFO_ENTITY(link),
                                                                 OSINFO_LINK_PROP_SUPPORTED,
                                                                 TRUE))
             continue;
 
-        osinfo_list_add(OSINFO_LIST(devlinks), OSINFO_ENTITY(devlink));
+        osinfo_list_add(OSINFO_LIST(new_links), OSINFO_ENTITY(link));
     }
 
-    g_object_unref(foreach_data.device_links);
+    g_object_unref(foreach_data.links);
     g_list_free(list);
 
-    return devlinks;
+    return new_links;
 }
 
 /**
@@ -533,7 +585,11 @@ osinfo_os_get_all_device_links_internal(OsinfoOs *os,
  */
 OsinfoDeviceLinkList *osinfo_os_get_all_device_links(OsinfoOs *os, OsinfoFilter *filter)
 {
-    return osinfo_os_get_all_device_links_internal(os, filter, FALSE);
+    OsinfoDeviceLinkList *links = osinfo_devicelinklist_new();
+    return OSINFO_DEVICELINKLIST(osinfo_os_get_all_links_internal(os,
+                                                                  filter,
+                                                                  FALSE,
+                                                                  OSINFO_LINKLIST(links)));
 }
 
 /**
-- 
2.19.1




More information about the Libosinfo mailing list