[virt-tools-list] [PATCH 01/47] Move all source & headers into osinfo/ directory
Daniel P. Berrange
berrange at redhat.com
Wed Aug 25 19:36:56 UTC 2010
The GLib/GObject standard practice is to have all source and
header files in the same directory, named after the library
prefix. Move all headers from api/ and inc/ into src/, then
rename src/ to osinfo/
* src/*, api/*, inc/*: Move to osinfo/
* Makefile.am: Update build rules for changed locations
* configure.ac: change AC_CONFIG_SRCDIR
---
Makefile.am | 48 +-
api/osinfo.h | 17 -
api/osinfo_db.h | 87 ----
api/osinfo_device.h | 49 ---
api/osinfo_devicelist.h | 50 ---
api/osinfo_entity.h | 51 ---
api/osinfo_filter.h | 64 ---
api/osinfo_hypervisor.h | 52 ---
api/osinfo_hypervisorlist.h | 50 ---
api/osinfo_list.h | 51 ---
api/osinfo_os.h | 55 ---
api/osinfo_oslist.h | 51 ---
configure.ac | 2 +-
inc/osinfo_common.h | 258 -----------
osinfo/osinfo.h | 17 +
osinfo/osinfo_common.c | 349 +++++++++++++++
osinfo/osinfo_common.h | 258 +++++++++++
osinfo/osinfo_dataread.c | 915 ++++++++++++++++++++++++++++++++++++++++
osinfo/osinfo_db.c | 555 ++++++++++++++++++++++++
osinfo/osinfo_db.h | 87 ++++
osinfo/osinfo_device.c | 94 ++++
osinfo/osinfo_device.h | 49 +++
osinfo/osinfo_devicelist.c | 121 ++++++
osinfo/osinfo_devicelist.h | 50 +++
osinfo/osinfo_entity.c | 321 ++++++++++++++
osinfo/osinfo_entity.h | 51 +++
osinfo/osinfo_filter.c | 298 +++++++++++++
osinfo/osinfo_filter.h | 64 +++
osinfo/osinfo_hypervisor.c | 122 ++++++
osinfo/osinfo_hypervisor.h | 52 +++
osinfo/osinfo_hypervisorlist.c | 121 ++++++
osinfo/osinfo_hypervisorlist.h | 50 +++
osinfo/osinfo_list.c | 219 ++++++++++
osinfo/osinfo_list.h | 51 +++
osinfo/osinfo_os.c | 402 ++++++++++++++++++
osinfo/osinfo_os.h | 55 +++
osinfo/osinfo_oslist.c | 121 ++++++
osinfo/osinfo_oslist.h | 51 +++
src/osinfo_common.c | 349 ---------------
src/osinfo_dataread.c | 915 ----------------------------------------
src/osinfo_db.c | 555 ------------------------
src/osinfo_device.c | 94 ----
src/osinfo_devicelist.c | 121 ------
src/osinfo_entity.c | 321 --------------
src/osinfo_filter.c | 298 -------------
src/osinfo_hypervisor.c | 122 ------
src/osinfo_hypervisorlist.c | 121 ------
src/osinfo_list.c | 219 ----------
src/osinfo_os.c | 402 ------------------
src/osinfo_oslist.c | 121 ------
50 files changed, 4498 insertions(+), 4498 deletions(-)
delete mode 100644 api/osinfo.h
delete mode 100644 api/osinfo_db.h
delete mode 100644 api/osinfo_device.h
delete mode 100644 api/osinfo_devicelist.h
delete mode 100644 api/osinfo_entity.h
delete mode 100644 api/osinfo_filter.h
delete mode 100644 api/osinfo_hypervisor.h
delete mode 100644 api/osinfo_hypervisorlist.h
delete mode 100644 api/osinfo_list.h
delete mode 100644 api/osinfo_os.h
delete mode 100644 api/osinfo_oslist.h
delete mode 100644 inc/osinfo_common.h
create mode 100644 osinfo/osinfo.h
create mode 100644 osinfo/osinfo_common.c
create mode 100644 osinfo/osinfo_common.h
create mode 100644 osinfo/osinfo_dataread.c
create mode 100644 osinfo/osinfo_db.c
create mode 100644 osinfo/osinfo_db.h
create mode 100644 osinfo/osinfo_device.c
create mode 100644 osinfo/osinfo_device.h
create mode 100644 osinfo/osinfo_devicelist.c
create mode 100644 osinfo/osinfo_devicelist.h
create mode 100644 osinfo/osinfo_entity.c
create mode 100644 osinfo/osinfo_entity.h
create mode 100644 osinfo/osinfo_filter.c
create mode 100644 osinfo/osinfo_filter.h
create mode 100644 osinfo/osinfo_hypervisor.c
create mode 100644 osinfo/osinfo_hypervisor.h
create mode 100644 osinfo/osinfo_hypervisorlist.c
create mode 100644 osinfo/osinfo_hypervisorlist.h
create mode 100644 osinfo/osinfo_list.c
create mode 100644 osinfo/osinfo_list.h
create mode 100644 osinfo/osinfo_os.c
create mode 100644 osinfo/osinfo_os.h
create mode 100644 osinfo/osinfo_oslist.c
create mode 100644 osinfo/osinfo_oslist.h
delete mode 100644 src/osinfo_common.c
delete mode 100644 src/osinfo_dataread.c
delete mode 100644 src/osinfo_db.c
delete mode 100644 src/osinfo_device.c
delete mode 100644 src/osinfo_devicelist.c
delete mode 100644 src/osinfo_entity.c
delete mode 100644 src/osinfo_filter.c
delete mode 100644 src/osinfo_hypervisor.c
delete mode 100644 src/osinfo_hypervisorlist.c
delete mode 100644 src/osinfo_list.c
delete mode 100644 src/osinfo_os.c
delete mode 100644 src/osinfo_oslist.c
diff --git a/Makefile.am b/Makefile.am
index f424d4c..22acdcb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,33 +1,33 @@
-AM_CPPFLAGS = -I$(top_srcdir)/inc -I$(top_srcdir)/api $(LIBXML_CFLAGS) $(GOBJECT_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir) $(LIBXML_CFLAGS) $(GOBJECT_CFLAGS)
libosinfo_la_LDFLAGS = $(LIBXML_LIBS) $(GOBJECT_LIBS)
lib_LTLIBRARIES = libosinfo.la
libosinfo_la_SOURCES = \
- api/osinfo_db.h \
- api/osinfo_device.h \
- api/osinfo_devicelist.h \
- api/osinfo_entity.h \
- api/osinfo_filter.h \
- api/osinfo_hypervisor.h \
- api/osinfo_hypervisorlist.h \
- api/osinfo_list.h \
- api/osinfo_os.h \
- api/osinfo_oslist.h \
- inc/osinfo_common.h \
- src/osinfo_common.c \
- src/osinfo_dataread.c \
- src/osinfo_device.c \
- src/osinfo_devicelist.c \
- src/osinfo_entity.c \
- src/osinfo_filter.c \
- src/osinfo_hypervisor.c \
- src/osinfo_hypervisorlist.c \
- src/osinfo_list.c \
- src/osinfo_oslist.c \
- src/osinfo_db.c \
- src/osinfo_os.c
+ osinfo/osinfo_db.h \
+ osinfo/osinfo_device.h \
+ osinfo/osinfo_devicelist.h \
+ osinfo/osinfo_entity.h \
+ osinfo/osinfo_filter.h \
+ osinfo/osinfo_hypervisor.h \
+ osinfo/osinfo_hypervisorlist.h \
+ osinfo/osinfo_list.h \
+ osinfo/osinfo_os.h \
+ osinfo/osinfo_oslist.h \
+ osinfo/osinfo_common.h \
+ osinfo/osinfo_common.c \
+ osinfo/osinfo_dataread.c \
+ osinfo/osinfo_device.c \
+ osinfo/osinfo_devicelist.c \
+ osinfo/osinfo_entity.c \
+ osinfo/osinfo_filter.c \
+ osinfo/osinfo_hypervisor.c \
+ osinfo/osinfo_hypervisorlist.c \
+ osinfo/osinfo_list.c \
+ osinfo/osinfo_oslist.c \
+ osinfo/osinfo_db.c \
+ osinfo/osinfo_os.c
check_PROGRAMS = \
test/test-skeleton
diff --git a/api/osinfo.h b/api/osinfo.h
deleted file mode 100644
index 63a06e4..0000000
--- a/api/osinfo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __OSINFO_H__
-#define __OSINFO_H__
-
-#include <glib-object.h>
-#include <osinfo_common.h>
-#include <osinfo_db.h>
-#include <osinfo_entity.h>
-#include <osinfo_device.h>
-#include <osinfo_os.h>
-#include <osinfo_hypervisor.h>
-#include <osinfo_filter.h>
-#include <osinfo_list.h>
-#include <osinfo_devicelist.h>
-#include <osinfo_oslist.h>
-#include <osinfo_hypervisorlist.h>
-
-#endif
diff --git a/api/osinfo_db.h b/api/osinfo_db.h
deleted file mode 100644
index 305ed29..0000000
--- a/api/osinfo_db.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_db.h
- * Represents the main entry point to data contained by libosinfo.
- */
-
-#ifndef __OSINFO_DB_H__
-#define __OSINFO_DB_H__
-
-#include "osinfo_devicelist.h"
-#include "osinfo_hypervisorlist.h"
-#include "osinfo_oslist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DB (osinfo_db_get_type ())
-#define OSINFO_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DB, OsinfoDb))
-#define OSINFO_IS_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DB))
-#define OSINFO_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DB, OsinfoDbClass))
-#define OSINFO_IS_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DB))
-#define OSINFO_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DB, OsinfoDbClass))
-
-//typedef struct _OsinfoDb OsinfoDb;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoDbClass OsinfoDbClass;
-
-typedef struct _OsinfoDbPrivate OsinfoDbPrivate;
-
-/*
- * To get a db handle, we construct one with a construct-time only
- * backing data directory. It is already considered to be initialized
- * on return from the constructor, and ready to do work.
- *
- * To close it, we call the destructor on it.
- * Setting parameters on it will work if it's not a construct-time only
- * parameter. Reading will always work. Currently the backing directory and
- * libvirt version are the only parameters.
- *
- * The db object contains information related to three main classes of
- * objects: hypervisors, operating systems and devices.
- */
-
-/* object */
-struct _OsinfoDb
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoDbPrivate *priv;
-};
-
-/* class */
-struct _OsinfoDbClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-int osinfoInitializeDb(OsinfoDb *self, GError **err);
-
-OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *hvId, GError **err);
-OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *devId, GError **err);
-OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *osId, GError **err);
-
-OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
-
-// Get me all unique values for property "vendor" among operating systems
-GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all unique values for property "vendor" among hypervisors
-GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all unique values for property "vendor" among devices
-GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err);
-
-// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
-OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err);
-
-#endif /* __OSINFO_DB_H__ */
diff --git a/api/osinfo_device.h b/api/osinfo_device.h
deleted file mode 100644
index 9f10e6b..0000000
--- a/api/osinfo_device.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_device.h
- * Represents a device in libosinfo.
- */
-
-#ifndef __OSINFO_DEVICE_H__
-#define __OSINFO_DEVICE_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DEVICE (osinfo_device_get_type ())
-#define OSINFO_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICE, OsinfoDevice))
-#define OSINFO_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICE))
-#define OSINFO_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
-#define OSINFO_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICE))
-#define OSINFO_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
-
-//typedef struct _OsinfoDevice OsinfoDevice;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoDeviceClass OsinfoDeviceClass;
-
-typedef struct _OsinfoDevicePrivate OsinfoDevicePrivate;
-
-/* object */
-struct _OsinfoDevice
-{
- OsinfoEntity parent_instance;
-
- /* public */
-
- /* private */
- OsinfoDevicePrivate *priv;
-};
-
-/* class */
-struct _OsinfoDeviceClass
-{
- OsinfoEntityClass parent_class;
-
- /* class members */
-};
-
-gchar *osinfoGetDeviceDriver(OsinfoDevice *self, gchar *devType, OsinfoOs *os, OsinfoHypervisor *hv, GError **err);
-
-#endif /* __OSINFO_DEVICE_H__ */
diff --git a/api/osinfo_devicelist.h b/api/osinfo_devicelist.h
deleted file mode 100644
index 49e2715..0000000
--- a/api/osinfo_devicelist.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_devicelist.h
- */
-
-#ifndef __OSINFO_DEVICELIST_H__
-#define __OSINFO_DEVICELIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_DEVICELIST (osinfo_devicelist_get_type ())
-#define OSINFO_DEVICELIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceList))
-#define OSINFO_IS_DEVICELIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICELIST))
-#define OSINFO_DEVICELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
-#define OSINFO_IS_DEVICELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICELIST))
-#define OSINFO_DEVICELIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
-
-typedef struct _OsinfoDeviceList OsinfoDeviceList;
-
-typedef struct _OsinfoDeviceListClass OsinfoDeviceListClass;
-
-typedef struct _OsinfoDeviceListPrivate OsinfoDeviceListPrivate;
-
-/* object */
-struct _OsinfoDeviceList
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoDeviceListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoDeviceListClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err);
-OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err);
-OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
-OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
-
-#endif /* __OSINFO_DEVICELIST_H__ */
diff --git a/api/osinfo_entity.h b/api/osinfo_entity.h
deleted file mode 100644
index 0c8047c..0000000
--- a/api/osinfo_entity.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_entity.h
- * All entities represented in libosinfo are derived from this class.
- */
-
-#ifndef __OSINFO_ENTITY_H__
-#define __OSINFO_ENTITY_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_ENTITY (osinfo_entity_get_type ())
-#define OSINFO_ENTITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_ENTITY, OsinfoEntity))
-#define OSINFO_IS_ENTITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_ENTITY))
-#define OSINFO_ENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
-#define OSINFO_IS_ENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_ENTITY))
-#define OSINFO_ENTITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
-
-typedef struct _OsinfoEntity OsinfoEntity;
-
-typedef struct _OsinfoEntityClass OsinfoEntityClass;
-
-typedef struct _OsinfoEntityPrivate OsinfoEntityPrivate;
-
-/* object */
-struct _OsinfoEntity
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoEntityPrivate *priv;
-};
-
-/* class */
-struct _OsinfoEntityClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-gchar *osinfoGetId(OsinfoEntity *self, GError **err);
-GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err);
-gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err);
-GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err);
-
-#endif /* __OSINFO_ENTITY_H__ */
diff --git a/api/osinfo_filter.h b/api/osinfo_filter.h
deleted file mode 100644
index 9a60fcd..0000000
--- a/api/osinfo_filter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_filter.h
- * Represents a filter in libosinfo.
- */
-
-#ifndef __OSINFO_FILTER_H__
-#define __OSINFO_FILTER_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_FILTER (osinfo_filter_get_type ())
-#define OSINFO_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_FILTER, OsinfoFilter))
-#define OSINFO_IS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_FILTER))
-#define OSINFO_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_FILTER, OsinfoFilterClass))
-#define OSINFO_IS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_FILTER))
-#define OSINFO_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_FILTER, OsinfoFilterClass))
-
-//typedef struct _OsinfoFilter OsinfoFilter;
-// (defined in osinfo_objects.h)
-
-#include "osinfo_oslist.h"
-
-typedef struct _OsinfoFilterClass OsinfoFilterClass;
-
-typedef struct _OsinfoFilterPrivate OsinfoFilterPrivate;
-
-/* object */
-struct _OsinfoFilter
-{
- OsinfoEntity parent_instance;
-
- /* public */
-
- /* private */
- OsinfoFilterPrivate *priv;
-};
-
-/* class */
-struct _OsinfoFilterClass
-{
- OsinfoEntityClass parent_class;
-
- /* class members */
-};
-
-void osinfoFreeFilter(OsinfoFilter *self);
-
-gint osinfoAddFilterContstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err);
-
-// Only applicable to OSes, ignored by other types of objects
-gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err);
-
-void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName);
-void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp);
-void osinfoClearAllFilterConstraints(OsinfoFilter *self);
-
-GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err);
-gchar *osinfoGetFilterConstraintValue(OsinfoFilter *self, GError **err);
-OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err);
-
-#endif /* __OSINFO_FILTER_H__ */
diff --git a/api/osinfo_hypervisor.h b/api/osinfo_hypervisor.h
deleted file mode 100644
index 65c78dc..0000000
--- a/api/osinfo_hypervisor.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_hypervisor.h
- * Represents a hypervisor in libosinfo.
- */
-
-#ifndef __OSINFO_HYPERVISOR_H__
-#define __OSINFO_HYPERVISOR_H__
-
-#include "osinfo_devicelist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_HYPERVISOR (osinfo_hypervisor_get_type ())
-#define OSINFO_HYPERVISOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisor))
-#define OSINFO_IS_HYPERVISOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISOR))
-#define OSINFO_HYPERVISOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
-#define OSINFO_IS_HYPERVISOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISOR))
-#define OSINFO_HYPERVISOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
-
-//typedef struct _OsinfoHypervisor OsinfoHypervisor;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoHypervisorClass OsinfoHypervisorClass;
-
-typedef struct _OsinfoHypervisorPrivate OsinfoHypervisorPrivate;
-
-/* object */
-struct _OsinfoHypervisor
-{
- OsinfoEntity parent_instance;
-
- /* public */
-
- /* private */
- OsinfoHypervisorPrivate *priv;
-};
-
-/* class */
-struct _OsinfoHypervisorClass
-{
- OsinfoEntityClass parent_class;
-
- /* class members */
-};
-
-GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err);
-OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err);
-
-#endif /* __OSINFO_HYPERVISOR_H__ */
diff --git a/api/osinfo_hypervisorlist.h b/api/osinfo_hypervisorlist.h
deleted file mode 100644
index bdc7f03..0000000
--- a/api/osinfo_hypervisorlist.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_hypervisorlist.h
- */
-
-#ifndef __OSINFO_HYPERVISORLIST_H__
-#define __OSINFO_HYPERVISORLIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_HYPERVISORLIST (osinfo_hypervisorlist_get_type ())
-#define OSINFO_HYPERVISORLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorList))
-#define OSINFO_IS_HYPERVISORLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISORLIST))
-#define OSINFO_HYPERVISORLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
-#define OSINFO_IS_HYPERVISORLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISORLIST))
-#define OSINFO_HYPERVISORLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
-
-typedef struct _OsinfoHypervisorList OsinfoHypervisorList;
-
-typedef struct _OsinfoHypervisorListClass OsinfoHypervisorListClass;
-
-typedef struct _OsinfoHypervisorListPrivate OsinfoHypervisorListPrivate;
-
-/* object */
-struct _OsinfoHypervisorList
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoHypervisorListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoHypervisorListClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err);
-OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err);
-OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
-OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
-
-#endif /* __OSINFO_HYPERVISORLIST_H__ */
diff --git a/api/osinfo_list.h b/api/osinfo_list.h
deleted file mode 100644
index 81a2bc7..0000000
--- a/api/osinfo_list.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_list.h
- */
-
-#ifndef __OSINFO_LIST_H__
-#define __OSINFO_LIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_LIST (osinfo_list_get_type ())
-#define OSINFO_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_LIST, OsinfoList))
-#define OSINFO_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_LIST))
-#define OSINFO_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_LIST, OsinfoListClass))
-#define OSINFO_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_LIST))
-#define OSINFO_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_LIST, OsinfoListClass))
-
-typedef struct _OsinfoListClass OsinfoListClass;
-
-typedef struct _OsinfoListPrivate OsinfoListPrivate;
-
-/* object */
-struct _OsinfoList
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoListClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-void osinfoFreeList(OsinfoList *self);
-gint osinfoListLength(OsinfoList *self);
-
-OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err);
-OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx);
-OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err);
-OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err);
-
-#endif /* __OSINFO_LIST_H__ */
diff --git a/api/osinfo_os.h b/api/osinfo_os.h
deleted file mode 100644
index 83241c9..0000000
--- a/api/osinfo_os.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_os.h
- * Represents an operating system in libosinfo.
- */
-
-#ifndef __OSINFO_OS_H__
-#define __OSINFO_OS_H__
-
-#include <glib-object.h>
-#include "osinfo_oslist.h"
-#include "osinfo_devicelist.h"
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_OS (osinfo_os_get_type ())
-#define OSINFO_OS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OS, OsinfoOs))
-#define OSINFO_IS_OS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OS))
-#define OSINFO_OS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OS, OsinfoOsClass))
-#define OSINFO_IS_OS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OS))
-#define OSINFO_OS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OS, OsinfoOsClass))
-
-//typedef struct _OsinfoOs OsinfoOs;
-// (defined in osinfo_objects.h)
-
-typedef struct _OsinfoOsClass OsinfoOsClass;
-
-typedef struct _OsinfoOsPrivate OsinfoOsPrivate;
-
-/* object */
-struct _OsinfoOs
-{
- OsinfoEntity parent_instance;
-
- /* public */
-
- /* private */
- OsinfoOsPrivate *priv;
-};
-
-/* class */
-struct _OsinfoOsClass
-{
- OsinfoEntityClass parent_class;
-
- /* class members */
-};
-
-OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
-OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err);
-OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
-
-#endif /* __OSINFO_OS_H__ */
diff --git a/api/osinfo_oslist.h b/api/osinfo_oslist.h
deleted file mode 100644
index 168f5a5..0000000
--- a/api/osinfo_oslist.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_oslist.h
- * All entities represented in libosinfo are derived from this class.
- */
-
-#ifndef __OSINFO_OSLIST_H__
-#define __OSINFO_OSLIST_H__
-
-/*
- * Type macros.
- */
-#define OSINFO_TYPE_OSLIST (osinfo_oslist_get_type ())
-#define OSINFO_OSLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OSLIST, OsinfoOsList))
-#define OSINFO_IS_OSLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OSLIST))
-#define OSINFO_OSLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
-#define OSINFO_IS_OSLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OSLIST))
-#define OSINFO_OSLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
-
-typedef struct _OsinfoOsList OsinfoOsList;
-
-typedef struct _OsinfoOsListClass OsinfoOsListClass;
-
-typedef struct _OsinfoOsListPrivate OsinfoOsListPrivate;
-
-/* object */
-struct _OsinfoOsList
-{
- GObject parent_instance;
-
- /* public */
-
- /* private */
- OsinfoOsListPrivate *priv;
-};
-
-/* class */
-struct _OsinfoOsListClass
-{
- GObjectClass parent_class;
-
- /* class members */
-};
-
-OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err);
-OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err);
-OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
-OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
-
-#endif /* __OSINFO_OSLIST_H__ */
diff --git a/configure.ac b/configure.ac
index 845c3f3..9a182be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11.1 -Wall -Werror foreign color-tests])
AC_PREREQ([2.61])
-AC_CONFIG_SRCDIR([src/osinfo_common.c])
+AC_CONFIG_SRCDIR([osinfo/osinfo_common.c])
AC_CONFIG_HEADERS([config.h])
AC_PROG_LIBTOOL
AC_PROG_CC
diff --git a/inc/osinfo_common.h b/inc/osinfo_common.h
deleted file mode 100644
index 8f80c91..0000000
--- a/inc/osinfo_common.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * libosinfo
- *
- * osinfo_objects.h
- * Contains forward declarations of our main object types, and definitions
- * of our internal data structures not exposed in the API as libosinfo objects.
- */
-
-#ifndef __OSINFO_OBJECTS_H__
-#define __OSINFO_OBJECTS_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib-object.h>
-#include <errno.h>
-#include "osinfo_entity.h"
-
-#define FREE_N(x) free(x); x = null;
-
-typedef struct _OsinfoDb OsinfoDb;
-typedef struct _OsinfoDevice OsinfoDevice;
-typedef struct _OsinfoHypervisor OsinfoHypervisor;
-typedef struct _OsinfoOs OsinfoOs;
-typedef struct _OsinfoFilter OsinfoFilter;
-typedef struct _OsinfoList OsinfoList;
-
-typedef enum OSI_RELATIONSHIP {
- RELATIONSHIP_MIN = 0,
- DERIVES_FROM,
- UPGRADES,
- CLONES,
- RELATIONSHIP_MAX
-} osinfoRelationship;
-
-
-/** ****************************************************************************
- * Internal data structures
- ******************************************************************************/
-
-struct __osinfoDeviceLink {
- OsinfoDevice *dev;
- gchar *driver;
-};
-
-struct __osinfoHvSection {
- OsinfoHypervisor *hv;
- OsinfoOs *os;
-
- GTree *sections; // Mapping GString key (device type) to GTree of deviceLink structs
- GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-};
-
-struct __osinfoOsLink {
- /* <subject_os> 'verbs' <direct_object_os>
- * fedora11 upgrades fedora10
- * centos clones rhel
- * scientificlinux derives from rhel
- */
- OsinfoOs *subjectOs;
- osinfoRelationship verb;
- OsinfoOs *directObjectOs;
-};
-
-struct __osinfoPtrArrayErr {
- GPtrArray *array;
- int err;
-};
-
-struct __osinfoPopulateListArgs {
- GError **err;
- int errcode;
- OsinfoFilter *filter;
- OsinfoList *list;
-};
-
-struct __osinfoPopulateValuesArgs {
- GError **err;
- int errcode;
- GTree *values;
- gchar *property;
-};
-
-struct __osinfoOsCheckRelationshipArgs {
- OsinfoList *list;
- int errcode;
- GError **err;
- osinfoRelationship relshp;
-};
-
-struct __osinfoFilterPassArgs {
- int passed;
- OsinfoEntity *entity;
-};
-
-/** ****************************************************************************
- * Convenience methods
- ******************************************************************************/
-
-gint __osinfoIntCompareBase(gconstpointer a,
- gconstpointer b);
-gint __osinfoIntCompare(gconstpointer a,
- gconstpointer b,
- gpointer data);
-gint __osinfoStringCompareBase(gconstpointer a,
- gconstpointer b);
-gint __osinfoStringCompare(gconstpointer a,
- gconstpointer b,
- gpointer data);
-
-void __osinfoFreePtrArray(gpointer ptrarray);
-void __osinfoFreeRelationship(gpointer ptrarray);
-void __osinfoFreeParamVals(gpointer ptrarray);
-void __osinfoFreeDeviceSection(gpointer tree);
-void __osinfoFreeHvSection(gpointer hvSection);
-void __osinfoFreeDeviceLink(gpointer ptr);
-void __osinfoFreeOsLink(gpointer ptr);
-
-void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity);
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver);
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section);
-
-gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data);
-void __osinfoDupArray(gpointer data, gpointer user_data);
-
-int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *device);
-int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device);
-int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *device);
-int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *device);
-
-int __osinfoCheckGErrorParamValid(GError **err);
-int __osinfoCheckRelationshipValid(osinfoRelationship relshp);
-
-/** ****************************************************************************
- * Private structures for objects
- ******************************************************************************/
-
-struct _OsinfoFilterPrivate
-{
- // Key: Constraint name
- // Value: Array of constraint values
- GTree *propertyConstraints;
-
- // Key: relationship type
- // Value: Array of OsinfoOs *
- // Note: Only used when filtering OsinfoOs objects
- GTree *relationshipConstraints;
-};
-
-struct _OsinfoDbPrivate
-{
- int ready;
-
- gchar *backing_dir;
- gchar *libvirt_ver;
-
- GTree *devices;
- GTree *hypervisors;
- GTree *oses;
-
- GError *error;
-};
-
-struct _OsinfoDevicePrivate
-{
- int tmp;
-};
-
-struct _OsinfoHypervisorPrivate
-{
- // Key: gchar* (device type)
- // Value: Tree of device_link structs (multiple devices per type)
- GTree *sections;
- GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-};
-
-struct _OsinfoOsPrivate
-{
- // OS-Hypervisor specific information
- // Key: gchar* (hypervisor id)
- // Value: hv_section struct
- GTree *hypervisors;
-
- // Key: gchar* (device type)
- // Value: Tree of device_link structs (multiple devices per type)
- GTree *sections;
- GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-
- // OS-OS relationships
- // Key: gchar* (other os id)
- // Value: Array of os_link structs
- GTree *relationshipsByOs;
- // Key: relationship type
- // Value: Array of os_link structs
- GTree *relationshipsByType;
-};
-
-struct _OsinfoEntityPrivate
-{
- gchar *id;
-
- // Key: gchar*
- // Value: Array of gchar* values for key (multiple values allowed)
- GTree *params;
-
- OsinfoDb *db; // Backpointer to db object
-};
-
-/** ****************************************************************************
- * Error strings
- ******************************************************************************/
-
-gchar *__osinfoErrorToString(int err);
-
-#define OSINFO_OTHER "An unspecified error occured"
-#define OSINFO_OBJ_NOT_DB "Object is wrong type (expected OsInfoDb)"
-#define OSINFO_OBJ_NOT_ENTITY "Object is wrong type (expected OsInfoEntity)"
-#define OSINFO_OBJ_NOT_DEVICE "Object is wrong type (expected OsInfoDevice)"
-#define OSINFO_OBJ_NOT_OS "Object is wrong type (expected OsInfoOs)"
-#define OSINFO_OBJ_NOT_HV "Object is wrong type (expected OsInfoHypervisor)"
-#define OSINFO_OBJ_NOT_LIST "Object is wrong type (expected OsInfoList)"
-#define OSINFO_OBJ_NOT_HYPERVISORLIST "Object is wrong type (expected OsInfoHypervisorList)"
-#define OSINFO_OBJ_NOT_DEVICELIST "Object is wrong type (expected OsInfoDeviceList)"
-#define OSINFO_OBJ_NOT_OSLIST "Object is wrong type (expected OsInfoOsList)"
-#define OSINFO_OBJ_NOT_FILTER "Object is wrong type (expected OsInfoFilter)"
-#define OSINFO_NO_ID "No object id specified"
-#define OSINFO_NO_DEVTYPE "No device type specified"
-#define OSINFO_NO_MEM "Not enough memory to complete operation"
-#define OSINFO_NO_PROPNAME "No property specified"
-#define OSINFO_NO_PROPVAL "No value specified for property"
-#define OSINFO_INVALID_RELATIONSHIP "Invalid relationship specified"
-#endif /* __OSINFO_OBJECTS_H__ */
-
-/** ****************************************************************************
- * Private Methods
- ******************************************************************************/
-
-void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev);
-void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv);
-void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os);
-
-// Private
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section);
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
-void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
-
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId);
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId);
-
-// Private
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section);
-
-// Private
-int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value);
-void __osinfoClearParam(OsinfoEntity *self, gchar *key);
diff --git a/osinfo/osinfo.h b/osinfo/osinfo.h
new file mode 100644
index 0000000..7591487
--- /dev/null
+++ b/osinfo/osinfo.h
@@ -0,0 +1,17 @@
+#ifndef __OSINFO_H__
+#define __OSINFO_H__
+
+#include <glib-object.h>
+#include <osinfo/osinfo_common.h>
+#include <osinfo/osinfo_db.h>
+#include <osinfo/osinfo_entity.h>
+#include <osinfo/osinfo_device.h>
+#include <osinfo/osinfo_os.h>
+#include <osinfo/osinfo_hypervisor.h>
+#include <osinfo/osinfo_filter.h>
+#include <osinfo/osinfo_list.h>
+#include <osinfo/osinfo_devicelist.h>
+#include <osinfo/osinfo_oslist.h>
+#include <osinfo/osinfo_hypervisorlist.h>
+
+#endif
diff --git a/osinfo/osinfo_common.c b/osinfo/osinfo_common.c
new file mode 100644
index 0000000..15eb8cd
--- /dev/null
+++ b/osinfo/osinfo_common.c
@@ -0,0 +1,349 @@
+#include <osinfo/osinfo.h>
+
+static int __osinfoAddDeviceToList(GTree *allSectionsAsList,
+ gchar *sectionName,
+ struct __osinfoDeviceLink *deviceLink)
+{
+ if (!allSectionsAsList || !sectionName || !deviceLink)
+ return -EINVAL;
+
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *sectionList;
+ gchar *sectionNameDup = NULL;
+
+ found = g_tree_lookup_extended(allSectionsAsList, sectionName, &origKey, &foundValue);
+ if (!found) {
+ sectionList = g_ptr_array_new();
+ sectionNameDup = g_strdup(sectionName);
+
+ if (!sectionList)
+ goto error_free;
+ if (!sectionNameDup) {
+ g_ptr_array_free(sectionList, TRUE);
+ goto error_free;
+ }
+
+ g_tree_insert(allSectionsAsList, sectionNameDup, sectionList);
+ }
+ else
+ sectionList = (GPtrArray *) foundValue;
+
+ g_ptr_array_add(sectionList, deviceLink);
+ return 0;
+
+error_free:
+ g_free(sectionNameDup);
+ return -ENOMEM;
+}
+
+int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver)
+{
+ if (!allSections || !sectionName || !id)
+ return -EINVAL;
+
+ gboolean found;
+ gpointer origKey, foundValue;
+ gchar *sectionNameDup = NULL, *idDup = NULL, *driverDup = NULL;
+ GTree *section;
+ struct __osinfoDeviceLink *deviceLink;
+ int ret;
+
+ idDup = g_strdup(id);
+ driverDup = g_strdup(driver);
+ deviceLink = g_malloc(sizeof(*deviceLink));
+
+ if (!idDup || g_strcmp0(driverDup, driver) != 0 || !deviceLink)
+ goto error_free;
+
+ found = g_tree_lookup_extended(allSections, sectionName, &origKey, &foundValue);
+ if (!found) {
+ section = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceLink);
+ sectionNameDup = g_strdup(sectionName);
+
+ if (!section)
+ goto error_free;
+ if (!sectionNameDup) {
+ g_tree_destroy(section);
+ goto error_free;
+ }
+
+ g_tree_insert(allSections, sectionNameDup, section);
+ }
+ else
+ section = (GTree *) foundValue;
+
+ deviceLink->driver = driverDup;
+ g_tree_insert(section, idDup, deviceLink);
+
+ ret = 0;
+ if (allSectionsAsList)
+ ret = __osinfoAddDeviceToList(allSectionsAsList, sectionName, deviceLink);
+
+ return ret;
+
+error_free:
+ g_free(sectionNameDup);
+ g_free(idDup);
+ g_free(driverDup);
+ g_free(deviceLink);
+ return -ENOMEM;
+}
+
+void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section)
+{
+ if (!allSections || !section)
+ return;
+
+ g_tree_remove(allSections, section);
+ g_tree_remove(allSectionsAsList, section);
+}
+
+void __osinfoFreeDeviceLink(gpointer ptr)
+{
+ if (!ptr)
+ return;
+ struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) ptr;
+ g_free(devLink->driver);
+ g_free(devLink);
+}
+
+void __osinfoFreeDeviceSection(gpointer tree)
+{
+ if (!tree)
+ return;
+ g_tree_destroy((GTree *)tree);
+}
+
+gint __osinfoStringCompare(gconstpointer a,
+ gconstpointer b,
+ gpointer data)
+{
+ // a and b are each gchar *, data is ignored
+ gchar *str1 = (gchar *) a;
+ gchar *str2 = (gchar *) b;
+ return g_strcmp0(str1, str2);
+}
+
+gint __osinfoStringCompareBase(gconstpointer a,
+ gconstpointer b)
+{
+ // a and b are each gchar *, data is ignored
+ gchar *str1 = (gchar *) a;
+ gchar *str2 = (gchar *) b;
+ return g_strcmp0(str1, str2);
+}
+
+gint __osinfoIntCompareBase(gconstpointer a,
+ gconstpointer b)
+{
+ // a and b are each gchar *, data is ignored
+ unsigned long int1 = (unsigned long) a;
+ unsigned long int2 = (unsigned long) b;
+ return a - b;
+}
+
+gint __osinfoIntCompare(gconstpointer a,
+ gconstpointer b,
+ gpointer data)
+{
+ // a and b are each gchar *, data is ignored
+ unsigned long int1 = (unsigned long) a;
+ unsigned long int2 = (unsigned long) b;
+ return a - b;
+}
+
+void __osinfoFreePtrArray(gpointer ptrarray)
+{
+ g_ptr_array_free(ptrarray, TRUE);
+}
+
+void __osinfoFreeRelationship(gpointer ptrarray)
+{
+ if (!ptrarray)
+ return;
+ __osinfoFreePtrArray(ptrarray);
+}
+
+void __osinfoFreeParamVals(gpointer ptrarray)
+{
+ if (!ptrarray)
+ return;
+ __osinfoFreePtrArray(ptrarray);
+}
+
+void __osinfoFreeOsLink(gpointer ptr)
+{
+ if (!ptr)
+ return;
+ struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) ptr;
+ g_free(osLink);
+}
+
+void __osinfoFreeHvSection(gpointer ptr)
+{
+ if (!ptr)
+ return;
+ struct __osinfoHvSection * hvSection = (struct __osinfoHvSection *) ptr;
+ g_tree_destroy(hvSection->sections);
+ g_tree_destroy(hvSection->sectionsAsList);
+ g_free(hvSection);
+}
+
+gboolean __osinfoFilterCheckProperty(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoFilterPassArgs *args;
+ args = (struct __osinfoFilterPassArgs *) data;
+ OsinfoEntity *entity = args->entity;
+
+ // Key is property to filter on
+ // Value is array of values for property
+
+ GPtrArray *filterValues = (GPtrArray *) value;
+ GPtrArray *entityValues = NULL;
+
+ entityValues = g_tree_lookup(entity->priv->params, key);
+ if (!entityValues && filterValues->len > 0) {
+ args->passed = 0;
+ return TRUE; // not passed
+ }
+
+ int i;
+ for (i = 0; i < filterValues->len; i++) {
+ gchar *currValue = g_ptr_array_index(filterValues, i);
+ int j, found = 0;
+ for (j = 0; j < entityValues->len; j++) {
+ gchar *testValue = g_ptr_array_index(entityValues, j);
+ if (g_strcmp0(currValue, testValue) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+ else {
+ args->passed = 0;
+ return TRUE; // not passed
+ }
+ }
+
+ args->passed = 1;
+ return FALSE; // continue iterating
+}
+
+int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *entity)
+{
+ if (!OSINFO_IS_ENTITY(entity))
+ return 0;
+
+ if (!filter)
+ return 1;
+
+ if (!OSINFO_IS_FILTER(filter))
+ return 0;
+
+ struct __osinfoFilterPassArgs args = {0, entity};
+ g_tree_foreach(filter->priv->propertyConstraints, __osinfoFilterCheckProperty, &args);
+ if (args.passed)
+ return 1;
+ else
+ return 0;
+}
+
+int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device)
+{
+ // Check is device
+ return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (device));
+}
+
+gboolean __osinfoFilterCheckRelationships(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoFilterPassArgs *args;
+ args = (struct __osinfoFilterPassArgs *) data;
+ OsinfoOs *os = (OsinfoOs *) args->entity;
+
+ // Key is relationship to filter on
+ // Value is array of oses for relationship
+
+ GPtrArray *filterOses = (GPtrArray *) value;
+ GPtrArray *oses = NULL;
+
+ oses = g_tree_lookup(os->priv->relationshipsByType, key);
+ if (!oses && filterOses->len > 0) {
+ args->passed = 0;
+ return TRUE; // not passed
+ }
+
+ int i;
+ for (i = 0; i < filterOses->len; i++) {
+ OsinfoOs *currOs = g_ptr_array_index(filterOses, i);
+ int j, found = 0;
+ for (j = 0; j < oses->len; j++) {
+ OsinfoOs *testOs = g_ptr_array_index(oses, j);
+ if (testOs == currOs) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+ else {
+ args->passed = 0;
+ return TRUE; // not passed
+ }
+ }
+
+ args->passed = 1;
+ return FALSE; // continue iterating
+}
+
+int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *os)
+{
+ if (!OSINFO_IS_OS(os))
+ return 0;
+
+ if (!filter)
+ return 1;
+
+ if (!OSINFO_IS_FILTER(filter))
+ return 0;
+
+ int pass = __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (os));
+ if (!pass)
+ return 0;
+
+ struct __osinfoFilterPassArgs args = {0, (OsinfoEntity *) os};
+ g_tree_foreach(filter->priv->relationshipConstraints, __osinfoFilterCheckRelationships, &args);
+ if (args.passed)
+ return 1;
+ else
+ return 0;
+}
+
+int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *hypervisor)
+{
+ return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (hypervisor));
+}
+
+int __osinfoCheckGErrorParamValid(GError **err)
+{
+ // If err is not null and *err is not null, then invalid
+ if (err && *err)
+ return 0;
+ else return 1;
+}
+
+int __osinfoCheckRelationshipValid(osinfoRelationship relshp)
+{
+ return (relshp > RELATIONSHIP_MIN && relshp < RELATIONSHIP_MAX);
+}
+
+gchar *__osinfoErrorToString(int err)
+{
+ switch (err) {
+ case -ENOMEM:
+ return OSINFO_NO_MEM;
+ default:
+ return OSINFO_OTHER;
+ }
+}
diff --git a/osinfo/osinfo_common.h b/osinfo/osinfo_common.h
new file mode 100644
index 0000000..8f80c91
--- /dev/null
+++ b/osinfo/osinfo_common.h
@@ -0,0 +1,258 @@
+/*
+ * libosinfo
+ *
+ * osinfo_objects.h
+ * Contains forward declarations of our main object types, and definitions
+ * of our internal data structures not exposed in the API as libosinfo objects.
+ */
+
+#ifndef __OSINFO_OBJECTS_H__
+#define __OSINFO_OBJECTS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include <errno.h>
+#include "osinfo_entity.h"
+
+#define FREE_N(x) free(x); x = null;
+
+typedef struct _OsinfoDb OsinfoDb;
+typedef struct _OsinfoDevice OsinfoDevice;
+typedef struct _OsinfoHypervisor OsinfoHypervisor;
+typedef struct _OsinfoOs OsinfoOs;
+typedef struct _OsinfoFilter OsinfoFilter;
+typedef struct _OsinfoList OsinfoList;
+
+typedef enum OSI_RELATIONSHIP {
+ RELATIONSHIP_MIN = 0,
+ DERIVES_FROM,
+ UPGRADES,
+ CLONES,
+ RELATIONSHIP_MAX
+} osinfoRelationship;
+
+
+/** ****************************************************************************
+ * Internal data structures
+ ******************************************************************************/
+
+struct __osinfoDeviceLink {
+ OsinfoDevice *dev;
+ gchar *driver;
+};
+
+struct __osinfoHvSection {
+ OsinfoHypervisor *hv;
+ OsinfoOs *os;
+
+ GTree *sections; // Mapping GString key (device type) to GTree of deviceLink structs
+ GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+};
+
+struct __osinfoOsLink {
+ /* <subject_os> 'verbs' <direct_object_os>
+ * fedora11 upgrades fedora10
+ * centos clones rhel
+ * scientificlinux derives from rhel
+ */
+ OsinfoOs *subjectOs;
+ osinfoRelationship verb;
+ OsinfoOs *directObjectOs;
+};
+
+struct __osinfoPtrArrayErr {
+ GPtrArray *array;
+ int err;
+};
+
+struct __osinfoPopulateListArgs {
+ GError **err;
+ int errcode;
+ OsinfoFilter *filter;
+ OsinfoList *list;
+};
+
+struct __osinfoPopulateValuesArgs {
+ GError **err;
+ int errcode;
+ GTree *values;
+ gchar *property;
+};
+
+struct __osinfoOsCheckRelationshipArgs {
+ OsinfoList *list;
+ int errcode;
+ GError **err;
+ osinfoRelationship relshp;
+};
+
+struct __osinfoFilterPassArgs {
+ int passed;
+ OsinfoEntity *entity;
+};
+
+/** ****************************************************************************
+ * Convenience methods
+ ******************************************************************************/
+
+gint __osinfoIntCompareBase(gconstpointer a,
+ gconstpointer b);
+gint __osinfoIntCompare(gconstpointer a,
+ gconstpointer b,
+ gpointer data);
+gint __osinfoStringCompareBase(gconstpointer a,
+ gconstpointer b);
+gint __osinfoStringCompare(gconstpointer a,
+ gconstpointer b,
+ gpointer data);
+
+void __osinfoFreePtrArray(gpointer ptrarray);
+void __osinfoFreeRelationship(gpointer ptrarray);
+void __osinfoFreeParamVals(gpointer ptrarray);
+void __osinfoFreeDeviceSection(gpointer tree);
+void __osinfoFreeHvSection(gpointer hvSection);
+void __osinfoFreeDeviceLink(gpointer ptr);
+void __osinfoFreeOsLink(gpointer ptr);
+
+void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity);
+
+int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver);
+void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section);
+
+gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data);
+void __osinfoDupArray(gpointer data, gpointer user_data);
+
+int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *device);
+int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device);
+int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *device);
+int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *device);
+
+int __osinfoCheckGErrorParamValid(GError **err);
+int __osinfoCheckRelationshipValid(osinfoRelationship relshp);
+
+/** ****************************************************************************
+ * Private structures for objects
+ ******************************************************************************/
+
+struct _OsinfoFilterPrivate
+{
+ // Key: Constraint name
+ // Value: Array of constraint values
+ GTree *propertyConstraints;
+
+ // Key: relationship type
+ // Value: Array of OsinfoOs *
+ // Note: Only used when filtering OsinfoOs objects
+ GTree *relationshipConstraints;
+};
+
+struct _OsinfoDbPrivate
+{
+ int ready;
+
+ gchar *backing_dir;
+ gchar *libvirt_ver;
+
+ GTree *devices;
+ GTree *hypervisors;
+ GTree *oses;
+
+ GError *error;
+};
+
+struct _OsinfoDevicePrivate
+{
+ int tmp;
+};
+
+struct _OsinfoHypervisorPrivate
+{
+ // Key: gchar* (device type)
+ // Value: Tree of device_link structs (multiple devices per type)
+ GTree *sections;
+ GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+};
+
+struct _OsinfoOsPrivate
+{
+ // OS-Hypervisor specific information
+ // Key: gchar* (hypervisor id)
+ // Value: hv_section struct
+ GTree *hypervisors;
+
+ // Key: gchar* (device type)
+ // Value: Tree of device_link structs (multiple devices per type)
+ GTree *sections;
+ GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+
+ // OS-OS relationships
+ // Key: gchar* (other os id)
+ // Value: Array of os_link structs
+ GTree *relationshipsByOs;
+ // Key: relationship type
+ // Value: Array of os_link structs
+ GTree *relationshipsByType;
+};
+
+struct _OsinfoEntityPrivate
+{
+ gchar *id;
+
+ // Key: gchar*
+ // Value: Array of gchar* values for key (multiple values allowed)
+ GTree *params;
+
+ OsinfoDb *db; // Backpointer to db object
+};
+
+/** ****************************************************************************
+ * Error strings
+ ******************************************************************************/
+
+gchar *__osinfoErrorToString(int err);
+
+#define OSINFO_OTHER "An unspecified error occured"
+#define OSINFO_OBJ_NOT_DB "Object is wrong type (expected OsInfoDb)"
+#define OSINFO_OBJ_NOT_ENTITY "Object is wrong type (expected OsInfoEntity)"
+#define OSINFO_OBJ_NOT_DEVICE "Object is wrong type (expected OsInfoDevice)"
+#define OSINFO_OBJ_NOT_OS "Object is wrong type (expected OsInfoOs)"
+#define OSINFO_OBJ_NOT_HV "Object is wrong type (expected OsInfoHypervisor)"
+#define OSINFO_OBJ_NOT_LIST "Object is wrong type (expected OsInfoList)"
+#define OSINFO_OBJ_NOT_HYPERVISORLIST "Object is wrong type (expected OsInfoHypervisorList)"
+#define OSINFO_OBJ_NOT_DEVICELIST "Object is wrong type (expected OsInfoDeviceList)"
+#define OSINFO_OBJ_NOT_OSLIST "Object is wrong type (expected OsInfoOsList)"
+#define OSINFO_OBJ_NOT_FILTER "Object is wrong type (expected OsInfoFilter)"
+#define OSINFO_NO_ID "No object id specified"
+#define OSINFO_NO_DEVTYPE "No device type specified"
+#define OSINFO_NO_MEM "Not enough memory to complete operation"
+#define OSINFO_NO_PROPNAME "No property specified"
+#define OSINFO_NO_PROPVAL "No value specified for property"
+#define OSINFO_INVALID_RELATIONSHIP "Invalid relationship specified"
+#endif /* __OSINFO_OBJECTS_H__ */
+
+/** ****************************************************************************
+ * Private Methods
+ ******************************************************************************/
+
+void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev);
+void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv);
+void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os);
+
+// Private
+int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver);
+void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section);
+
+int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
+void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
+
+struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId);
+void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId);
+
+// Private
+int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver);
+void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section);
+
+// Private
+int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value);
+void __osinfoClearParam(OsinfoEntity *self, gchar *key);
diff --git a/osinfo/osinfo_dataread.c b/osinfo/osinfo_dataread.c
new file mode 100644
index 0000000..b77119f
--- /dev/null
+++ b/osinfo/osinfo_dataread.c
@@ -0,0 +1,915 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <libxml/xmlreader.h>
+
+#include <osinfo/osinfo.h>
+
+#ifdef LIBXML_READER_ENABLED
+
+#define TEXT_NODE 3
+#define ELEMENT_NODE 1
+#define END_NODE 15
+#define WHITESPACE_NODE 14
+#define COMMENT_NODE 8
+
+/*
+ * TODO:
+ * 1. More robust handling of files that are in bad format
+ * 2. Error messages for parsing
+ */
+
+/*
+ * Notes regarding parsing XML Data:
+ *
+ * The top level tag is <libosinfo>. The next highest level consists of
+ * <device>, <hypervisor> and <os>. Each tag may be empty (of the form <tag />)
+ * or containing data (of the form <tag>...</tag>). After parsing an object, the
+ * cursor will be located at the closing tag for the object (which, for an empty
+ * object, is the same as the starting tag for the object).
+ */
+
+struct __osinfoDbRet {
+ OsinfoDb *db;
+ int *ret;
+};
+
+static gboolean __osinfoResolveDeviceLink(gpointer key, gpointer value, gpointer data)
+{
+ gchar *id = (gchar *) key;
+ struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) value;
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+
+ OsinfoDevice *dev = g_tree_lookup(db->priv->devices, id);
+ if (!dev) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ devLink->dev = dev;
+ *ret = 0;
+ return FALSE;
+}
+
+static gboolean __osinfoResolveSectionDevices(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+ GTree *section = (GTree *) value;
+ if (!section) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ g_tree_foreach(section, __osinfoResolveDeviceLink, dbRet);
+ if (*ret)
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean __osinfoResolveHvLink(gpointer key, gpointer value, gpointer data)
+{
+ gchar *hvId = (gchar *) key;
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+ struct __osinfoHvSection *hvSection = (struct __osinfoHvSection *) value;
+ OsinfoHypervisor *hv;
+
+ g_tree_foreach(hvSection->sections, __osinfoResolveSectionDevices, dbRet);
+ if (*ret)
+ return TRUE;
+
+ hv = g_tree_lookup(db->priv->hypervisors, hvId);
+ if (!hv) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ hvSection->hv = hv;
+ *ret = 0;
+ return FALSE;
+}
+
+static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
+{
+ gchar *targetOsId = (gchar *) key;
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+ struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) value;
+
+ OsinfoOs *targetOs;
+ targetOs = g_tree_lookup(db->priv->oses, targetOsId);
+ if (!targetOs) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ osLink->directObjectOs = targetOs;
+ *ret = 0;
+ return FALSE;
+}
+
+static gboolean __osinfoFixOsLinks(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+ OsinfoOs *os = OSINFO_OS(value);
+ if (!os) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ g_tree_foreach(os->priv->sections, __osinfoResolveSectionDevices, dbRet);
+ if (*ret)
+ return TRUE;
+
+ g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
+ if (*ret)
+ return TRUE;
+
+ g_tree_foreach(os->priv->hypervisors, __osinfoResolveHvLink, dbRet);
+ if (*ret)
+ return TRUE;
+
+ *ret = 0;
+ return FALSE;
+}
+
+static gboolean __osinfoFixHvLinks(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
+ OsinfoDb *db = dbRet->db;
+ int *ret = dbRet->ret;
+ OsinfoHypervisor *hv = OSINFO_HYPERVISOR(value);
+ if (!hv) {
+ *ret = -EINVAL;
+ return TRUE;
+ }
+
+ g_tree_foreach(hv->priv->sections, __osinfoResolveSectionDevices, dbRet);
+ if (*ret)
+ return TRUE;
+ return FALSE;
+}
+
+static int __osinfoFixObjLinks(OsinfoDb *db)
+{
+ OsinfoHypervisor *hv;
+ OsinfoOs *os;
+ int ret;
+
+ if (!OSINFO_IS_DB(db))
+ return -EINVAL;
+
+ struct __osinfoDbRet dbRet = {db, &ret};
+
+ g_tree_foreach(db->priv->hypervisors, __osinfoFixHvLinks, &dbRet);
+ if (ret)
+ return ret;
+ g_tree_foreach(db->priv->oses, __osinfoFixOsLinks, &dbRet);
+
+ return ret;
+}
+
+static int __osinfoProcessTag(xmlTextReaderPtr reader, char** ptr_to_key, char** ptr_to_val)
+{
+ int node_type, ret, err = 0;
+ char* key = NULL;
+ char* val = NULL;
+ const xmlChar* node_name, * end_node_name, * xml_value;
+
+ node_name = xmlTextReaderConstName(reader);
+ if (!node_name)
+ goto error;
+
+ key = strdup(node_name);
+ if (!key) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ /* Advance to next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1)
+ goto error;
+
+ /* Ensure node is a text node */
+ node_type = xmlTextReaderNodeType(reader);
+ if (node_type != TEXT_NODE)
+ goto error;
+
+ /* Store the value of the text node */
+ xml_value = xmlTextReaderConstValue(reader);
+ if (!xml_value)
+ goto error;
+
+ val = strdup(xml_value);
+ if (!val) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ /* Advance to the next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1)
+ goto error;
+
+ /* Ensure the node is an end node for the tracked start node */
+ node_type = xmlTextReaderNodeType(reader);
+ end_node_name = xmlTextReaderConstName(reader);
+ if (node_type != END_NODE ||
+ !end_node_name ||
+ strcmp(end_node_name, node_name) != 0)
+ goto error;
+
+ /* Now we have key and val with no errors so we return with success */
+ *ptr_to_key = key;
+ *ptr_to_val = val;
+ return 0;
+
+error:
+ free(key);
+ free(val);
+ *ptr_to_key = NULL;
+ *ptr_to_val = NULL;
+ if (err == 0)
+ err = -EINVAL;
+ return err;
+}
+
+static int __osinfoProcessDevSection(xmlTextReaderPtr reader,
+ GTree *section, GTree *sectionAsList)
+{
+ int err, empty, node_type;
+ char * sectionType, * id, * key = NULL, * driver = NULL;
+ const char * name;
+
+ if (!section)
+ return -EINVAL;
+
+ sectionType = xmlTextReaderGetAttribute(reader, "type");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!sectionType)
+ return -EINVAL;
+
+ /* If no devices in section then we are done */
+ if (empty)
+ return 0;
+
+ /* Otherwise, read in devices and add to section */
+ for (;;) {
+ /* Advance to next node */
+ err = xmlTextReaderRead(reader);
+ if (err != 1) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+
+ /* If end of section, break */
+ if (node_type == END_NODE && strcmp(name, "section") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ /* Element within section needs to be of type device */
+ if (strcmp(name, "device") != 0) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!id) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ if (!empty) {
+ err = __osinfoProcessTag(reader, &key, &driver);
+ if (err != 0 || !key || !driver)
+ goto error;
+ free(key);
+ key = NULL; /* In case the next malloc fails, avoid a double free */
+ }
+
+ // Alright, we have the id and driver
+ err = __osinfoAddDeviceToSection(section, sectionAsList, sectionType, id, driver);
+ free (driver);
+ driver = NULL;
+ free (id);
+ id = NULL;
+ if (err != 0)
+ goto error;
+ }
+ free(sectionType);
+
+finished:
+ return 0;
+
+error:
+ free(sectionType);
+ free(key);
+ free(driver);
+ return err;
+}
+
+static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
+ OsinfoOs *os)
+{
+ /*
+ * Get id for hypervisor else fail
+ * While true:
+ * Advance to next node
+ * If node is end of hypervisor break
+ * If node is not element type continue
+ * If node is element type and not section fail
+ * Else handle section and add to hv_link
+ * If fail delete hv_link so far
+ * On success add hv_link to os
+ */
+ int empty, node_type, err;
+ char* id;
+ const xmlChar* name;
+ struct __osinfoHvSection *hvSection;
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!id)
+ return -EINVAL;
+
+ hvSection = __osinfoAddHypervisorSectionToOs(os, id);
+ free(id);
+ if (!hvSection)
+ return -EINVAL;
+
+ if (empty)
+ goto finished;
+
+ for (;;) {
+ /* Advance to next node */
+ err = xmlTextReaderRead(reader);
+ if (err != 1) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+ if (node_type == -1 || !name) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ /* If end of hv link, break */
+ if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ /* Ensure it is element node of type 'section' else fail */
+ if (strcmp(name, "section") != 0) {
+ err = -EINVAL;
+ goto error;
+ }
+
+ /* Process device type info for this <os, hv> combination */
+ err = __osinfoProcessDevSection(reader, hvSection->sections, hvSection->sectionsAsList);
+ if (err != 0)
+ goto error;
+ }
+
+finished:
+ return 0;
+
+error:
+ return err;
+}
+
+static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
+ OsinfoOs *os,
+ osinfoRelationship relationship)
+{
+ int empty, ret;
+ char* id;
+ struct osi_os_link * os_link;
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+ if (!empty || !id) {
+ free(id);
+ return -EINVAL;
+ }
+
+ ret = __osinfoAddOsRelationship (os, id, relationship);
+ free(id);
+ return ret;
+}
+
+static int __osinfoProcessOs(OsinfoDb *db,
+ xmlTextReaderPtr reader)
+{
+ /* Cursor is at start of (possibly empty) os node */
+ /*
+ * First, determine if hv has ID or not, and if tag is empty or not.
+ * The following cases can occur:
+ * 1. No ID: Return invalid. Parse fails overall.
+ * 2. Empty, ID: Make hv with given ID and no data and return.
+ * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
+ */
+
+ int empty, node_type, err, ret;
+ char* id, * key = NULL, * val = NULL;
+ const xmlChar* name;
+ OsinfoOs *os;
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!id)
+ return -EINVAL;
+
+ os = g_object_new(OSINFO_TYPE_OS, "id", id, "db", db, NULL);
+ free(id);
+ if (!os)
+ return -ENOMEM;
+
+ if (empty)
+ goto finished;
+
+ /* Current node is start of non empty os
+ * While true:
+ * Advance to next node
+ * If node == end of os break
+ * If node is not element, continue
+ * If node is element and not section or hypervisor:
+ * Note element name
+ * Advance to next node, ensure type is text else error
+ * Store value, advance to next node
+ * Ensure node is end of current name
+ * Store <key, val> in params list for object
+ * If node is start of section handle section and track device driver
+ * If node is hypervisor handle hypervisor link
+ */
+
+ for (;;) {
+ /* Advance to next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+ if (node_type == -1 || !name) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+ /* If end of os, break */
+ if (node_type == END_NODE && strcmp(name, "os") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ if (strcmp(name, "section") == 0) {
+ /* Node is start of device section for os */
+ err = __osinfoProcessDevSection(reader, (OSINFO_OS(os))->priv->sections, (OSINFO_OS(os))->priv->sectionsAsList);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "hypervisor") == 0) {
+ err = __osinfoProcessOsHvLink(reader, os);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "upgrades") == 0) {
+ err = __osinfoProcessOsRelationship(reader, os, UPGRADES);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "clones") == 0) {
+ err = __osinfoProcessOsRelationship(reader, os, CLONES);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "derives-from") == 0) {
+ err = __osinfoProcessOsRelationship(reader, os, DERIVES_FROM);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else {
+ /* Node is start of element of known name */
+ err = __osinfoProcessTag(reader, &key, &val);
+ if (err != 0 || !key || !val)
+ goto cleanup_error;
+
+ err = __osinfoAddParam(OSINFO_ENTITY(os), key, val);
+ if (err != 0)
+ goto cleanup_error;
+
+ free(key);
+ free(val);
+ }
+ }
+
+finished:
+ __osinfoAddOsToDb(db, os);
+ return 0;
+ /* At end, cursor is at end of os node */
+
+cleanup_error:
+ g_object_unref(os);
+ return err;
+}
+
+static int __osinfoProcessHypervisor(OsinfoDb *db,
+ xmlTextReaderPtr reader)
+{
+ /* Cursor is at start of (possibly empty) hypervisor node */
+
+ /*
+ * First, determine if hv has ID or not, and if tag is empty or not.
+ * The following cases can occur:
+ * 1. No ID: Return invalid. Parse fails overall.
+ * 2. Empty, ID: Make hv with given ID and no data and return.
+ * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
+ */
+
+ int empty, node_type, err, ret;
+ char* id;
+ const xmlChar* name;
+ OsinfoHypervisor *hv;
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!id)
+ return -EINVAL;
+
+
+ hv = g_object_new(OSINFO_TYPE_HYPERVISOR, "id", id, "db", db, NULL);
+ free(id);
+ if (!hv) {
+ return -ENOMEM;
+ }
+
+ if (empty)
+ goto finished;
+
+ /* Current node is start of non empty hv
+ * While true:
+ * Advance to next node
+ * If node == end of hv break
+ * If node is not element, continue
+ * If node is element and not section:
+ * Note element name
+ * Advance to next node, ensure type is text else error
+ * Store value, advance to next node
+ * Ensure node is end of current name
+ * Store <key, val> in params list for object
+ * If node is start of section:
+ * Note section type
+ * While true:
+ * Advance to next node
+ * If node is not element continue
+ * If end of section, break
+ * If not empty device node, parse error
+ * If id not defined, parse error
+ * Store id
+ * Store all ids for given section in the HV
+ */
+
+ for (;;) {
+ /* Advance to next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+ if (node_type == -1 || !name) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+ /* If end of hv, break */
+ if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ if (strcmp(name, "section") == 0) {
+ /* Node is start of device section for hv */
+ err = __osinfoProcessDevSection(reader, (OSINFO_HYPERVISOR(hv))->priv->sections, (OSINFO_HYPERVISOR(hv))->priv->sectionsAsList);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else {
+ /* Node is start of element of known name */
+ char *key = NULL, *val = NULL;
+ err = __osinfoProcessTag(reader, &key, &val);
+ if (err != 0)
+ goto cleanup_error;
+
+
+ err = __osinfoAddParam(OSINFO_ENTITY(hv), key, val);
+ free(key);
+ free(val);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ }
+
+finished:
+ __osinfoAddHypervisorToDb(db, hv);
+ return 0;
+ /* At end, cursor is at end of hv node */
+
+cleanup_error:
+ g_object_unref(hv);
+ return err;
+}
+
+static int __osinfoProcessDevice(OsinfoDb *db,
+ xmlTextReaderPtr reader)
+{
+ /* Cursor is at start of (possibly empty) device node */
+
+ /*
+ * First, determine if device has ID or not, and if tag is empty or not.
+ * The following cases can occur:
+ * 1. No ID: Return invalid. Parse fails overall.
+ * 2. Empty, ID: Make device with given ID and no data and return.
+ * 3. Non-Empty, ID: Make device, parse data till closing tag, return.
+ */
+
+ int empty, node_type, err, ret;
+ char* id, * key, * val;
+ const xmlChar* name;
+ OsinfoDevice *dev;
+
+ id = xmlTextReaderGetAttribute(reader, "id");
+ empty = xmlTextReaderIsEmptyElement(reader);
+
+ if (!id)
+ return -EINVAL;
+
+ dev = g_object_new(OSINFO_TYPE_DEVICE, "id", id, "db", db, NULL);
+ free(id);
+ if (!dev) {
+ // TODO: How do errors in gobject creation manifest themselves?
+ return -ENOMEM;
+ }
+
+ if (empty)
+ goto finished;
+
+ /* Current node is start of non empty device
+ * While true:
+ * Advance to next node
+ * If node == end of device break
+ * If node is not element, continue
+ * If node is element:
+ * Note element name
+ * Advance to next node, ensure type is text else error
+ * Store value, advance to next node
+ * Ensure node is end of current name
+ * Store <key, val> in params list for object
+ */
+
+ for (;;) {
+ /* Advance to next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+
+ if (node_type == -1 || !name) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ /* If end of device, break */
+ if (node_type == END_NODE && strcmp(name, "device") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ /* Node is start of element of known name */
+ err = __osinfoProcessTag(reader, &key, &val);
+ if (err != 0 || !key || !val)
+ goto cleanup_error;
+
+ err = __osinfoAddParam(OSINFO_ENTITY(dev), key, val);
+ if (err != 0)
+ goto cleanup_error;
+
+ free(key);
+ free(val);
+ }
+
+finished:
+ // Add dev to db
+ __osinfoAddDeviceToDb(db, dev);
+ return 0;
+ /* At end, cursor is at end of device node */
+
+cleanup_error:
+ free(key);
+ free(val);
+ g_object_unref(dev);
+ return err;
+}
+
+static int __osinfoProcessFile(OsinfoDb *db,
+ xmlTextReaderPtr reader)
+{
+ /*
+ * File assumed to contain data in XML format. All data
+ * is within <libosinfo>...</libosinfo>. The following steps are taken
+ * to process the data within the file:
+ *
+ * Advance till we are at opening <libosinfo> tag.
+ * While true:
+ * Advance tag
+ * If closing libosinfo tag, break
+ * If non element tag, continue
+ * If element tag, and element is not os, hypervisor or device, error
+ * Else, switch on tag type and handle reading in data
+ * After loop, return success if no error
+ * If there was an error, clean up lib data acquired so far
+ */
+
+ int err, node_type, ret;
+ const char* name;
+
+ /* Advance to starting libosinfo tag */
+ for (;;) {
+ err = xmlTextReaderRead(reader);
+ if (err != 1) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ name = xmlTextReaderConstName(reader);
+ if (strcmp(name, "libosinfo") == 0)
+ break;
+ }
+
+ /* Now read and handle each tag of interest */
+ for (;;) {
+ /* Advance to next node */
+ ret = xmlTextReaderRead(reader);
+ if (ret != 1) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ node_type = xmlTextReaderNodeType(reader);
+ name = xmlTextReaderConstName(reader);
+
+ if (node_type == -1 || !name) {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+
+ /* If end of libosinfo, break */
+ if (node_type == END_NODE && strcmp(name, "libosinfo") == 0)
+ break;
+
+ /* If node is not start of an element, continue */
+ if (node_type != ELEMENT_NODE)
+ continue;
+
+ /* Process element node */
+ if (strcmp(name, "device") == 0) {
+ err = __osinfoProcessDevice(db, reader);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "hypervisor") == 0) {
+ err = __osinfoProcessHypervisor(db, reader);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else if (strcmp(name, "os") == 0) {
+ err = __osinfoProcessOs(db, reader);
+ if (err != 0)
+ goto cleanup_error;
+ }
+ else {
+ err = -EINVAL;
+ goto cleanup_error;
+ }
+ }
+
+ /* And we are done, successfully */
+ return 0;
+
+cleanup_error:
+ // Db will be unsatisfactorily initiated, caller will call unref to clean it
+ return err;
+}
+
+static int __osinfoReadDataFile(OsinfoDb *db,
+ const char *dir,
+ const char *filename)
+{
+ int ret;
+ xmlTextReaderPtr reader;
+ char *rel_name = malloc (strlen(dir) + 1 + strlen(filename) + 1);
+ if (!rel_name)
+ return -errno;
+
+ stpcpy(stpcpy(stpcpy(rel_name, dir), "/"), filename);
+
+ reader = xmlReaderForFile(rel_name, NULL, 0);
+ free(rel_name);
+ if (!reader) {
+ return -EINVAL;
+ }
+ ret = __osinfoProcessFile(db, reader);
+ xmlFreeTextReader(reader);
+ return ret;
+}
+
+int __osinfoInitializeData(OsinfoDb *db)
+{
+ int ret;
+ DIR* dir;
+ struct dirent *dp;
+
+ char *backingDir;
+ g_object_get(G_OBJECT(db), "backing-dir", &backingDir, NULL);
+
+ /* Initialize library and check version */
+ LIBXML_TEST_VERSION
+
+ /* Get directory with backing data. Defaults to CWD */
+ if (!backingDir)
+ backingDir = ".";
+
+ /* Get XML files in directory */
+ dir = opendir(backingDir);
+ if (!dir) {
+ ret = errno;
+ goto cleanup;
+ }
+
+ while ((dp=readdir(dir)) != NULL) {
+ if (dp->d_type != DT_REG)
+ continue;
+ ret = __osinfoReadDataFile(db, backingDir, dp->d_name);
+ if (ret != 0)
+ break;
+ }
+ closedir(dir);
+ if (ret == 0)
+ ret = __osinfoFixObjLinks(db);
+
+cleanup:
+ xmlCleanupParser();
+ g_free(backingDir);
+ return ret;
+}
+
+#else
+int __osinfoInitializeData(OsinfoDb *db)
+{
+ return -ENOSYS;
+}
+#endif
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
new file mode 100644
index 0000000..e669f78
--- /dev/null
+++ b/osinfo/osinfo_db.c
@@ -0,0 +1,555 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
+
+#define OSINFO_DB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DB, OsinfoDbPrivate))
+
+static void osinfo_db_set_property(GObject * object, guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void osinfo_db_get_property(GObject * object, guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+static void osinfo_db_finalize (GObject *object);
+
+enum OSI_DB_PROPERTIES {
+ OSI_DB_PROP_0,
+
+ OSI_DB_BACKING_DIR,
+ OSI_DB_LIBVIRT_VER,
+ OSI_DB_ERROR
+};
+
+static void
+osinfo_db_finalize (GObject *object)
+{
+ OsinfoDb *self = OSINFO_DB (object);
+
+ g_free (self->priv->backing_dir);
+ g_free (self->priv->libvirt_ver);
+
+ g_tree_destroy(self->priv->devices);
+ g_tree_destroy(self->priv->hypervisors);
+ g_tree_destroy(self->priv->oses);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_db_parent_class)->finalize (object);
+}
+
+static void
+osinfo_db_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoDb *self = OSINFO_DB (object);
+
+ switch (property_id)
+ {
+ case OSI_DB_BACKING_DIR:
+ g_free(self->priv->backing_dir);
+ self->priv->backing_dir = g_value_dup_string (value);
+ break;
+
+ case OSI_DB_LIBVIRT_VER:
+ g_free(self->priv->libvirt_ver);
+ self->priv->libvirt_ver = g_value_dup_string (value);
+ break;
+
+ case OSI_DB_ERROR:
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+osinfo_db_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoDb *self = OSINFO_DB (object);
+
+ switch (property_id)
+ {
+ case OSI_DB_BACKING_DIR:
+ g_value_set_string (value, self->priv->backing_dir);
+ break;
+
+ case OSI_DB_LIBVIRT_VER:
+ g_value_set_string (value, self->priv->libvirt_ver);
+ break;
+
+ case OSI_DB_ERROR:
+ g_value_set_pointer(value, self->priv->error);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/* Init functions */
+static void
+osinfo_db_class_init (OsinfoDbClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ g_klass->set_property = osinfo_db_set_property;
+ g_klass->get_property = osinfo_db_get_property;
+ g_klass->finalize = osinfo_db_finalize;
+
+ pspec = g_param_spec_string ("backing-dir",
+ "Backing directory",
+ "Contains backing data store.",
+ NULL /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (g_klass,
+ OSI_DB_BACKING_DIR,
+ pspec);
+
+ pspec = g_param_spec_string ("libvirt-ver",
+ "Libvirt version",
+ "Libvirt version user is interested in",
+ NULL /* default value */,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (g_klass,
+ OSI_DB_LIBVIRT_VER,
+ pspec);
+
+ pspec = g_param_spec_pointer ("error",
+ "Error",
+ "GError object for db",
+ G_PARAM_READABLE);
+ g_object_class_install_property (g_klass,
+ OSI_DB_ERROR,
+ pspec);
+
+ g_type_class_add_private (klass, sizeof (OsinfoDbPrivate));
+}
+
+
+static void
+osinfo_db_init (OsinfoDb *self)
+{
+ OsinfoDbPrivate *priv;
+ int ret;
+ self->priv = priv = OSINFO_DB_GET_PRIVATE(self);
+
+ self->priv->devices = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+ self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+ self->priv->oses = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
+
+ self->priv->error = NULL;
+ self->priv->ready = 0;
+}
+
+/** PUBLIC METHODS */
+
+int osinfoInitializeDb(OsinfoDb *self, GError **err)
+{
+ int ret;
+ // And now read in data.
+ ret = __osinfoInitializeData(self);
+ if (ret != 0) {
+ self->priv->ready = 0;
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, "Error during reading data");
+ }
+ else
+ self->priv->ready = 1;
+ return ret;
+}
+
+OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *id, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!id) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+ return NULL;
+ }
+
+ return g_tree_lookup(self->priv->hypervisors, id);
+}
+
+OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *id, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!id) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+ return NULL;
+ }
+
+ return g_tree_lookup(self->priv->devices, id);
+}
+
+OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *id, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!id) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
+ return NULL;
+ }
+
+ return g_tree_lookup(self->priv->oses, id);
+}
+
+static gboolean __osinfoFilteredAddToList(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoPopulateListArgs *args;
+ args = (struct __osinfoPopulateListArgs *) data;
+ OsinfoFilter *filter = args->filter;
+ OsinfoList *list = args->list;
+ GError **err = args->err;
+
+ // Key is string ID, value is pointer to entity
+ OsinfoEntity *entity = (OsinfoEntity *) value;
+ if (__osinfoEntityPassesFilter(filter, entity)) {
+ __osinfoListAdd(list, entity);
+ }
+
+ args->errcode = 0;
+
+ return FALSE; // continue iteration
+}
+
+static int __osinfoPopulateList(GTree *entities, OsinfoList *newList, OsinfoFilter *filter, GError **err)
+{
+ struct __osinfoPopulateListArgs args = {err, 0, filter, newList};
+ g_tree_foreach(entities, __osinfoFilteredAddToList, &args);
+ return args.errcode;
+}
+
+OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // Create list
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoPopulateList(self->priv->oses, OSINFO_LIST (newList), filter, err);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // Create list
+ OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoPopulateList(self->priv->hypervisors, OSINFO_LIST (newList), filter, err);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // Create list
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoPopulateList(self->priv->devices, OSINFO_LIST (newList), filter, err);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+gboolean __osinfoGetPropertyValuesInEntity(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoPopulateValuesArgs *args;
+ args = (struct __osinfoPopulateValuesArgs *) data;
+ GTree *values = args->values;
+ GError **err = args->err;
+ gchar *property = args->property;
+
+ OsinfoEntity *entity = OSINFO_ENTITY (value);
+ GPtrArray *valueArray = NULL;
+
+ valueArray = g_tree_lookup(entity->priv->params, property);
+ if (valueArray)
+ return FALSE; // No values here, skip
+
+ int i;
+ for (i = 0; i < valueArray->len; i++) {
+ gchar *currValue = g_ptr_array_index(valueArray, i);
+ void *test = g_tree_lookup(values, currValue);
+ if (test)
+ continue;
+ gchar *dupValue = g_strdup(currValue);
+ if (!dupValue) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ args->errcode = -ENOMEM;
+ return TRUE;
+ }
+
+ // Add to tree with dummy value
+ g_tree_insert(values, dupValue, (gpointer) 1);
+ }
+
+ return FALSE; // Continue iterating
+}
+
+static gboolean __osinfoPutKeysInList(gpointer key, gpointer value, gpointer data)
+{
+ gchar *currValue = (gchar *) key;
+ GPtrArray *valuesList = (GPtrArray *) data;
+
+ g_ptr_array_add(valuesList, currValue);
+ return FALSE; // keep iterating
+}
+
+static gboolean __osinfoFreeKeys(gpointer key, gpointer value, gpointer data)
+{
+ g_free(key);
+ return FALSE; // keep iterating
+}
+
+static GPtrArray *__osinfoUniqueValuesForPropertyInEntity(GTree *entities, gchar *propName, GError **err)
+{
+ GTree *values = g_tree_new(__osinfoStringCompareBase);
+ if (!values) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ struct __osinfoPopulateValuesArgs args = {err, 0, values, propName};
+ g_tree_foreach(entities, __osinfoGetPropertyValuesInEntity, &args);
+
+ if (args.errcode != 0) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
+ g_tree_foreach(values, __osinfoFreeKeys, NULL);
+ g_tree_destroy(values);
+ return NULL;
+ }
+
+ // For each key in tree, add to gptrarray
+ GPtrArray *valuesList = g_ptr_array_sized_new(g_tree_nnodes(values));
+ if (!valuesList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ g_tree_foreach(values, __osinfoFreeKeys, NULL);
+ g_tree_destroy(values);
+ return NULL;
+ }
+
+ g_tree_foreach(values, __osinfoPutKeysInList, valuesList);
+ g_tree_destroy(values);
+ return valuesList;
+}
+
+// Get me all unique values for property "vendor" among operating systems
+GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!propName) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ return __osinfoUniqueValuesForPropertyInEntity(self->priv->oses, propName, err);
+}
+
+// Get me all unique values for property "vendor" among hypervisors
+GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!propName) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ return __osinfoUniqueValuesForPropertyInEntity(self->priv->hypervisors, propName, err);
+}
+
+// Get me all unique values for property "vendor" among devices
+GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!propName) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ return __osinfoUniqueValuesForPropertyInEntity(self->priv->devices, propName, err);
+}
+
+static gboolean __osinfoAddOsIfRelationship(gpointer key, gpointer value, gpointer data)
+{
+ OsinfoOs *os = (OsinfoOs *) value;
+ struct __osinfoOsCheckRelationshipArgs *args;
+ args = (struct __osinfoOsCheckRelationshipArgs *) data;
+ GError **err = args->err;
+ OsinfoList *list = args->list;
+
+ GPtrArray *relatedOses = NULL;
+ relatedOses = g_tree_lookup(os->priv->relationshipsByType, (gpointer) args->relshp);
+ if (relatedOses) {
+ __osinfoListAdd(list, OSINFO_ENTITY (os));
+ }
+
+ return FALSE;
+}
+
+// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
+OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DB(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
+ return NULL;
+ }
+
+ if (!__osinfoCheckRelationshipValid(relshp)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+ return NULL;
+ }
+
+ // Create list
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ struct __osinfoOsCheckRelationshipArgs args = {OSINFO_LIST (newList), 0, err, relshp};
+
+ g_tree_foreach(self->priv->oses, __osinfoAddOsIfRelationship, &args);
+ if (args.errcode != 0) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
+ g_object_unref(newList);
+ return NULL;
+ }
+
+ return newList;
+}
+
+/** PRIVATE */
+
+void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev)
+{
+ gchar *id;
+ g_object_get(G_OBJECT(dev), "id", &id, NULL);
+ g_tree_insert(db->priv->devices, id, dev);
+}
+
+void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv)
+{
+ gchar *id;
+ g_object_get(G_OBJECT(hv), "id", &id, NULL);
+ g_tree_insert(db->priv->hypervisors, id, hv);
+}
+
+void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os)
+{
+ gchar *id;
+ g_object_get(G_OBJECT(os), "id", &id, NULL);
+ g_tree_insert(db->priv->oses, id, os);
+}
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
new file mode 100644
index 0000000..305ed29
--- /dev/null
+++ b/osinfo/osinfo_db.h
@@ -0,0 +1,87 @@
+/*
+ * libosinfo
+ *
+ * osinfo_db.h
+ * Represents the main entry point to data contained by libosinfo.
+ */
+
+#ifndef __OSINFO_DB_H__
+#define __OSINFO_DB_H__
+
+#include "osinfo_devicelist.h"
+#include "osinfo_hypervisorlist.h"
+#include "osinfo_oslist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DB (osinfo_db_get_type ())
+#define OSINFO_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DB, OsinfoDb))
+#define OSINFO_IS_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DB))
+#define OSINFO_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DB, OsinfoDbClass))
+#define OSINFO_IS_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DB))
+#define OSINFO_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DB, OsinfoDbClass))
+
+//typedef struct _OsinfoDb OsinfoDb;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoDbClass OsinfoDbClass;
+
+typedef struct _OsinfoDbPrivate OsinfoDbPrivate;
+
+/*
+ * To get a db handle, we construct one with a construct-time only
+ * backing data directory. It is already considered to be initialized
+ * on return from the constructor, and ready to do work.
+ *
+ * To close it, we call the destructor on it.
+ * Setting parameters on it will work if it's not a construct-time only
+ * parameter. Reading will always work. Currently the backing directory and
+ * libvirt version are the only parameters.
+ *
+ * The db object contains information related to three main classes of
+ * objects: hypervisors, operating systems and devices.
+ */
+
+/* object */
+struct _OsinfoDb
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoDbPrivate *priv;
+};
+
+/* class */
+struct _OsinfoDbClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+int osinfoInitializeDb(OsinfoDb *self, GError **err);
+
+OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *hvId, GError **err);
+OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *devId, GError **err);
+OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *osId, GError **err);
+
+OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err);
+
+// Get me all unique values for property "vendor" among operating systems
+GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all unique values for property "vendor" among hypervisors
+GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all unique values for property "vendor" among devices
+GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err);
+
+// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
+OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err);
+
+#endif /* __OSINFO_DB_H__ */
diff --git a/osinfo/osinfo_device.c b/osinfo/osinfo_device.c
new file mode 100644
index 0000000..d43c405
--- /dev/null
+++ b/osinfo/osinfo_device.c
@@ -0,0 +1,94 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDevice, osinfo_device, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICE, OsinfoDevicePrivate))
+
+static void osinfo_device_finalize (GObject *object);
+
+static void
+osinfo_device_finalize (GObject *object)
+{
+ OsinfoDevice *self = OSINFO_DEVICE (object);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_device_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_device_class_init (OsinfoDeviceClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_device_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoDevicePrivate));
+}
+
+static void
+osinfo_device_init (OsinfoDevice *self)
+{
+ OsinfoDevicePrivate *priv;
+ self->priv = priv = OSINFO_DEVICE_GET_PRIVATE(self);
+}
+
+gchar *osinfoGetDeviceDriver(OsinfoDevice *self,
+ gchar *devType,
+ OsinfoOs *os,
+ OsinfoHypervisor *hv,
+ GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_DEVICE(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICE);
+ return NULL;
+ }
+
+ if (!OSINFO_IS_OS(os)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+ return NULL;
+ }
+
+ if (!OSINFO_IS_HYPERVISOR(hv)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+ return NULL;
+ }
+
+ if (!devType) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+ return NULL;
+ }
+
+ gchar *driver = NULL;
+
+ // For os, get hypervisor specific info. If not present, return NULL.
+ struct __osinfoHvSection *hvSection = NULL;
+ hvSection = g_tree_lookup(os->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+ if (!hvSection)
+ return NULL;
+
+ // Check for info for type of devices in <os,hv>. If not found, return NULL.
+ GTree *section = NULL;
+ section = g_tree_lookup(hvSection->sections, devType);
+ if (!section)
+ return NULL;
+
+ // Check device section for device. If not found, return NULL.
+ struct __osinfoDeviceLink *deviceLink = NULL;
+ deviceLink = g_tree_lookup(section, (OSINFO_ENTITY(self))->priv->id);
+ if (!deviceLink)
+ return NULL;
+
+ if (!deviceLink->driver)
+ return NULL;
+
+ driver = g_strdup(deviceLink->driver);
+ if (!driver) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ return driver;
+}
diff --git a/osinfo/osinfo_device.h b/osinfo/osinfo_device.h
new file mode 100644
index 0000000..9f10e6b
--- /dev/null
+++ b/osinfo/osinfo_device.h
@@ -0,0 +1,49 @@
+/*
+ * libosinfo
+ *
+ * osinfo_device.h
+ * Represents a device in libosinfo.
+ */
+
+#ifndef __OSINFO_DEVICE_H__
+#define __OSINFO_DEVICE_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DEVICE (osinfo_device_get_type ())
+#define OSINFO_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICE, OsinfoDevice))
+#define OSINFO_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICE))
+#define OSINFO_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
+#define OSINFO_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICE))
+#define OSINFO_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICE, OsinfoDeviceClass))
+
+//typedef struct _OsinfoDevice OsinfoDevice;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoDeviceClass OsinfoDeviceClass;
+
+typedef struct _OsinfoDevicePrivate OsinfoDevicePrivate;
+
+/* object */
+struct _OsinfoDevice
+{
+ OsinfoEntity parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoDevicePrivate *priv;
+};
+
+/* class */
+struct _OsinfoDeviceClass
+{
+ OsinfoEntityClass parent_class;
+
+ /* class members */
+};
+
+gchar *osinfoGetDeviceDriver(OsinfoDevice *self, gchar *devType, OsinfoOs *os, OsinfoHypervisor *hv, GError **err);
+
+#endif /* __OSINFO_DEVICE_H__ */
diff --git a/osinfo/osinfo_devicelist.c b/osinfo/osinfo_devicelist.c
new file mode 100644
index 0000000..af6f6c0
--- /dev/null
+++ b/osinfo/osinfo_devicelist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoDeviceList, osinfo_devicelist, OSINFO_TYPE_LIST);
+
+#define OSINFO_DEVICELIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListPrivate))
+
+static void osinfo_devicelist_finalize (GObject *object);
+
+struct _OsinfoDeviceListPrivate
+{
+ int tmp;
+};
+
+static void
+osinfo_devicelist_finalize (GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_devicelist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_devicelist_class_init (OsinfoDeviceListClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_devicelist_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoDeviceListPrivate));
+}
+
+static void
+osinfo_devicelist_init (OsinfoDeviceList *self)
+{
+ OsinfoDeviceListPrivate *priv;
+ self->priv = priv = OSINFO_DEVICELIST_GET_PRIVATE(self);
+
+}
+
+OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err)
+{
+ if (!OSINFO_IS_DEVICELIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+ return NULL;
+ }
+
+ OsinfoList *selfAsList = OSINFO_LIST (self);
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+ return OSINFO_DEVICE (entity);
+}
+
+OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_DEVICELIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // For each element in self, if passes filter, add to new list.
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+ return newList;
+}
+
+OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
+{
+ if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+ return NULL;
+ }
+
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+
+ ret = __osinfoDoIntersect(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
+{
+ if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
+ return NULL;
+ }
+
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoDoUnion(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_devicelist.h b/osinfo/osinfo_devicelist.h
new file mode 100644
index 0000000..49e2715
--- /dev/null
+++ b/osinfo/osinfo_devicelist.h
@@ -0,0 +1,50 @@
+/*
+ * libosinfo
+ *
+ * osinfo_devicelist.h
+ */
+
+#ifndef __OSINFO_DEVICELIST_H__
+#define __OSINFO_DEVICELIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_DEVICELIST (osinfo_devicelist_get_type ())
+#define OSINFO_DEVICELIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceList))
+#define OSINFO_IS_DEVICELIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_DEVICELIST))
+#define OSINFO_DEVICELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
+#define OSINFO_IS_DEVICELIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_DEVICELIST))
+#define OSINFO_DEVICELIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListClass))
+
+typedef struct _OsinfoDeviceList OsinfoDeviceList;
+
+typedef struct _OsinfoDeviceListClass OsinfoDeviceListClass;
+
+typedef struct _OsinfoDeviceListPrivate OsinfoDeviceListPrivate;
+
+/* object */
+struct _OsinfoDeviceList
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoDeviceListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoDeviceListClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err);
+OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err);
+OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
+OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherDeviceList, GError **err);
+
+#endif /* __OSINFO_DEVICELIST_H__ */
diff --git a/osinfo/osinfo_entity.c b/osinfo/osinfo_entity.c
new file mode 100644
index 0000000..cbf33e0
--- /dev/null
+++ b/osinfo/osinfo_entity.c
@@ -0,0 +1,321 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_ABSTRACT_TYPE (OsinfoEntity, osinfo_entity, G_TYPE_OBJECT);
+
+#define OSINFO_ENTITY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityPrivate))
+
+static void osinfo_entity_finalize (GObject *object);
+
+enum OSI_ENTITY_PROPERTIES {
+ OSI_ENTITY_PROP_0,
+
+ OSI_ENTITY_ID,
+ OSI_DB_PTR
+};
+
+static void
+osinfo_entity_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoEntity *self = OSINFO_ENTITY (object);
+
+ switch (property_id)
+ {
+ case OSI_ENTITY_ID:
+ g_free(self->priv->id);
+ self->priv->id = g_value_dup_string (value);
+ break;
+ case OSI_DB_PTR:
+ self->priv->db = g_value_get_pointer (value);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+osinfo_entity_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OsinfoEntity *self = OSINFO_ENTITY (object);
+
+ switch (property_id)
+ {
+ case OSI_ENTITY_ID:
+ g_value_set_string (value, self->priv->id);
+ break;
+ case OSI_DB_PTR:
+ g_value_set_pointer(value, self->priv->db);
+ break;
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+osinfo_entity_finalize (GObject *object)
+{
+ OsinfoEntity *self = OSINFO_ENTITY (object);
+
+ g_free (self->priv->id);
+ g_tree_destroy (self->priv->params);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_entity_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_entity_class_init (OsinfoEntityClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ g_klass->set_property = osinfo_entity_set_property;
+ g_klass->get_property = osinfo_entity_get_property;
+
+ pspec = g_param_spec_string ("id",
+ "ID",
+ "Contains unique identifier for entity.",
+ NULL /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (g_klass,
+ OSI_ENTITY_ID,
+ pspec);
+ pspec = g_param_spec_pointer ("db",
+ "Db pointer",
+ "Contains backpointer to libosinfo db object.",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (g_klass,
+ OSI_DB_PTR,
+ pspec);
+
+ g_klass->finalize = osinfo_entity_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoEntityPrivate));
+}
+
+static void
+osinfo_entity_init (OsinfoEntity *self)
+{
+ OsinfoEntityPrivate *priv;
+ self->priv = priv = OSINFO_ENTITY_GET_PRIVATE(self);
+
+ self->priv->params = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeParamVals);
+}
+
+int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value)
+{
+ if (!OSINFO_IS_ENTITY(self) || !key || !value)
+ return -EINVAL;
+
+ // First check if there exists an existing array of entries for this key
+ // If not, create a ptrarray of strings for this key and insert into map
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *valueArray;
+ gchar *valueDup = NULL, *keyDup = NULL;
+
+ valueDup = g_strdup(value);
+
+ if (!valueDup)
+ goto error_free;
+
+ found = g_tree_lookup_extended(self->priv->params, key, &origKey, &foundValue);
+ if (!found) {
+ keyDup = g_strdup(key);
+ valueArray = g_ptr_array_new_with_free_func(g_free);
+
+ if (!valueArray)
+ goto error_free;
+ if (!keyDup) {
+ g_ptr_array_free(valueArray, TRUE);
+ goto error_free;
+ }
+
+ g_tree_insert(self->priv->params, keyDup, valueArray);
+ }
+ else
+ valueArray = (GPtrArray *) foundValue;
+
+ // Add a copy of the value to the array
+ g_ptr_array_add(valueArray, valueDup);
+ return 0;
+
+error_free:
+ g_free(keyDup);
+ g_free(valueDup);
+ return -ENOMEM;
+}
+
+void __osinfoClearParam(OsinfoEntity *self, gchar *key)
+{
+ g_tree_remove(self->priv->params, key);
+}
+
+gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data)
+{
+ struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
+ GPtrArray *results = arrayErr->array;
+ gchar *keyDup = g_strdup(key);
+
+ if (!keyDup) {
+ arrayErr->err = -ENOMEM;
+ return TRUE;
+ }
+ g_ptr_array_add(results, keyDup);
+ return FALSE; // Continue iterating
+}
+
+void __osinfoDupArray(gpointer data, gpointer user_data)
+{
+ struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
+ GPtrArray *results = arrayErr->array;
+
+ if (arrayErr->err != 0)
+ return;
+
+ gchar *valueDup = g_strdup((gchar *)data);
+ if (!valueDup) {
+ arrayErr->err = -ENOMEM;
+ return;
+ }
+ g_ptr_array_add(results, valueDup);
+}
+
+gchar *osinfoGetId(OsinfoEntity *self, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_ENTITY(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+ return NULL;
+ }
+
+ gchar *dupId = g_strdup(self->priv->id);
+ if (!dupId) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+ return dupId;
+}
+
+GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_ENTITY(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+ return NULL;
+ }
+
+ GPtrArray *params = g_ptr_array_new();
+ if (!params) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ struct __osinfoPtrArrayErr arrayErr = {params, 0};
+ g_tree_foreach(self->priv->params, __osinfoGetKeys, &arrayErr);
+
+ // If we had an error, cleanup and return NULL
+ if (arrayErr.err != 0) {
+ int i;
+ for (i = 0; i < params->len; i++)
+ g_free(g_ptr_array_index(params, i));
+ g_ptr_array_free(params, TRUE);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+ return NULL;
+ }
+
+ return params;
+}
+
+gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_ENTITY(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+ return NULL;
+ }
+
+ if (!key) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ gboolean found;
+ gpointer origKey, value;
+ gchar *firstValueDup;
+ GPtrArray *array;
+
+ found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
+ if (!found)
+ return NULL;
+ array = (GPtrArray *) value;
+ if (array->len == 0)
+ return NULL;
+
+ firstValueDup = g_strdup(g_ptr_array_index(array, 0));
+ if (!firstValueDup) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ return firstValueDup;
+}
+
+GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_ENTITY(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
+ return NULL;
+ }
+
+ if (!key) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ gboolean found;
+ gpointer origKey, value;
+ GPtrArray *srcArray, *retArray;
+
+ retArray = g_ptr_array_new();
+ if (!retArray) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
+ if (!found)
+ return retArray;
+ srcArray = (GPtrArray *) value;
+ if (srcArray->len == 0)
+ return retArray;
+
+ struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
+ g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
+ if (arrayErr.err) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+ g_ptr_array_set_free_func(retArray, g_free);
+ g_ptr_array_free(retArray, TRUE);
+ return NULL;
+ }
+
+ return retArray;
+}
diff --git a/osinfo/osinfo_entity.h b/osinfo/osinfo_entity.h
new file mode 100644
index 0000000..0c8047c
--- /dev/null
+++ b/osinfo/osinfo_entity.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_entity.h
+ * All entities represented in libosinfo are derived from this class.
+ */
+
+#ifndef __OSINFO_ENTITY_H__
+#define __OSINFO_ENTITY_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_ENTITY (osinfo_entity_get_type ())
+#define OSINFO_ENTITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_ENTITY, OsinfoEntity))
+#define OSINFO_IS_ENTITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_ENTITY))
+#define OSINFO_ENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
+#define OSINFO_IS_ENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_ENTITY))
+#define OSINFO_ENTITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityClass))
+
+typedef struct _OsinfoEntity OsinfoEntity;
+
+typedef struct _OsinfoEntityClass OsinfoEntityClass;
+
+typedef struct _OsinfoEntityPrivate OsinfoEntityPrivate;
+
+/* object */
+struct _OsinfoEntity
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoEntityPrivate *priv;
+};
+
+/* class */
+struct _OsinfoEntityClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+gchar *osinfoGetId(OsinfoEntity *self, GError **err);
+GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err);
+gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err);
+GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err);
+
+#endif /* __OSINFO_ENTITY_H__ */
diff --git a/osinfo/osinfo_filter.c b/osinfo/osinfo_filter.c
new file mode 100644
index 0000000..c8dae31
--- /dev/null
+++ b/osinfo/osinfo_filter.c
@@ -0,0 +1,298 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoFilter, osinfo_filter, G_TYPE_OBJECT);
+
+#define OSINFO_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_FILTER, OsinfoFilterPrivate))
+
+static void osinfo_filter_finalize (GObject *object);
+
+static void
+osinfo_filter_finalize (GObject *object)
+{
+ OsinfoFilter *self = OSINFO_FILTER (object);
+
+ g_tree_destroy(self->priv->propertyConstraints);
+ g_tree_destroy(self->priv->relationshipConstraints);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_filter_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_filter_class_init (OsinfoFilterClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_filter_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoFilterPrivate));
+}
+
+static void
+osinfo_filter_init (OsinfoFilter *self)
+{
+ OsinfoFilterPrivate *priv;
+ priv = OSINFO_FILTER_GET_PRIVATE(self);
+ self->priv = priv;
+
+ self->priv->propertyConstraints = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreePtrArray);
+
+
+ self->priv->relationshipConstraints = g_tree_new_full(__osinfoIntCompare,
+ NULL,
+ NULL,
+ __osinfoFreePtrArray);
+}
+
+void osinfoFreeFilter(OsinfoFilter *self)
+{
+ g_object_unref(self);
+}
+
+gint osinfoAddFilterConstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return -EINVAL;
+
+ if (!OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return -EINVAL;
+ }
+
+ if (!propName) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return -EINVAL;
+ }
+
+ if (!propVal) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPVAL);
+ return -EINVAL;
+ }
+
+ // First check if there exists an array of entries for this key
+ // If not, create a ptrarray of strings for this key and insert into map
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *valueArray;
+ gchar *valueDup = NULL, *keyDup = NULL;
+
+ valueDup = g_strdup(propVal);
+
+ if (!valueDup)
+ goto error_free;
+
+ found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &foundValue);
+ if (!found) {
+ keyDup = g_strdup(propName);
+ valueArray = g_ptr_array_new_with_free_func(g_free);
+
+ if (!valueArray)
+ goto error_free;
+ if (!keyDup) {
+ g_ptr_array_free(valueArray, TRUE);
+ goto error_free;
+ }
+
+ g_tree_insert(self->priv->propertyConstraints, keyDup, valueArray);
+ }
+ else
+ valueArray = (GPtrArray *) foundValue;
+
+ // Add a copy of the value to the array
+ g_ptr_array_add(valueArray, valueDup);
+ return 0;
+
+error_free:
+ g_free(keyDup);
+ g_free(valueDup);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return -ENOMEM;
+}
+
+// Only applicable to OSes, ignored by other types of objects
+gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return -EINVAL;
+
+ if (!OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return -EINVAL;
+ }
+
+ if (!__osinfoCheckRelationshipValid(relshp)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+ return -EINVAL;
+ }
+
+ if (!OSINFO_IS_OS(os)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+ return -EINVAL;
+ }
+
+ // First check if there exists an array of entries for this key
+ // If not, create a ptrarray of strings for this key and insert into map
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *valueArray;
+
+ found = g_tree_lookup_extended(self->priv->relationshipConstraints, (gpointer) relshp, &origKey, &foundValue);
+ if (!found) {
+ valueArray = g_ptr_array_new();
+ if (!valueArray)
+ goto error_nomem;
+
+ g_tree_insert(self->priv->relationshipConstraints, (gpointer) relshp, valueArray);
+ }
+ else
+ valueArray = (GPtrArray *) foundValue;
+
+ // Add to the array
+ g_ptr_array_add(valueArray, os);
+ return 0;
+
+error_nomem:
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return -ENOMEM;
+}
+
+void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName)
+{
+ g_tree_remove(self->priv->propertyConstraints, propName);
+}
+
+void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp)
+{
+ g_tree_remove(self->priv->relationshipConstraints, (gpointer) relshp);
+}
+
+static gboolean __osinfoRemoveTreeEntry(gpointer key, gpointer value, gpointer data)
+{
+ GTree *tree = (GTree *) data;
+ g_tree_remove(tree, key);
+ return FALSE; // continue iterating
+}
+
+void osinfoClearAllFilterConstraints(OsinfoFilter *self)
+{
+ g_tree_foreach(self->priv->propertyConstraints, __osinfoRemoveTreeEntry, self->priv->propertyConstraints);
+ g_tree_foreach(self->priv->relationshipConstraints, __osinfoRemoveTreeEntry, self->priv->relationshipConstraints);
+}
+
+// get keyset for constraints map
+GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ GPtrArray *constraints = g_ptr_array_new();
+ if (!constraints) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ struct __osinfoPtrArrayErr arrayErr = {constraints, 0};
+ g_tree_foreach(self->priv->propertyConstraints, __osinfoGetKeys, &arrayErr);
+
+ // If we had an error, cleanup and return NULL
+ if (arrayErr.err != 0) {
+ int i;
+ for (i = 0; i < constraints->len; i++)
+ g_free(g_ptr_array_index(constraints, i));
+ g_ptr_array_free(constraints, TRUE);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+ return NULL;
+ }
+
+ return constraints;
+}
+
+// get values for given key
+GPtrArray *osinfoGetFilterConstraintValues(OsinfoFilter *self, gchar *propName, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ if (!propName) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
+ return NULL;
+ }
+
+ gboolean found;
+ gpointer origKey, value;
+ GPtrArray *srcArray, *retArray;
+
+ retArray = g_ptr_array_new();
+ if (!retArray) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &value);
+ if (!found)
+ return retArray;
+ srcArray = (GPtrArray *) value;
+ if (srcArray->len == 0)
+ return retArray;
+
+ struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
+ g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
+ if (arrayErr.err) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
+ g_ptr_array_set_free_func(retArray, g_free);
+ g_ptr_array_free(retArray, TRUE);
+ return NULL;
+ }
+
+ return retArray;
+}
+
+// get oses for given relshp
+OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ if (!__osinfoCheckRelationshipValid(relshp)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+ return NULL;
+ }
+
+ // Create our list
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ GPtrArray *relatedOses = NULL;
+ relatedOses = g_tree_lookup(self->priv->relationshipConstraints, (gpointer) relshp);
+ if (relatedOses) {
+ int i, len;
+ len = relatedOses->len;
+ for (i = 0; i < len; i++) {
+ OsinfoOs *os = g_ptr_array_index(relatedOses, i);
+ __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (os));
+ }
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_filter.h b/osinfo/osinfo_filter.h
new file mode 100644
index 0000000..9a60fcd
--- /dev/null
+++ b/osinfo/osinfo_filter.h
@@ -0,0 +1,64 @@
+/*
+ * libosinfo
+ *
+ * osinfo_filter.h
+ * Represents a filter in libosinfo.
+ */
+
+#ifndef __OSINFO_FILTER_H__
+#define __OSINFO_FILTER_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_FILTER (osinfo_filter_get_type ())
+#define OSINFO_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_FILTER, OsinfoFilter))
+#define OSINFO_IS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_FILTER))
+#define OSINFO_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_FILTER, OsinfoFilterClass))
+#define OSINFO_IS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_FILTER))
+#define OSINFO_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_FILTER, OsinfoFilterClass))
+
+//typedef struct _OsinfoFilter OsinfoFilter;
+// (defined in osinfo_objects.h)
+
+#include "osinfo_oslist.h"
+
+typedef struct _OsinfoFilterClass OsinfoFilterClass;
+
+typedef struct _OsinfoFilterPrivate OsinfoFilterPrivate;
+
+/* object */
+struct _OsinfoFilter
+{
+ OsinfoEntity parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoFilterPrivate *priv;
+};
+
+/* class */
+struct _OsinfoFilterClass
+{
+ OsinfoEntityClass parent_class;
+
+ /* class members */
+};
+
+void osinfoFreeFilter(OsinfoFilter *self);
+
+gint osinfoAddFilterContstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err);
+
+// Only applicable to OSes, ignored by other types of objects
+gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err);
+
+void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName);
+void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp);
+void osinfoClearAllFilterConstraints(OsinfoFilter *self);
+
+GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err);
+gchar *osinfoGetFilterConstraintValue(OsinfoFilter *self, GError **err);
+OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err);
+
+#endif /* __OSINFO_FILTER_H__ */
diff --git a/osinfo/osinfo_hypervisor.c b/osinfo/osinfo_hypervisor.c
new file mode 100644
index 0000000..712766f
--- /dev/null
+++ b/osinfo/osinfo_hypervisor.c
@@ -0,0 +1,122 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoHypervisor, osinfo_hypervisor, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_HYPERVISOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorPrivate))
+
+static void osinfo_hypervisor_finalize (GObject *object);
+
+static void
+osinfo_hypervisor_finalize (GObject *object)
+{
+ OsinfoHypervisor *self = OSINFO_HYPERVISOR (object);
+
+ g_tree_destroy (self->priv->sections);
+ g_tree_destroy (self->priv->sectionsAsList);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_hypervisor_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_hypervisor_class_init (OsinfoHypervisorClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_hypervisor_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoHypervisorPrivate));
+}
+
+static void
+osinfo_hypervisor_init (OsinfoHypervisor *self)
+{
+ OsinfoHypervisorPrivate *priv;
+ self->priv = priv = OSINFO_HYPERVISOR_GET_PRIVATE(self);
+
+ self->priv->sections = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceSection);
+ self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreePtrArray);
+}
+
+int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver)
+{
+ if( !OSINFO_IS_HYPERVISOR(self) || !section || !id || !driver)
+ return -EINVAL;
+
+ return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
+}
+
+void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section)
+{
+ if (!OSINFO_IS_HYPERVISOR(self) || !section)
+ return;
+
+ __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
+}
+
+GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_HYPERVISOR(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+ return NULL;
+ }
+
+ GPtrArray *deviceTypes = g_ptr_array_sized_new(g_tree_nnodes(self->priv->sections));
+ if (!deviceTypes) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ // For each key in our tree of device sections, dup and add to the array
+ struct __osinfoPtrArrayErr arrayErr = {deviceTypes, 0};
+ g_tree_foreach(self->priv->sections, __osinfoGetKeys, &arrayErr);
+ return deviceTypes;
+}
+
+OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_HYPERVISOR(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ if (!devType) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+ return NULL;
+ }
+
+ // Create our device list
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ // If section does not exist, return empty list
+ GPtrArray *sectionList = NULL;
+ sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+ if (!sectionList)
+ return newList;
+
+ // For each device in section list, apply filter. If filter passes, add device to list.
+ int i;
+ struct __osinfoDeviceLink *deviceLink;
+ for (i = 0; i < sectionList->len; i++) {
+ deviceLink = g_ptr_array_index(sectionList, i);
+ if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+ __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_hypervisor.h b/osinfo/osinfo_hypervisor.h
new file mode 100644
index 0000000..65c78dc
--- /dev/null
+++ b/osinfo/osinfo_hypervisor.h
@@ -0,0 +1,52 @@
+/*
+ * libosinfo
+ *
+ * osinfo_hypervisor.h
+ * Represents a hypervisor in libosinfo.
+ */
+
+#ifndef __OSINFO_HYPERVISOR_H__
+#define __OSINFO_HYPERVISOR_H__
+
+#include "osinfo_devicelist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_HYPERVISOR (osinfo_hypervisor_get_type ())
+#define OSINFO_HYPERVISOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisor))
+#define OSINFO_IS_HYPERVISOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISOR))
+#define OSINFO_HYPERVISOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
+#define OSINFO_IS_HYPERVISOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISOR))
+#define OSINFO_HYPERVISOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorClass))
+
+//typedef struct _OsinfoHypervisor OsinfoHypervisor;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoHypervisorClass OsinfoHypervisorClass;
+
+typedef struct _OsinfoHypervisorPrivate OsinfoHypervisorPrivate;
+
+/* object */
+struct _OsinfoHypervisor
+{
+ OsinfoEntity parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoHypervisorPrivate *priv;
+};
+
+/* class */
+struct _OsinfoHypervisorClass
+{
+ OsinfoEntityClass parent_class;
+
+ /* class members */
+};
+
+GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err);
+OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err);
+
+#endif /* __OSINFO_HYPERVISOR_H__ */
diff --git a/osinfo/osinfo_hypervisorlist.c b/osinfo/osinfo_hypervisorlist.c
new file mode 100644
index 0000000..147f4b4
--- /dev/null
+++ b/osinfo/osinfo_hypervisorlist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoHypervisorList, osinfo_hypervisorlist, OSINFO_TYPE_LIST);
+
+#define OSINFO_HYPERVISORLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListPrivate))
+
+static void osinfo_hypervisorlist_finalize (GObject *object);
+
+struct _OsinfoHypervisorListPrivate
+{
+ int tmp;
+};
+
+static void
+osinfo_hypervisorlist_finalize (GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_hypervisorlist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_hypervisorlist_class_init (OsinfoHypervisorListClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_hypervisorlist_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoHypervisorListPrivate));
+}
+
+static void
+osinfo_hypervisorlist_init (OsinfoHypervisorList *self)
+{
+ OsinfoHypervisorListPrivate *priv;
+ self->priv = priv = OSINFO_HYPERVISORLIST_GET_PRIVATE(self);
+
+}
+
+OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err)
+{
+ if (!OSINFO_IS_HYPERVISORLIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+ return NULL;
+ }
+
+ OsinfoList *selfAsList = OSINFO_LIST (self);
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+ return OSINFO_HYPERVISOR (entity);
+}
+
+OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_HYPERVISORLIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // For each element in self, if passes filter, add to new list.
+ OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+ return newList;
+}
+
+OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
+{
+ if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+ return NULL;
+ }
+
+ OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+
+ ret = __osinfoDoIntersect(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
+{
+ if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
+ return NULL;
+ }
+
+ OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoDoUnion(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_hypervisorlist.h b/osinfo/osinfo_hypervisorlist.h
new file mode 100644
index 0000000..bdc7f03
--- /dev/null
+++ b/osinfo/osinfo_hypervisorlist.h
@@ -0,0 +1,50 @@
+/*
+ * libosinfo
+ *
+ * osinfo_hypervisorlist.h
+ */
+
+#ifndef __OSINFO_HYPERVISORLIST_H__
+#define __OSINFO_HYPERVISORLIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_HYPERVISORLIST (osinfo_hypervisorlist_get_type ())
+#define OSINFO_HYPERVISORLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorList))
+#define OSINFO_IS_HYPERVISORLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_HYPERVISORLIST))
+#define OSINFO_HYPERVISORLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
+#define OSINFO_IS_HYPERVISORLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_HYPERVISORLIST))
+#define OSINFO_HYPERVISORLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListClass))
+
+typedef struct _OsinfoHypervisorList OsinfoHypervisorList;
+
+typedef struct _OsinfoHypervisorListClass OsinfoHypervisorListClass;
+
+typedef struct _OsinfoHypervisorListPrivate OsinfoHypervisorListPrivate;
+
+/* object */
+struct _OsinfoHypervisorList
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoHypervisorListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoHypervisorListClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err);
+OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err);
+OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
+OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherHypervisorList, GError **err);
+
+#endif /* __OSINFO_HYPERVISORLIST_H__ */
diff --git a/osinfo/osinfo_list.c b/osinfo/osinfo_list.c
new file mode 100644
index 0000000..9e88993
--- /dev/null
+++ b/osinfo/osinfo_list.c
@@ -0,0 +1,219 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoList, osinfo_list, G_TYPE_OBJECT);
+
+#define OSINFO_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_LIST, OsinfoListPrivate))
+
+static void osinfo_list_finalize (GObject *object);
+
+struct _OsinfoListPrivate
+{
+ GPtrArray *array;
+};
+
+static void
+osinfo_list_finalize (GObject *object)
+{
+ OsinfoList *self = OSINFO_LIST (object);
+
+ g_ptr_array_free(self->priv->array, TRUE);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_list_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_list_class_init (OsinfoListClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_list_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoListPrivate));
+}
+
+static void
+osinfo_list_init (OsinfoList *self)
+{
+ OsinfoListPrivate *priv;
+ self->priv = priv = OSINFO_LIST_GET_PRIVATE(self);
+
+ self->priv->array = g_ptr_array_new();
+}
+
+void osinfoFreeList(OsinfoList *self)
+{
+ g_object_unref(self);
+}
+
+gint osinfoListLength(OsinfoList *self)
+{
+ return self->priv->array->len;
+}
+
+OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx)
+{
+ return g_ptr_array_index(self->priv->array, idx);
+}
+
+void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity)
+{
+ g_ptr_array_add(self->priv->array, entity);
+}
+
+void __osinfoDoFilter(OsinfoList *src, OsinfoList *dst, OsinfoFilter *filter)
+{
+ int i, len;
+ len = osinfoListLength(src);
+ for (i = 0; i < len; i++) {
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(src, i);
+ if (__osinfoEntityPassesFilter(filter, entity))
+ __osinfoListAdd(dst, entity);
+ }
+}
+
+OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_LIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // For each element in self, if passes filter, add to new list.
+ OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ __osinfoDoFilter(self, newList, filter);
+ return newList;
+}
+
+int __osinfoDoIntersect(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
+{
+ int i, len;
+
+ // Make set representation of otherList and newList
+ GTree *otherSet = g_tree_new(__osinfoStringCompareBase);
+ if (!otherSet)
+ return -ENOMEM;
+
+ GTree *newSet = g_tree_new(__osinfoStringCompareBase);
+ if (!newSet) {
+ g_tree_destroy(otherSet);
+ return -ENOMEM;
+ }
+
+ // Add all from otherList to otherSet
+ len = osinfoListLength(src2);
+ for (i = 0; i < len; i++) {
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
+ gchar *id = entity->priv->id;
+ g_tree_insert(otherSet, id, entity);
+ }
+
+ // If other contains entity, and new list does not, add to new list
+ len = osinfoListLength(src1);
+ for (i = 0; i < len; i++) {
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
+ gchar *id = entity->priv->id;
+
+ if (g_tree_lookup(otherSet, entity->priv->id) &&
+ !g_tree_lookup(newSet, entity->priv->id)) {
+ g_tree_insert(newSet, id, entity);
+ __osinfoListAdd(dst, entity);
+ }
+ }
+
+ g_tree_destroy(otherSet);
+ g_tree_destroy(newSet);
+ return 0;
+}
+
+OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err)
+{
+ if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+ return NULL;
+ }
+
+ OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+
+ ret = __osinfoDoIntersect(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+int __osinfoDoUnion(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
+{
+ // Make set version of new list
+ GTree *newSet = g_tree_new(__osinfoStringCompareBase);
+ if (!newSet)
+ return -ENOMEM;
+
+ // Add all from other list to new list
+ int i, len;
+ len = osinfoListLength(src2);
+ for (i = 0; i < len; i++) {
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
+ gchar *id = entity->priv->id;
+ __osinfoListAdd(dst, entity);
+ g_tree_insert(newSet, id, entity);
+ }
+
+ // Add remaining elements from this list to new list
+ len = osinfoListLength(src1);
+ for (i = 0; i < len; i++) {
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
+ gchar *id = entity->priv->id;
+ // If new list does not contain element, add to new list
+ if (!g_tree_lookup(newSet, id)) {
+ __osinfoListAdd(dst, entity);
+ g_tree_insert(newSet, id, entity);
+ }
+ }
+
+ g_tree_destroy(newSet);
+ return 0;
+}
+
+OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err)
+{
+ if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
+ return NULL;
+ }
+
+ OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoDoUnion(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_list.h b/osinfo/osinfo_list.h
new file mode 100644
index 0000000..81a2bc7
--- /dev/null
+++ b/osinfo/osinfo_list.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_list.h
+ */
+
+#ifndef __OSINFO_LIST_H__
+#define __OSINFO_LIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_LIST (osinfo_list_get_type ())
+#define OSINFO_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_LIST, OsinfoList))
+#define OSINFO_IS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_LIST))
+#define OSINFO_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_LIST, OsinfoListClass))
+#define OSINFO_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_LIST))
+#define OSINFO_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_LIST, OsinfoListClass))
+
+typedef struct _OsinfoListClass OsinfoListClass;
+
+typedef struct _OsinfoListPrivate OsinfoListPrivate;
+
+/* object */
+struct _OsinfoList
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoListClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+void osinfoFreeList(OsinfoList *self);
+gint osinfoListLength(OsinfoList *self);
+
+OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err);
+OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx);
+OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err);
+OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err);
+
+#endif /* __OSINFO_LIST_H__ */
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
new file mode 100644
index 0000000..a3ba4fe
--- /dev/null
+++ b/osinfo/osinfo_os.c
@@ -0,0 +1,402 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoOs, osinfo_os, OSINFO_TYPE_ENTITY);
+
+#define OSINFO_OS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OS, OsinfoOsPrivate))
+
+static void osinfo_os_finalize (GObject *object);
+
+static void
+osinfo_os_finalize (GObject *object)
+{
+ OsinfoOs *self = OSINFO_OS (object);
+
+ g_tree_destroy (self->priv->sections);
+ g_tree_destroy (self->priv->sectionsAsList);
+ g_tree_destroy (self->priv->hypervisors);
+ g_tree_destroy (self->priv->relationshipsByOs);
+ g_tree_destroy (self->priv->relationshipsByType);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_os_class_init (OsinfoOsClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_os_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoOsPrivate));
+}
+
+static void
+osinfo_os_init (OsinfoOs *self)
+{
+ OsinfoOsPrivate *priv;
+ self->priv = priv = OSINFO_OS_GET_PRIVATE(self);
+
+ self->priv->sections = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreeDeviceSection);
+
+ self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreePtrArray);
+
+ self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreeRelationship);
+ self->priv->relationshipsByType = g_tree_new(__osinfoIntCompareBase);
+
+ self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreeHvSection);
+}
+
+static int __osinfoAddOsRelationshipByOs(OsinfoOs *self,
+ gchar *otherOsId,
+ osinfoRelationship rel,
+ struct __osinfoOsLink *osLink)
+{
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *relationshipsForOs;
+ gchar *otherOsIdDup = NULL;
+
+ found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
+ if (!found) {
+ otherOsIdDup = g_strdup(otherOsId);
+ relationshipsForOs = g_ptr_array_new_with_free_func(__osinfoFreeOsLink);
+
+ if (!relationshipsForOs)
+ return -ENOMEM;
+ if (!otherOsIdDup) {
+ g_ptr_array_free(relationshipsForOs, TRUE);
+ return -ENOMEM;
+ }
+ g_tree_insert(self->priv->relationshipsByOs, otherOsIdDup, relationshipsForOs);
+ }
+ else
+ relationshipsForOs = (GPtrArray *) foundValue;
+
+ g_ptr_array_add(relationshipsForOs, osLink);
+ return 0;
+}
+
+static int __osinfoAddOsRelationshipByType(OsinfoOs *self,
+ osinfoRelationship relshp,
+ struct __osinfoOsLink *osLink)
+{
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *relationshipsForType;
+
+ found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
+ if (!found) {
+ relationshipsForType = g_ptr_array_new();
+ if (!relationshipsForType)
+ return -ENOMEM;
+
+ g_tree_insert(self->priv->relationshipsByType, (gpointer) relshp, relationshipsForType);
+ }
+ else
+ relationshipsForType = (GPtrArray *) foundValue;
+
+ g_ptr_array_add(relationshipsForType, osLink);
+ return 0;
+}
+
+static void __osinfoRemoveOsLink(OsinfoOs *self,
+ gchar *otherOsId,
+ osinfoRelationship relshp,
+ struct __osinfoOsLink *osLink)
+{
+ gboolean found;
+ gpointer origKey, foundValue;
+ GPtrArray *relationshipsForOs;
+ GPtrArray *relationshipsForType;
+
+ // First from by-os list
+ found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
+ if (found) {
+ relationshipsForOs = (GPtrArray *) foundValue;
+ g_ptr_array_remove(relationshipsForOs, osLink);
+ }
+
+ // Now from by-relshp list
+ found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
+ if (found) {
+ relationshipsForType = (GPtrArray *) foundValue;
+ g_ptr_array_remove(relationshipsForType, osLink);
+ }
+}
+
+int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel)
+{
+ if ( !OSINFO_IS_OS(self) || !otherOsId)
+ return -EINVAL;
+
+ struct __osinfoOsLink *osLink = NULL;
+ osLink = g_malloc(sizeof(*osLink));
+ if (!osLink)
+ return -ENOMEM;
+
+ osLink->subjectOs = self;
+ osLink->verb = rel;
+
+ int ret;
+ ret = __osinfoAddOsRelationshipByOs(self, otherOsId, rel, osLink);
+ if (ret != 0)
+ goto error_free;
+
+ ret = __osinfoAddOsRelationshipByType(self, rel, osLink);
+ if (ret != 0)
+ goto error_cleanup;
+
+ return ret;
+
+error_cleanup:
+ __osinfoRemoveOsLink(self, otherOsId, rel, osLink);
+error_free:
+ g_free(osLink);
+ return ret;
+}
+
+int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver)
+{
+ if( !OSINFO_IS_OS(self) || !section || !id || !driver)
+ return -EINVAL;
+
+ return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
+}
+
+void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section)
+{
+ if (!OSINFO_IS_OS(self) || !section)
+ return;
+
+ __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
+}
+
+struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId)
+{
+ if (!OSINFO_IS_OS(self) || !hvId)
+ return NULL;
+
+ gboolean found;
+ gpointer origKey, foundValue;
+ struct __osinfoHvSection *hvSection = NULL;
+ gchar *hvIdDup = NULL;
+ GTree *deviceSections;
+ GTree *deviceSectionsAsList;
+
+ found = g_tree_lookup_extended(self->priv->hypervisors, hvId, &origKey, &foundValue);
+ if (!found) {
+ hvSection = g_malloc(sizeof(*hvSection));
+ hvIdDup = g_strdup(hvId);
+ deviceSections = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreeDeviceSection);
+
+ if (!deviceSections)
+ goto error_free;
+
+ deviceSectionsAsList = g_tree_new_full(__osinfoStringCompare,
+ NULL,
+ g_free,
+ __osinfoFreePtrArray);
+ if (!deviceSectionsAsList) {
+ g_tree_destroy(deviceSections);
+ goto error_free;
+ }
+
+ if (!hvSection || !hvIdDup) {
+ g_tree_destroy(deviceSectionsAsList);
+ g_tree_destroy(deviceSections);
+ goto error_free;
+ }
+
+ hvSection->os = self;
+ // Will set hv link later
+ hvSection->sections = deviceSections;
+ hvSection->sectionsAsList = deviceSectionsAsList;
+
+ g_tree_insert(self->priv->hypervisors, hvIdDup, hvSection);
+ return hvSection;
+ }
+ else
+ return (struct __osinfoHvSection *) foundValue;
+
+error_free:
+ g_free(hvSection);
+ g_free(hvIdDup);
+ return NULL;
+}
+
+void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId)
+{
+ g_tree_remove(self->priv->hypervisors, hvId);
+}
+
+OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_OS(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+ return NULL;
+ }
+
+ if (hv && !OSINFO_IS_HYPERVISOR(hv)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+ return NULL;
+ }
+
+ if (!devType) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // Check if device type info present for <os,hv>, else return NULL.
+
+ GPtrArray *sectionList = NULL;
+ if (hv) {
+ // Check if hypervisor specific info present for Os, else return NULL.
+ struct __osinfoHvSection *hvSection = NULL;
+ hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+ if (!hvSection)
+ return NULL;
+
+ sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
+ if (!sectionList)
+ return NULL;
+ }
+ else {
+ sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+ if (!sectionList)
+ return NULL;
+ }
+
+ // For each device in section list, apply filter. If filter passes, return device.
+ int i;
+ struct __osinfoDeviceLink *deviceLink;
+ for (i = 0; i < sectionList->len; i++) {
+ deviceLink = g_ptr_array_index(sectionList, i);
+ if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+ return deviceLink->dev;
+ }
+
+ // If no devices pass filter, return NULL.
+ return NULL;
+}
+
+OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_OS(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+ return NULL;
+ }
+
+ if (!__osinfoCheckRelationshipValid(relshp)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
+ return NULL;
+ }
+
+ // Create our list
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ GPtrArray *relatedOses = NULL;
+ relatedOses = g_tree_lookup(self->priv->relationshipsByType, (gpointer) relshp);
+ if (relatedOses) {
+ int i, len;
+ len = relatedOses->len;
+ for (i = 0; i < len; i++) {
+ struct __osinfoOsLink *osLink = g_ptr_array_index(relatedOses, i);
+ __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (osLink->directObjectOs));
+ }
+ }
+
+ return newList;
+}
+
+OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
+{
+ if (!__osinfoCheckGErrorParamValid(err))
+ return NULL;
+
+ if (!OSINFO_IS_OS(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
+ return NULL;
+ }
+
+ if (!OSINFO_IS_HYPERVISOR(hv)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
+ return NULL;
+ }
+
+ if (!devType) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(filter)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ GPtrArray *sectionList = NULL;
+
+ // Create our device list
+ OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ if (hv) {
+ struct __osinfoHvSection *hvSection = NULL;
+ hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
+ if (!hvSection)
+ return newList;
+
+ sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
+ if (!sectionList)
+ return newList;
+ }
+ else {
+ sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
+ if (!sectionList)
+ return newList;
+ }
+
+ // For each device in section list, apply filter. If filter passes, add device to list.
+ int i;
+ struct __osinfoDeviceLink *deviceLink;
+ for (i = 0; i < sectionList->len; i++) {
+ deviceLink = g_ptr_array_index(sectionList, i);
+ if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
+ __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
+ }
+
+ return NULL;
+}
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
new file mode 100644
index 0000000..83241c9
--- /dev/null
+++ b/osinfo/osinfo_os.h
@@ -0,0 +1,55 @@
+/*
+ * libosinfo
+ *
+ * osinfo_os.h
+ * Represents an operating system in libosinfo.
+ */
+
+#ifndef __OSINFO_OS_H__
+#define __OSINFO_OS_H__
+
+#include <glib-object.h>
+#include "osinfo_oslist.h"
+#include "osinfo_devicelist.h"
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_OS (osinfo_os_get_type ())
+#define OSINFO_OS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OS, OsinfoOs))
+#define OSINFO_IS_OS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OS))
+#define OSINFO_OS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OS, OsinfoOsClass))
+#define OSINFO_IS_OS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OS))
+#define OSINFO_OS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OS, OsinfoOsClass))
+
+//typedef struct _OsinfoOs OsinfoOs;
+// (defined in osinfo_objects.h)
+
+typedef struct _OsinfoOsClass OsinfoOsClass;
+
+typedef struct _OsinfoOsPrivate OsinfoOsPrivate;
+
+/* object */
+struct _OsinfoOs
+{
+ OsinfoEntity parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoOsPrivate *priv;
+};
+
+/* class */
+struct _OsinfoOsClass
+{
+ OsinfoEntityClass parent_class;
+
+ /* class members */
+};
+
+OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
+OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err);
+OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err);
+
+#endif /* __OSINFO_OS_H__ */
diff --git a/osinfo/osinfo_oslist.c b/osinfo/osinfo_oslist.c
new file mode 100644
index 0000000..4a3d1ce
--- /dev/null
+++ b/osinfo/osinfo_oslist.c
@@ -0,0 +1,121 @@
+#include <osinfo/osinfo.h>
+
+G_DEFINE_TYPE (OsinfoOsList, osinfo_oslist, OSINFO_TYPE_LIST);
+
+#define OSINFO_OSLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListPrivate))
+
+static void osinfo_oslist_finalize (GObject *object);
+
+struct _OsinfoOsListPrivate
+{
+ int tmp;
+};
+
+static void
+osinfo_oslist_finalize (GObject *object)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (osinfo_oslist_parent_class)->finalize (object);
+}
+
+/* Init functions */
+static void
+osinfo_oslist_class_init (OsinfoOsListClass *klass)
+{
+ GObjectClass *g_klass = G_OBJECT_CLASS (klass);
+
+ g_klass->finalize = osinfo_oslist_finalize;
+ g_type_class_add_private (klass, sizeof (OsinfoOsListPrivate));
+}
+
+static void
+osinfo_oslist_init (OsinfoOsList *self)
+{
+ OsinfoOsListPrivate *priv;
+ self->priv = priv = OSINFO_OSLIST_GET_PRIVATE(self);
+
+}
+
+OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err)
+{
+ if (!OSINFO_IS_OSLIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+ return NULL;
+ }
+
+ OsinfoList *selfAsList = OSINFO_LIST (self);
+ OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
+ return OSINFO_OS (entity);
+}
+
+OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err)
+{
+ if (!OSINFO_IS_OSLIST(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+ return NULL;
+ }
+
+ if (filter && !OSINFO_IS_FILTER(self)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
+ return NULL;
+ }
+
+ // For each element in self, if passes filter, add to new list.
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
+ return newList;
+}
+
+OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
+{
+ if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+ return NULL;
+ }
+
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+
+ ret = __osinfoDoIntersect(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
+
+OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
+{
+ if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
+ return NULL;
+ }
+
+ OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
+ if (!newList) {
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
+ return NULL;
+ }
+
+ int ret;
+ ret = __osinfoDoUnion(self, otherList, newList);
+ if (ret != 0) {
+ g_object_unref(newList);
+ g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
+ return NULL;
+ }
+
+ return newList;
+}
diff --git a/osinfo/osinfo_oslist.h b/osinfo/osinfo_oslist.h
new file mode 100644
index 0000000..168f5a5
--- /dev/null
+++ b/osinfo/osinfo_oslist.h
@@ -0,0 +1,51 @@
+/*
+ * libosinfo
+ *
+ * osinfo_oslist.h
+ * All entities represented in libosinfo are derived from this class.
+ */
+
+#ifndef __OSINFO_OSLIST_H__
+#define __OSINFO_OSLIST_H__
+
+/*
+ * Type macros.
+ */
+#define OSINFO_TYPE_OSLIST (osinfo_oslist_get_type ())
+#define OSINFO_OSLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSINFO_TYPE_OSLIST, OsinfoOsList))
+#define OSINFO_IS_OSLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSINFO_TYPE_OSLIST))
+#define OSINFO_OSLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
+#define OSINFO_IS_OSLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OSLIST))
+#define OSINFO_OSLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListClass))
+
+typedef struct _OsinfoOsList OsinfoOsList;
+
+typedef struct _OsinfoOsListClass OsinfoOsListClass;
+
+typedef struct _OsinfoOsListPrivate OsinfoOsListPrivate;
+
+/* object */
+struct _OsinfoOsList
+{
+ GObject parent_instance;
+
+ /* public */
+
+ /* private */
+ OsinfoOsListPrivate *priv;
+};
+
+/* class */
+struct _OsinfoOsListClass
+{
+ GObjectClass parent_class;
+
+ /* class members */
+};
+
+OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err);
+OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err);
+OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
+OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherOsList, GError **err);
+
+#endif /* __OSINFO_OSLIST_H__ */
diff --git a/src/osinfo_common.c b/src/osinfo_common.c
deleted file mode 100644
index 3dc1cc0..0000000
--- a/src/osinfo_common.c
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <osinfo.h>
-
-static int __osinfoAddDeviceToList(GTree *allSectionsAsList,
- gchar *sectionName,
- struct __osinfoDeviceLink *deviceLink)
-{
- if (!allSectionsAsList || !sectionName || !deviceLink)
- return -EINVAL;
-
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *sectionList;
- gchar *sectionNameDup = NULL;
-
- found = g_tree_lookup_extended(allSectionsAsList, sectionName, &origKey, &foundValue);
- if (!found) {
- sectionList = g_ptr_array_new();
- sectionNameDup = g_strdup(sectionName);
-
- if (!sectionList)
- goto error_free;
- if (!sectionNameDup) {
- g_ptr_array_free(sectionList, TRUE);
- goto error_free;
- }
-
- g_tree_insert(allSectionsAsList, sectionNameDup, sectionList);
- }
- else
- sectionList = (GPtrArray *) foundValue;
-
- g_ptr_array_add(sectionList, deviceLink);
- return 0;
-
-error_free:
- g_free(sectionNameDup);
- return -ENOMEM;
-}
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver)
-{
- if (!allSections || !sectionName || !id)
- return -EINVAL;
-
- gboolean found;
- gpointer origKey, foundValue;
- gchar *sectionNameDup = NULL, *idDup = NULL, *driverDup = NULL;
- GTree *section;
- struct __osinfoDeviceLink *deviceLink;
- int ret;
-
- idDup = g_strdup(id);
- driverDup = g_strdup(driver);
- deviceLink = g_malloc(sizeof(*deviceLink));
-
- if (!idDup || g_strcmp0(driverDup, driver) != 0 || !deviceLink)
- goto error_free;
-
- found = g_tree_lookup_extended(allSections, sectionName, &origKey, &foundValue);
- if (!found) {
- section = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceLink);
- sectionNameDup = g_strdup(sectionName);
-
- if (!section)
- goto error_free;
- if (!sectionNameDup) {
- g_tree_destroy(section);
- goto error_free;
- }
-
- g_tree_insert(allSections, sectionNameDup, section);
- }
- else
- section = (GTree *) foundValue;
-
- deviceLink->driver = driverDup;
- g_tree_insert(section, idDup, deviceLink);
-
- ret = 0;
- if (allSectionsAsList)
- ret = __osinfoAddDeviceToList(allSectionsAsList, sectionName, deviceLink);
-
- return ret;
-
-error_free:
- g_free(sectionNameDup);
- g_free(idDup);
- g_free(driverDup);
- g_free(deviceLink);
- return -ENOMEM;
-}
-
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section)
-{
- if (!allSections || !section)
- return;
-
- g_tree_remove(allSections, section);
- g_tree_remove(allSectionsAsList, section);
-}
-
-void __osinfoFreeDeviceLink(gpointer ptr)
-{
- if (!ptr)
- return;
- struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) ptr;
- g_free(devLink->driver);
- g_free(devLink);
-}
-
-void __osinfoFreeDeviceSection(gpointer tree)
-{
- if (!tree)
- return;
- g_tree_destroy((GTree *)tree);
-}
-
-gint __osinfoStringCompare(gconstpointer a,
- gconstpointer b,
- gpointer data)
-{
- // a and b are each gchar *, data is ignored
- gchar *str1 = (gchar *) a;
- gchar *str2 = (gchar *) b;
- return g_strcmp0(str1, str2);
-}
-
-gint __osinfoStringCompareBase(gconstpointer a,
- gconstpointer b)
-{
- // a and b are each gchar *, data is ignored
- gchar *str1 = (gchar *) a;
- gchar *str2 = (gchar *) b;
- return g_strcmp0(str1, str2);
-}
-
-gint __osinfoIntCompareBase(gconstpointer a,
- gconstpointer b)
-{
- // a and b are each gchar *, data is ignored
- unsigned long int1 = (unsigned long) a;
- unsigned long int2 = (unsigned long) b;
- return a - b;
-}
-
-gint __osinfoIntCompare(gconstpointer a,
- gconstpointer b,
- gpointer data)
-{
- // a and b are each gchar *, data is ignored
- unsigned long int1 = (unsigned long) a;
- unsigned long int2 = (unsigned long) b;
- return a - b;
-}
-
-void __osinfoFreePtrArray(gpointer ptrarray)
-{
- g_ptr_array_free(ptrarray, TRUE);
-}
-
-void __osinfoFreeRelationship(gpointer ptrarray)
-{
- if (!ptrarray)
- return;
- __osinfoFreePtrArray(ptrarray);
-}
-
-void __osinfoFreeParamVals(gpointer ptrarray)
-{
- if (!ptrarray)
- return;
- __osinfoFreePtrArray(ptrarray);
-}
-
-void __osinfoFreeOsLink(gpointer ptr)
-{
- if (!ptr)
- return;
- struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) ptr;
- g_free(osLink);
-}
-
-void __osinfoFreeHvSection(gpointer ptr)
-{
- if (!ptr)
- return;
- struct __osinfoHvSection * hvSection = (struct __osinfoHvSection *) ptr;
- g_tree_destroy(hvSection->sections);
- g_tree_destroy(hvSection->sectionsAsList);
- g_free(hvSection);
-}
-
-gboolean __osinfoFilterCheckProperty(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoFilterPassArgs *args;
- args = (struct __osinfoFilterPassArgs *) data;
- OsinfoEntity *entity = args->entity;
-
- // Key is property to filter on
- // Value is array of values for property
-
- GPtrArray *filterValues = (GPtrArray *) value;
- GPtrArray *entityValues = NULL;
-
- entityValues = g_tree_lookup(entity->priv->params, key);
- if (!entityValues && filterValues->len > 0) {
- args->passed = 0;
- return TRUE; // not passed
- }
-
- int i;
- for (i = 0; i < filterValues->len; i++) {
- gchar *currValue = g_ptr_array_index(filterValues, i);
- int j, found = 0;
- for (j = 0; j < entityValues->len; j++) {
- gchar *testValue = g_ptr_array_index(entityValues, j);
- if (g_strcmp0(currValue, testValue) == 0) {
- found = 1;
- break;
- }
- }
- if (found)
- continue;
- else {
- args->passed = 0;
- return TRUE; // not passed
- }
- }
-
- args->passed = 1;
- return FALSE; // continue iterating
-}
-
-int __osinfoEntityPassesFilter(OsinfoFilter *filter, OsinfoEntity *entity)
-{
- if (!OSINFO_IS_ENTITY(entity))
- return 0;
-
- if (!filter)
- return 1;
-
- if (!OSINFO_IS_FILTER(filter))
- return 0;
-
- struct __osinfoFilterPassArgs args = {0, entity};
- g_tree_foreach(filter->priv->propertyConstraints, __osinfoFilterCheckProperty, &args);
- if (args.passed)
- return 1;
- else
- return 0;
-}
-
-int __osinfoDevicePassesFilter(OsinfoFilter *filter, OsinfoDevice *device)
-{
- // Check is device
- return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (device));
-}
-
-gboolean __osinfoFilterCheckRelationships(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoFilterPassArgs *args;
- args = (struct __osinfoFilterPassArgs *) data;
- OsinfoOs *os = (OsinfoOs *) args->entity;
-
- // Key is relationship to filter on
- // Value is array of oses for relationship
-
- GPtrArray *filterOses = (GPtrArray *) value;
- GPtrArray *oses = NULL;
-
- oses = g_tree_lookup(os->priv->relationshipsByType, key);
- if (!oses && filterOses->len > 0) {
- args->passed = 0;
- return TRUE; // not passed
- }
-
- int i;
- for (i = 0; i < filterOses->len; i++) {
- OsinfoOs *currOs = g_ptr_array_index(filterOses, i);
- int j, found = 0;
- for (j = 0; j < oses->len; j++) {
- OsinfoOs *testOs = g_ptr_array_index(oses, j);
- if (testOs == currOs) {
- found = 1;
- break;
- }
- }
- if (found)
- continue;
- else {
- args->passed = 0;
- return TRUE; // not passed
- }
- }
-
- args->passed = 1;
- return FALSE; // continue iterating
-}
-
-int __osinfoOsPassesFilter(OsinfoFilter *filter, OsinfoOs *os)
-{
- if (!OSINFO_IS_OS(os))
- return 0;
-
- if (!filter)
- return 1;
-
- if (!OSINFO_IS_FILTER(filter))
- return 0;
-
- int pass = __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (os));
- if (!pass)
- return 0;
-
- struct __osinfoFilterPassArgs args = {0, (OsinfoEntity *) os};
- g_tree_foreach(filter->priv->relationshipConstraints, __osinfoFilterCheckRelationships, &args);
- if (args.passed)
- return 1;
- else
- return 0;
-}
-
-int __osinfoHypervisorPassesFilter(OsinfoFilter *filter, OsinfoHypervisor *hypervisor)
-{
- return __osinfoEntityPassesFilter(filter, OSINFO_ENTITY (hypervisor));
-}
-
-int __osinfoCheckGErrorParamValid(GError **err)
-{
- // If err is not null and *err is not null, then invalid
- if (err && *err)
- return 0;
- else return 1;
-}
-
-int __osinfoCheckRelationshipValid(osinfoRelationship relshp)
-{
- return (relshp > RELATIONSHIP_MIN && relshp < RELATIONSHIP_MAX);
-}
-
-gchar *__osinfoErrorToString(int err)
-{
- switch (err) {
- case -ENOMEM:
- return OSINFO_NO_MEM;
- default:
- return OSINFO_OTHER;
- }
-}
diff --git a/src/osinfo_dataread.c b/src/osinfo_dataread.c
deleted file mode 100644
index e1e0d52..0000000
--- a/src/osinfo_dataread.c
+++ /dev/null
@@ -1,915 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <errno.h>
-#include <unistd.h>
-#include <libxml/xmlreader.h>
-
-#include <osinfo.h>
-
-#ifdef LIBXML_READER_ENABLED
-
-#define TEXT_NODE 3
-#define ELEMENT_NODE 1
-#define END_NODE 15
-#define WHITESPACE_NODE 14
-#define COMMENT_NODE 8
-
-/*
- * TODO:
- * 1. More robust handling of files that are in bad format
- * 2. Error messages for parsing
- */
-
-/*
- * Notes regarding parsing XML Data:
- *
- * The top level tag is <libosinfo>. The next highest level consists of
- * <device>, <hypervisor> and <os>. Each tag may be empty (of the form <tag />)
- * or containing data (of the form <tag>...</tag>). After parsing an object, the
- * cursor will be located at the closing tag for the object (which, for an empty
- * object, is the same as the starting tag for the object).
- */
-
-struct __osinfoDbRet {
- OsinfoDb *db;
- int *ret;
-};
-
-static gboolean __osinfoResolveDeviceLink(gpointer key, gpointer value, gpointer data)
-{
- gchar *id = (gchar *) key;
- struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) value;
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
-
- OsinfoDevice *dev = g_tree_lookup(db->priv->devices, id);
- if (!dev) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- devLink->dev = dev;
- *ret = 0;
- return FALSE;
-}
-
-static gboolean __osinfoResolveSectionDevices(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
- GTree *section = (GTree *) value;
- if (!section) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- g_tree_foreach(section, __osinfoResolveDeviceLink, dbRet);
- if (*ret)
- return TRUE;
- return FALSE;
-}
-
-static gboolean __osinfoResolveHvLink(gpointer key, gpointer value, gpointer data)
-{
- gchar *hvId = (gchar *) key;
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
- struct __osinfoHvSection *hvSection = (struct __osinfoHvSection *) value;
- OsinfoHypervisor *hv;
-
- g_tree_foreach(hvSection->sections, __osinfoResolveSectionDevices, dbRet);
- if (*ret)
- return TRUE;
-
- hv = g_tree_lookup(db->priv->hypervisors, hvId);
- if (!hv) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- hvSection->hv = hv;
- *ret = 0;
- return FALSE;
-}
-
-static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
-{
- gchar *targetOsId = (gchar *) key;
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
- struct __osinfoOsLink *osLink = (struct __osinfoOsLink *) value;
-
- OsinfoOs *targetOs;
- targetOs = g_tree_lookup(db->priv->oses, targetOsId);
- if (!targetOs) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- osLink->directObjectOs = targetOs;
- *ret = 0;
- return FALSE;
-}
-
-static gboolean __osinfoFixOsLinks(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
- OsinfoOs *os = OSINFO_OS(value);
- if (!os) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- g_tree_foreach(os->priv->sections, __osinfoResolveSectionDevices, dbRet);
- if (*ret)
- return TRUE;
-
- g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
- if (*ret)
- return TRUE;
-
- g_tree_foreach(os->priv->hypervisors, __osinfoResolveHvLink, dbRet);
- if (*ret)
- return TRUE;
-
- *ret = 0;
- return FALSE;
-}
-
-static gboolean __osinfoFixHvLinks(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
- OsinfoDb *db = dbRet->db;
- int *ret = dbRet->ret;
- OsinfoHypervisor *hv = OSINFO_HYPERVISOR(value);
- if (!hv) {
- *ret = -EINVAL;
- return TRUE;
- }
-
- g_tree_foreach(hv->priv->sections, __osinfoResolveSectionDevices, dbRet);
- if (*ret)
- return TRUE;
- return FALSE;
-}
-
-static int __osinfoFixObjLinks(OsinfoDb *db)
-{
- OsinfoHypervisor *hv;
- OsinfoOs *os;
- int ret;
-
- if (!OSINFO_IS_DB(db))
- return -EINVAL;
-
- struct __osinfoDbRet dbRet = {db, &ret};
-
- g_tree_foreach(db->priv->hypervisors, __osinfoFixHvLinks, &dbRet);
- if (ret)
- return ret;
- g_tree_foreach(db->priv->oses, __osinfoFixOsLinks, &dbRet);
-
- return ret;
-}
-
-static int __osinfoProcessTag(xmlTextReaderPtr reader, char** ptr_to_key, char** ptr_to_val)
-{
- int node_type, ret, err = 0;
- char* key = NULL;
- char* val = NULL;
- const xmlChar* node_name, * end_node_name, * xml_value;
-
- node_name = xmlTextReaderConstName(reader);
- if (!node_name)
- goto error;
-
- key = strdup(node_name);
- if (!key) {
- err = -ENOMEM;
- goto error;
- }
-
- /* Advance to next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1)
- goto error;
-
- /* Ensure node is a text node */
- node_type = xmlTextReaderNodeType(reader);
- if (node_type != TEXT_NODE)
- goto error;
-
- /* Store the value of the text node */
- xml_value = xmlTextReaderConstValue(reader);
- if (!xml_value)
- goto error;
-
- val = strdup(xml_value);
- if (!val) {
- err = -ENOMEM;
- goto error;
- }
-
- /* Advance to the next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1)
- goto error;
-
- /* Ensure the node is an end node for the tracked start node */
- node_type = xmlTextReaderNodeType(reader);
- end_node_name = xmlTextReaderConstName(reader);
- if (node_type != END_NODE ||
- !end_node_name ||
- strcmp(end_node_name, node_name) != 0)
- goto error;
-
- /* Now we have key and val with no errors so we return with success */
- *ptr_to_key = key;
- *ptr_to_val = val;
- return 0;
-
-error:
- free(key);
- free(val);
- *ptr_to_key = NULL;
- *ptr_to_val = NULL;
- if (err == 0)
- err = -EINVAL;
- return err;
-}
-
-static int __osinfoProcessDevSection(xmlTextReaderPtr reader,
- GTree *section, GTree *sectionAsList)
-{
- int err, empty, node_type;
- char * sectionType, * id, * key = NULL, * driver = NULL;
- const char * name;
-
- if (!section)
- return -EINVAL;
-
- sectionType = xmlTextReaderGetAttribute(reader, "type");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!sectionType)
- return -EINVAL;
-
- /* If no devices in section then we are done */
- if (empty)
- return 0;
-
- /* Otherwise, read in devices and add to section */
- for (;;) {
- /* Advance to next node */
- err = xmlTextReaderRead(reader);
- if (err != 1) {
- err = -EINVAL;
- goto error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
-
- /* If end of section, break */
- if (node_type == END_NODE && strcmp(name, "section") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- /* Element within section needs to be of type device */
- if (strcmp(name, "device") != 0) {
- err = -EINVAL;
- goto error;
- }
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!id) {
- err = -EINVAL;
- goto error;
- }
-
- if (!empty) {
- err = __osinfoProcessTag(reader, &key, &driver);
- if (err != 0 || !key || !driver)
- goto error;
- free(key);
- key = NULL; /* In case the next malloc fails, avoid a double free */
- }
-
- // Alright, we have the id and driver
- err = __osinfoAddDeviceToSection(section, sectionAsList, sectionType, id, driver);
- free (driver);
- driver = NULL;
- free (id);
- id = NULL;
- if (err != 0)
- goto error;
- }
- free(sectionType);
-
-finished:
- return 0;
-
-error:
- free(sectionType);
- free(key);
- free(driver);
- return err;
-}
-
-static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
- OsinfoOs *os)
-{
- /*
- * Get id for hypervisor else fail
- * While true:
- * Advance to next node
- * If node is end of hypervisor break
- * If node is not element type continue
- * If node is element type and not section fail
- * Else handle section and add to hv_link
- * If fail delete hv_link so far
- * On success add hv_link to os
- */
- int empty, node_type, err;
- char* id;
- const xmlChar* name;
- struct __osinfoHvSection *hvSection;
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!id)
- return -EINVAL;
-
- hvSection = __osinfoAddHypervisorSectionToOs(os, id);
- free(id);
- if (!hvSection)
- return -EINVAL;
-
- if (empty)
- goto finished;
-
- for (;;) {
- /* Advance to next node */
- err = xmlTextReaderRead(reader);
- if (err != 1) {
- err = -EINVAL;
- goto error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
- if (node_type == -1 || !name) {
- err = -EINVAL;
- goto error;
- }
-
- /* If end of hv link, break */
- if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- /* Ensure it is element node of type 'section' else fail */
- if (strcmp(name, "section") != 0) {
- err = -EINVAL;
- goto error;
- }
-
- /* Process device type info for this <os, hv> combination */
- err = __osinfoProcessDevSection(reader, hvSection->sections, hvSection->sectionsAsList);
- if (err != 0)
- goto error;
- }
-
-finished:
- return 0;
-
-error:
- return err;
-}
-
-static int __osinfoProcessOsRelationship(xmlTextReaderPtr reader,
- OsinfoOs *os,
- osinfoRelationship relationship)
-{
- int empty, ret;
- char* id;
- struct osi_os_link * os_link;
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
- if (!empty || !id) {
- free(id);
- return -EINVAL;
- }
-
- ret = __osinfoAddOsRelationship (os, id, relationship);
- free(id);
- return ret;
-}
-
-static int __osinfoProcessOs(OsinfoDb *db,
- xmlTextReaderPtr reader)
-{
- /* Cursor is at start of (possibly empty) os node */
- /*
- * First, determine if hv has ID or not, and if tag is empty or not.
- * The following cases can occur:
- * 1. No ID: Return invalid. Parse fails overall.
- * 2. Empty, ID: Make hv with given ID and no data and return.
- * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
- */
-
- int empty, node_type, err, ret;
- char* id, * key = NULL, * val = NULL;
- const xmlChar* name;
- OsinfoOs *os;
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!id)
- return -EINVAL;
-
- os = g_object_new(OSINFO_TYPE_OS, "id", id, "db", db, NULL);
- free(id);
- if (!os)
- return -ENOMEM;
-
- if (empty)
- goto finished;
-
- /* Current node is start of non empty os
- * While true:
- * Advance to next node
- * If node == end of os break
- * If node is not element, continue
- * If node is element and not section or hypervisor:
- * Note element name
- * Advance to next node, ensure type is text else error
- * Store value, advance to next node
- * Ensure node is end of current name
- * Store <key, val> in params list for object
- * If node is start of section handle section and track device driver
- * If node is hypervisor handle hypervisor link
- */
-
- for (;;) {
- /* Advance to next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
- if (node_type == -1 || !name) {
- err = -EINVAL;
- goto cleanup_error;
- }
- /* If end of os, break */
- if (node_type == END_NODE && strcmp(name, "os") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- if (strcmp(name, "section") == 0) {
- /* Node is start of device section for os */
- err = __osinfoProcessDevSection(reader, (OSINFO_OS(os))->priv->sections, (OSINFO_OS(os))->priv->sectionsAsList);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "hypervisor") == 0) {
- err = __osinfoProcessOsHvLink(reader, os);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "upgrades") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, UPGRADES);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "clones") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, CLONES);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "derives-from") == 0) {
- err = __osinfoProcessOsRelationship(reader, os, DERIVES_FROM);
- if (err != 0)
- goto cleanup_error;
- }
- else {
- /* Node is start of element of known name */
- err = __osinfoProcessTag(reader, &key, &val);
- if (err != 0 || !key || !val)
- goto cleanup_error;
-
- err = __osinfoAddParam(OSINFO_ENTITY(os), key, val);
- if (err != 0)
- goto cleanup_error;
-
- free(key);
- free(val);
- }
- }
-
-finished:
- __osinfoAddOsToDb(db, os);
- return 0;
- /* At end, cursor is at end of os node */
-
-cleanup_error:
- g_object_unref(os);
- return err;
-}
-
-static int __osinfoProcessHypervisor(OsinfoDb *db,
- xmlTextReaderPtr reader)
-{
- /* Cursor is at start of (possibly empty) hypervisor node */
-
- /*
- * First, determine if hv has ID or not, and if tag is empty or not.
- * The following cases can occur:
- * 1. No ID: Return invalid. Parse fails overall.
- * 2. Empty, ID: Make hv with given ID and no data and return.
- * 3. Non-Empty, ID: Make hv, parse data till closing tag, return.
- */
-
- int empty, node_type, err, ret;
- char* id;
- const xmlChar* name;
- OsinfoHypervisor *hv;
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!id)
- return -EINVAL;
-
-
- hv = g_object_new(OSINFO_TYPE_HYPERVISOR, "id", id, "db", db, NULL);
- free(id);
- if (!hv) {
- return -ENOMEM;
- }
-
- if (empty)
- goto finished;
-
- /* Current node is start of non empty hv
- * While true:
- * Advance to next node
- * If node == end of hv break
- * If node is not element, continue
- * If node is element and not section:
- * Note element name
- * Advance to next node, ensure type is text else error
- * Store value, advance to next node
- * Ensure node is end of current name
- * Store <key, val> in params list for object
- * If node is start of section:
- * Note section type
- * While true:
- * Advance to next node
- * If node is not element continue
- * If end of section, break
- * If not empty device node, parse error
- * If id not defined, parse error
- * Store id
- * Store all ids for given section in the HV
- */
-
- for (;;) {
- /* Advance to next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
- if (node_type == -1 || !name) {
- err = -EINVAL;
- goto cleanup_error;
- }
- /* If end of hv, break */
- if (node_type == END_NODE && strcmp(name, "hypervisor") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- if (strcmp(name, "section") == 0) {
- /* Node is start of device section for hv */
- err = __osinfoProcessDevSection(reader, (OSINFO_HYPERVISOR(hv))->priv->sections, (OSINFO_HYPERVISOR(hv))->priv->sectionsAsList);
- if (err != 0)
- goto cleanup_error;
- }
- else {
- /* Node is start of element of known name */
- char *key = NULL, *val = NULL;
- err = __osinfoProcessTag(reader, &key, &val);
- if (err != 0)
- goto cleanup_error;
-
-
- err = __osinfoAddParam(OSINFO_ENTITY(hv), key, val);
- free(key);
- free(val);
- if (err != 0)
- goto cleanup_error;
- }
- }
-
-finished:
- __osinfoAddHypervisorToDb(db, hv);
- return 0;
- /* At end, cursor is at end of hv node */
-
-cleanup_error:
- g_object_unref(hv);
- return err;
-}
-
-static int __osinfoProcessDevice(OsinfoDb *db,
- xmlTextReaderPtr reader)
-{
- /* Cursor is at start of (possibly empty) device node */
-
- /*
- * First, determine if device has ID or not, and if tag is empty or not.
- * The following cases can occur:
- * 1. No ID: Return invalid. Parse fails overall.
- * 2. Empty, ID: Make device with given ID and no data and return.
- * 3. Non-Empty, ID: Make device, parse data till closing tag, return.
- */
-
- int empty, node_type, err, ret;
- char* id, * key, * val;
- const xmlChar* name;
- OsinfoDevice *dev;
-
- id = xmlTextReaderGetAttribute(reader, "id");
- empty = xmlTextReaderIsEmptyElement(reader);
-
- if (!id)
- return -EINVAL;
-
- dev = g_object_new(OSINFO_TYPE_DEVICE, "id", id, "db", db, NULL);
- free(id);
- if (!dev) {
- // TODO: How do errors in gobject creation manifest themselves?
- return -ENOMEM;
- }
-
- if (empty)
- goto finished;
-
- /* Current node is start of non empty device
- * While true:
- * Advance to next node
- * If node == end of device break
- * If node is not element, continue
- * If node is element:
- * Note element name
- * Advance to next node, ensure type is text else error
- * Store value, advance to next node
- * Ensure node is end of current name
- * Store <key, val> in params list for object
- */
-
- for (;;) {
- /* Advance to next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
-
- if (node_type == -1 || !name) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- /* If end of device, break */
- if (node_type == END_NODE && strcmp(name, "device") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- /* Node is start of element of known name */
- err = __osinfoProcessTag(reader, &key, &val);
- if (err != 0 || !key || !val)
- goto cleanup_error;
-
- err = __osinfoAddParam(OSINFO_ENTITY(dev), key, val);
- if (err != 0)
- goto cleanup_error;
-
- free(key);
- free(val);
- }
-
-finished:
- // Add dev to db
- __osinfoAddDeviceToDb(db, dev);
- return 0;
- /* At end, cursor is at end of device node */
-
-cleanup_error:
- free(key);
- free(val);
- g_object_unref(dev);
- return err;
-}
-
-static int __osinfoProcessFile(OsinfoDb *db,
- xmlTextReaderPtr reader)
-{
- /*
- * File assumed to contain data in XML format. All data
- * is within <libosinfo>...</libosinfo>. The following steps are taken
- * to process the data within the file:
- *
- * Advance till we are at opening <libosinfo> tag.
- * While true:
- * Advance tag
- * If closing libosinfo tag, break
- * If non element tag, continue
- * If element tag, and element is not os, hypervisor or device, error
- * Else, switch on tag type and handle reading in data
- * After loop, return success if no error
- * If there was an error, clean up lib data acquired so far
- */
-
- int err, node_type, ret;
- const char* name;
-
- /* Advance to starting libosinfo tag */
- for (;;) {
- err = xmlTextReaderRead(reader);
- if (err != 1) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- if (node_type != ELEMENT_NODE)
- continue;
-
- name = xmlTextReaderConstName(reader);
- if (strcmp(name, "libosinfo") == 0)
- break;
- }
-
- /* Now read and handle each tag of interest */
- for (;;) {
- /* Advance to next node */
- ret = xmlTextReaderRead(reader);
- if (ret != 1) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- node_type = xmlTextReaderNodeType(reader);
- name = xmlTextReaderConstName(reader);
-
- if (node_type == -1 || !name) {
- err = -EINVAL;
- goto cleanup_error;
- }
-
- /* If end of libosinfo, break */
- if (node_type == END_NODE && strcmp(name, "libosinfo") == 0)
- break;
-
- /* If node is not start of an element, continue */
- if (node_type != ELEMENT_NODE)
- continue;
-
- /* Process element node */
- if (strcmp(name, "device") == 0) {
- err = __osinfoProcessDevice(db, reader);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "hypervisor") == 0) {
- err = __osinfoProcessHypervisor(db, reader);
- if (err != 0)
- goto cleanup_error;
- }
- else if (strcmp(name, "os") == 0) {
- err = __osinfoProcessOs(db, reader);
- if (err != 0)
- goto cleanup_error;
- }
- else {
- err = -EINVAL;
- goto cleanup_error;
- }
- }
-
- /* And we are done, successfully */
- return 0;
-
-cleanup_error:
- // Db will be unsatisfactorily initiated, caller will call unref to clean it
- return err;
-}
-
-static int __osinfoReadDataFile(OsinfoDb *db,
- const char *dir,
- const char *filename)
-{
- int ret;
- xmlTextReaderPtr reader;
- char *rel_name = malloc (strlen(dir) + 1 + strlen(filename) + 1);
- if (!rel_name)
- return -errno;
-
- stpcpy(stpcpy(stpcpy(rel_name, dir), "/"), filename);
-
- reader = xmlReaderForFile(rel_name, NULL, 0);
- free(rel_name);
- if (!reader) {
- return -EINVAL;
- }
- ret = __osinfoProcessFile(db, reader);
- xmlFreeTextReader(reader);
- return ret;
-}
-
-int __osinfoInitializeData(OsinfoDb *db)
-{
- int ret;
- DIR* dir;
- struct dirent *dp;
-
- char *backingDir;
- g_object_get(G_OBJECT(db), "backing-dir", &backingDir, NULL);
-
- /* Initialize library and check version */
- LIBXML_TEST_VERSION
-
- /* Get directory with backing data. Defaults to CWD */
- if (!backingDir)
- backingDir = ".";
-
- /* Get XML files in directory */
- dir = opendir(backingDir);
- if (!dir) {
- ret = errno;
- goto cleanup;
- }
-
- while ((dp=readdir(dir)) != NULL) {
- if (dp->d_type != DT_REG)
- continue;
- ret = __osinfoReadDataFile(db, backingDir, dp->d_name);
- if (ret != 0)
- break;
- }
- closedir(dir);
- if (ret == 0)
- ret = __osinfoFixObjLinks(db);
-
-cleanup:
- xmlCleanupParser();
- g_free(backingDir);
- return ret;
-}
-
-#else
-int __osinfoInitializeData(OsinfoDb *db)
-{
- return -ENOSYS;
-}
-#endif
diff --git a/src/osinfo_db.c b/src/osinfo_db.c
deleted file mode 100644
index f78d241..0000000
--- a/src/osinfo_db.c
+++ /dev/null
@@ -1,555 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDb, osinfo_db, G_TYPE_OBJECT);
-
-#define OSINFO_DB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DB, OsinfoDbPrivate))
-
-static void osinfo_db_set_property(GObject * object, guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void osinfo_db_get_property(GObject * object, guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-static void osinfo_db_finalize (GObject *object);
-
-enum OSI_DB_PROPERTIES {
- OSI_DB_PROP_0,
-
- OSI_DB_BACKING_DIR,
- OSI_DB_LIBVIRT_VER,
- OSI_DB_ERROR
-};
-
-static void
-osinfo_db_finalize (GObject *object)
-{
- OsinfoDb *self = OSINFO_DB (object);
-
- g_free (self->priv->backing_dir);
- g_free (self->priv->libvirt_ver);
-
- g_tree_destroy(self->priv->devices);
- g_tree_destroy(self->priv->hypervisors);
- g_tree_destroy(self->priv->oses);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_db_parent_class)->finalize (object);
-}
-
-static void
-osinfo_db_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- OsinfoDb *self = OSINFO_DB (object);
-
- switch (property_id)
- {
- case OSI_DB_BACKING_DIR:
- g_free(self->priv->backing_dir);
- self->priv->backing_dir = g_value_dup_string (value);
- break;
-
- case OSI_DB_LIBVIRT_VER:
- g_free(self->priv->libvirt_ver);
- self->priv->libvirt_ver = g_value_dup_string (value);
- break;
-
- case OSI_DB_ERROR:
- break;
-
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-osinfo_db_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- OsinfoDb *self = OSINFO_DB (object);
-
- switch (property_id)
- {
- case OSI_DB_BACKING_DIR:
- g_value_set_string (value, self->priv->backing_dir);
- break;
-
- case OSI_DB_LIBVIRT_VER:
- g_value_set_string (value, self->priv->libvirt_ver);
- break;
-
- case OSI_DB_ERROR:
- g_value_set_pointer(value, self->priv->error);
- break;
-
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-/* Init functions */
-static void
-osinfo_db_class_init (OsinfoDbClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- g_klass->set_property = osinfo_db_set_property;
- g_klass->get_property = osinfo_db_get_property;
- g_klass->finalize = osinfo_db_finalize;
-
- pspec = g_param_spec_string ("backing-dir",
- "Backing directory",
- "Contains backing data store.",
- NULL /* default value */,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
- g_object_class_install_property (g_klass,
- OSI_DB_BACKING_DIR,
- pspec);
-
- pspec = g_param_spec_string ("libvirt-ver",
- "Libvirt version",
- "Libvirt version user is interested in",
- NULL /* default value */,
- G_PARAM_READWRITE);
- g_object_class_install_property (g_klass,
- OSI_DB_LIBVIRT_VER,
- pspec);
-
- pspec = g_param_spec_pointer ("error",
- "Error",
- "GError object for db",
- G_PARAM_READABLE);
- g_object_class_install_property (g_klass,
- OSI_DB_ERROR,
- pspec);
-
- g_type_class_add_private (klass, sizeof (OsinfoDbPrivate));
-}
-
-
-static void
-osinfo_db_init (OsinfoDb *self)
-{
- OsinfoDbPrivate *priv;
- int ret;
- self->priv = priv = OSINFO_DB_GET_PRIVATE(self);
-
- self->priv->devices = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
- self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
- self->priv->oses = g_tree_new_full(__osinfoStringCompare, NULL, g_free, g_object_unref);
-
- self->priv->error = NULL;
- self->priv->ready = 0;
-}
-
-/** PUBLIC METHODS */
-
-int osinfoInitializeDb(OsinfoDb *self, GError **err)
-{
- int ret;
- // And now read in data.
- ret = __osinfoInitializeData(self);
- if (ret != 0) {
- self->priv->ready = 0;
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, "Error during reading data");
- }
- else
- self->priv->ready = 1;
- return ret;
-}
-
-OsinfoHypervisor *osinfoGetHypervisorById(OsinfoDb *self, gchar *id, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!id) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
- return NULL;
- }
-
- return g_tree_lookup(self->priv->hypervisors, id);
-}
-
-OsinfoDevice *osinfoGetDeviceById(OsinfoDb *self, gchar *id, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!id) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
- return NULL;
- }
-
- return g_tree_lookup(self->priv->devices, id);
-}
-
-OsinfoOs *osinfoGetOsById(OsinfoDb *self, gchar *id, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!id) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_ID);
- return NULL;
- }
-
- return g_tree_lookup(self->priv->oses, id);
-}
-
-static gboolean __osinfoFilteredAddToList(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoPopulateListArgs *args;
- args = (struct __osinfoPopulateListArgs *) data;
- OsinfoFilter *filter = args->filter;
- OsinfoList *list = args->list;
- GError **err = args->err;
-
- // Key is string ID, value is pointer to entity
- OsinfoEntity *entity = (OsinfoEntity *) value;
- if (__osinfoEntityPassesFilter(filter, entity)) {
- __osinfoListAdd(list, entity);
- }
-
- args->errcode = 0;
-
- return FALSE; // continue iteration
-}
-
-static int __osinfoPopulateList(GTree *entities, OsinfoList *newList, OsinfoFilter *filter, GError **err)
-{
- struct __osinfoPopulateListArgs args = {err, 0, filter, newList};
- g_tree_foreach(entities, __osinfoFilteredAddToList, &args);
- return args.errcode;
-}
-
-OsinfoOsList *osinfoGetOsList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // Create list
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoPopulateList(self->priv->oses, OSINFO_LIST (newList), filter, err);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-OsinfoHypervisorList *osinfoGetHypervisorList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // Create list
- OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoPopulateList(self->priv->hypervisors, OSINFO_LIST (newList), filter, err);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-OsinfoDeviceList *osinfoGetDeviceList(OsinfoDb *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // Create list
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoPopulateList(self->priv->devices, OSINFO_LIST (newList), filter, err);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-gboolean __osinfoGetPropertyValuesInEntity(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoPopulateValuesArgs *args;
- args = (struct __osinfoPopulateValuesArgs *) data;
- GTree *values = args->values;
- GError **err = args->err;
- gchar *property = args->property;
-
- OsinfoEntity *entity = OSINFO_ENTITY (value);
- GPtrArray *valueArray = NULL;
-
- valueArray = g_tree_lookup(entity->priv->params, property);
- if (valueArray)
- return FALSE; // No values here, skip
-
- int i;
- for (i = 0; i < valueArray->len; i++) {
- gchar *currValue = g_ptr_array_index(valueArray, i);
- void *test = g_tree_lookup(values, currValue);
- if (test)
- continue;
- gchar *dupValue = g_strdup(currValue);
- if (!dupValue) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- args->errcode = -ENOMEM;
- return TRUE;
- }
-
- // Add to tree with dummy value
- g_tree_insert(values, dupValue, (gpointer) 1);
- }
-
- return FALSE; // Continue iterating
-}
-
-static gboolean __osinfoPutKeysInList(gpointer key, gpointer value, gpointer data)
-{
- gchar *currValue = (gchar *) key;
- GPtrArray *valuesList = (GPtrArray *) data;
-
- g_ptr_array_add(valuesList, currValue);
- return FALSE; // keep iterating
-}
-
-static gboolean __osinfoFreeKeys(gpointer key, gpointer value, gpointer data)
-{
- g_free(key);
- return FALSE; // keep iterating
-}
-
-static GPtrArray *__osinfoUniqueValuesForPropertyInEntity(GTree *entities, gchar *propName, GError **err)
-{
- GTree *values = g_tree_new(__osinfoStringCompareBase);
- if (!values) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- struct __osinfoPopulateValuesArgs args = {err, 0, values, propName};
- g_tree_foreach(entities, __osinfoGetPropertyValuesInEntity, &args);
-
- if (args.errcode != 0) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
- g_tree_foreach(values, __osinfoFreeKeys, NULL);
- g_tree_destroy(values);
- return NULL;
- }
-
- // For each key in tree, add to gptrarray
- GPtrArray *valuesList = g_ptr_array_sized_new(g_tree_nnodes(values));
- if (!valuesList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- g_tree_foreach(values, __osinfoFreeKeys, NULL);
- g_tree_destroy(values);
- return NULL;
- }
-
- g_tree_foreach(values, __osinfoPutKeysInList, valuesList);
- g_tree_destroy(values);
- return valuesList;
-}
-
-// Get me all unique values for property "vendor" among operating systems
-GPtrArray *osinfoUniqueValuesForPropertyInOs(OsinfoDb *self, gchar *propName, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!propName) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- return __osinfoUniqueValuesForPropertyInEntity(self->priv->oses, propName, err);
-}
-
-// Get me all unique values for property "vendor" among hypervisors
-GPtrArray *osinfoUniqueValuesForPropertyInHv(OsinfoDb *self, gchar *propName, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!propName) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- return __osinfoUniqueValuesForPropertyInEntity(self->priv->hypervisors, propName, err);
-}
-
-// Get me all unique values for property "vendor" among devices
-GPtrArray *osinfoUniqueValuesForPropertyInDev(OsinfoDb *self, gchar *propName, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!propName) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- return __osinfoUniqueValuesForPropertyInEntity(self->priv->devices, propName, err);
-}
-
-static gboolean __osinfoAddOsIfRelationship(gpointer key, gpointer value, gpointer data)
-{
- OsinfoOs *os = (OsinfoOs *) value;
- struct __osinfoOsCheckRelationshipArgs *args;
- args = (struct __osinfoOsCheckRelationshipArgs *) data;
- GError **err = args->err;
- OsinfoList *list = args->list;
-
- GPtrArray *relatedOses = NULL;
- relatedOses = g_tree_lookup(os->priv->relationshipsByType, (gpointer) args->relshp);
- if (relatedOses) {
- __osinfoListAdd(list, OSINFO_ENTITY (os));
- }
-
- return FALSE;
-}
-
-// Get me all OSes that 'upgrade' another OS (or whatever relationship is specified)
-OsinfoOsList *osinfoUniqueValuesForOsRelationship(OsinfoDb *self, osinfoRelationship relshp, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DB(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DB);
- return NULL;
- }
-
- if (!__osinfoCheckRelationshipValid(relshp)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
- return NULL;
- }
-
- // Create list
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- struct __osinfoOsCheckRelationshipArgs args = {OSINFO_LIST (newList), 0, err, relshp};
-
- g_tree_foreach(self->priv->oses, __osinfoAddOsIfRelationship, &args);
- if (args.errcode != 0) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), args.errcode, __osinfoErrorToString(args.errcode));
- g_object_unref(newList);
- return NULL;
- }
-
- return newList;
-}
-
-/** PRIVATE */
-
-void __osinfoAddDeviceToDb(OsinfoDb *db, OsinfoDevice *dev)
-{
- gchar *id;
- g_object_get(G_OBJECT(dev), "id", &id, NULL);
- g_tree_insert(db->priv->devices, id, dev);
-}
-
-void __osinfoAddHypervisorToDb(OsinfoDb *db, OsinfoHypervisor *hv)
-{
- gchar *id;
- g_object_get(G_OBJECT(hv), "id", &id, NULL);
- g_tree_insert(db->priv->hypervisors, id, hv);
-}
-
-void __osinfoAddOsToDb(OsinfoDb *db, OsinfoOs *os)
-{
- gchar *id;
- g_object_get(G_OBJECT(os), "id", &id, NULL);
- g_tree_insert(db->priv->oses, id, os);
-}
diff --git a/src/osinfo_device.c b/src/osinfo_device.c
deleted file mode 100644
index cae6f1b..0000000
--- a/src/osinfo_device.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDevice, osinfo_device, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_DEVICE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICE, OsinfoDevicePrivate))
-
-static void osinfo_device_finalize (GObject *object);
-
-static void
-osinfo_device_finalize (GObject *object)
-{
- OsinfoDevice *self = OSINFO_DEVICE (object);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_device_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_device_class_init (OsinfoDeviceClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_device_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoDevicePrivate));
-}
-
-static void
-osinfo_device_init (OsinfoDevice *self)
-{
- OsinfoDevicePrivate *priv;
- self->priv = priv = OSINFO_DEVICE_GET_PRIVATE(self);
-}
-
-gchar *osinfoGetDeviceDriver(OsinfoDevice *self,
- gchar *devType,
- OsinfoOs *os,
- OsinfoHypervisor *hv,
- GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_DEVICE(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICE);
- return NULL;
- }
-
- if (!OSINFO_IS_OS(os)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
- return NULL;
- }
-
- if (!OSINFO_IS_HYPERVISOR(hv)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
- return NULL;
- }
-
- if (!devType) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
- return NULL;
- }
-
- gchar *driver = NULL;
-
- // For os, get hypervisor specific info. If not present, return NULL.
- struct __osinfoHvSection *hvSection = NULL;
- hvSection = g_tree_lookup(os->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
- if (!hvSection)
- return NULL;
-
- // Check for info for type of devices in <os,hv>. If not found, return NULL.
- GTree *section = NULL;
- section = g_tree_lookup(hvSection->sections, devType);
- if (!section)
- return NULL;
-
- // Check device section for device. If not found, return NULL.
- struct __osinfoDeviceLink *deviceLink = NULL;
- deviceLink = g_tree_lookup(section, (OSINFO_ENTITY(self))->priv->id);
- if (!deviceLink)
- return NULL;
-
- if (!deviceLink->driver)
- return NULL;
-
- driver = g_strdup(deviceLink->driver);
- if (!driver) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- return driver;
-}
diff --git a/src/osinfo_devicelist.c b/src/osinfo_devicelist.c
deleted file mode 100644
index db8a059..0000000
--- a/src/osinfo_devicelist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoDeviceList, osinfo_devicelist, OSINFO_TYPE_LIST);
-
-#define OSINFO_DEVICELIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_DEVICELIST, OsinfoDeviceListPrivate))
-
-static void osinfo_devicelist_finalize (GObject *object);
-
-struct _OsinfoDeviceListPrivate
-{
- int tmp;
-};
-
-static void
-osinfo_devicelist_finalize (GObject *object)
-{
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_devicelist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_devicelist_class_init (OsinfoDeviceListClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_devicelist_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoDeviceListPrivate));
-}
-
-static void
-osinfo_devicelist_init (OsinfoDeviceList *self)
-{
- OsinfoDeviceListPrivate *priv;
- self->priv = priv = OSINFO_DEVICELIST_GET_PRIVATE(self);
-
-}
-
-OsinfoDevice *osinfoGetDeviceAtIndex(OsinfoDeviceList *self, gint idx, GError **err)
-{
- if (!OSINFO_IS_DEVICELIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
- return NULL;
- }
-
- OsinfoList *selfAsList = OSINFO_LIST (self);
- OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
- return OSINFO_DEVICE (entity);
-}
-
-OsinfoDeviceList *osinfoDeviceListFilter(OsinfoDeviceList *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_DEVICELIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // For each element in self, if passes filter, add to new list.
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
- return newList;
-}
-
-OsinfoDeviceList *osinfoDeviceListIntersect(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
-{
- if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
- return NULL;
- }
-
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
-
- ret = __osinfoDoIntersect(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-OsinfoDeviceList *osinfoDeviceListUnion(OsinfoDeviceList *self, OsinfoDeviceList *otherList, GError **err)
-{
- if (!OSINFO_IS_DEVICELIST(self) || !OSINFO_IS_DEVICELIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_DEVICELIST);
- return NULL;
- }
-
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoDoUnion(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
diff --git a/src/osinfo_entity.c b/src/osinfo_entity.c
deleted file mode 100644
index f052277..0000000
--- a/src/osinfo_entity.c
+++ /dev/null
@@ -1,321 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_ABSTRACT_TYPE (OsinfoEntity, osinfo_entity, G_TYPE_OBJECT);
-
-#define OSINFO_ENTITY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_ENTITY, OsinfoEntityPrivate))
-
-static void osinfo_entity_finalize (GObject *object);
-
-enum OSI_ENTITY_PROPERTIES {
- OSI_ENTITY_PROP_0,
-
- OSI_ENTITY_ID,
- OSI_DB_PTR
-};
-
-static void
-osinfo_entity_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- OsinfoEntity *self = OSINFO_ENTITY (object);
-
- switch (property_id)
- {
- case OSI_ENTITY_ID:
- g_free(self->priv->id);
- self->priv->id = g_value_dup_string (value);
- break;
- case OSI_DB_PTR:
- self->priv->db = g_value_get_pointer (value);
- break;
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-osinfo_entity_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- OsinfoEntity *self = OSINFO_ENTITY (object);
-
- switch (property_id)
- {
- case OSI_ENTITY_ID:
- g_value_set_string (value, self->priv->id);
- break;
- case OSI_DB_PTR:
- g_value_set_pointer(value, self->priv->db);
- break;
- default:
- /* We don't have any other property... */
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-osinfo_entity_finalize (GObject *object)
-{
- OsinfoEntity *self = OSINFO_ENTITY (object);
-
- g_free (self->priv->id);
- g_tree_destroy (self->priv->params);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_entity_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_entity_class_init (OsinfoEntityClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- g_klass->set_property = osinfo_entity_set_property;
- g_klass->get_property = osinfo_entity_get_property;
-
- pspec = g_param_spec_string ("id",
- "ID",
- "Contains unique identifier for entity.",
- NULL /* default value */,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
- g_object_class_install_property (g_klass,
- OSI_ENTITY_ID,
- pspec);
- pspec = g_param_spec_pointer ("db",
- "Db pointer",
- "Contains backpointer to libosinfo db object.",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
- g_object_class_install_property (g_klass,
- OSI_DB_PTR,
- pspec);
-
- g_klass->finalize = osinfo_entity_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoEntityPrivate));
-}
-
-static void
-osinfo_entity_init (OsinfoEntity *self)
-{
- OsinfoEntityPrivate *priv;
- self->priv = priv = OSINFO_ENTITY_GET_PRIVATE(self);
-
- self->priv->params = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeParamVals);
-}
-
-int __osinfoAddParam(OsinfoEntity *self, gchar *key, gchar *value)
-{
- if (!OSINFO_IS_ENTITY(self) || !key || !value)
- return -EINVAL;
-
- // First check if there exists an existing array of entries for this key
- // If not, create a ptrarray of strings for this key and insert into map
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *valueArray;
- gchar *valueDup = NULL, *keyDup = NULL;
-
- valueDup = g_strdup(value);
-
- if (!valueDup)
- goto error_free;
-
- found = g_tree_lookup_extended(self->priv->params, key, &origKey, &foundValue);
- if (!found) {
- keyDup = g_strdup(key);
- valueArray = g_ptr_array_new_with_free_func(g_free);
-
- if (!valueArray)
- goto error_free;
- if (!keyDup) {
- g_ptr_array_free(valueArray, TRUE);
- goto error_free;
- }
-
- g_tree_insert(self->priv->params, keyDup, valueArray);
- }
- else
- valueArray = (GPtrArray *) foundValue;
-
- // Add a copy of the value to the array
- g_ptr_array_add(valueArray, valueDup);
- return 0;
-
-error_free:
- g_free(keyDup);
- g_free(valueDup);
- return -ENOMEM;
-}
-
-void __osinfoClearParam(OsinfoEntity *self, gchar *key)
-{
- g_tree_remove(self->priv->params, key);
-}
-
-gboolean __osinfoGetKeys(gpointer key, gpointer value, gpointer data)
-{
- struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
- GPtrArray *results = arrayErr->array;
- gchar *keyDup = g_strdup(key);
-
- if (!keyDup) {
- arrayErr->err = -ENOMEM;
- return TRUE;
- }
- g_ptr_array_add(results, keyDup);
- return FALSE; // Continue iterating
-}
-
-void __osinfoDupArray(gpointer data, gpointer user_data)
-{
- struct __osinfoPtrArrayErr *arrayErr = (struct __osinfoPtrArrayErr *) data;
- GPtrArray *results = arrayErr->array;
-
- if (arrayErr->err != 0)
- return;
-
- gchar *valueDup = g_strdup((gchar *)data);
- if (!valueDup) {
- arrayErr->err = -ENOMEM;
- return;
- }
- g_ptr_array_add(results, valueDup);
-}
-
-gchar *osinfoGetId(OsinfoEntity *self, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_ENTITY(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
- return NULL;
- }
-
- gchar *dupId = g_strdup(self->priv->id);
- if (!dupId) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
- return dupId;
-}
-
-GPtrArray *osinfoGetParams(OsinfoEntity *self, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_ENTITY(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
- return NULL;
- }
-
- GPtrArray *params = g_ptr_array_new();
- if (!params) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- struct __osinfoPtrArrayErr arrayErr = {params, 0};
- g_tree_foreach(self->priv->params, __osinfoGetKeys, &arrayErr);
-
- // If we had an error, cleanup and return NULL
- if (arrayErr.err != 0) {
- int i;
- for (i = 0; i < params->len; i++)
- g_free(g_ptr_array_index(params, i));
- g_ptr_array_free(params, TRUE);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
- return NULL;
- }
-
- return params;
-}
-
-gchar *osinfoGetParamValue(OsinfoEntity *self, gchar *key, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_ENTITY(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
- return NULL;
- }
-
- if (!key) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- gboolean found;
- gpointer origKey, value;
- gchar *firstValueDup;
- GPtrArray *array;
-
- found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
- if (!found)
- return NULL;
- array = (GPtrArray *) value;
- if (array->len == 0)
- return NULL;
-
- firstValueDup = g_strdup(g_ptr_array_index(array, 0));
- if (!firstValueDup) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- return firstValueDup;
-}
-
-GPtrArray *osinfoGetParamAllValues(OsinfoEntity *self, gchar *key, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_ENTITY(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_ENTITY);
- return NULL;
- }
-
- if (!key) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- gboolean found;
- gpointer origKey, value;
- GPtrArray *srcArray, *retArray;
-
- retArray = g_ptr_array_new();
- if (!retArray) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- found = g_tree_lookup_extended(self->priv->params, key, &origKey, &value);
- if (!found)
- return retArray;
- srcArray = (GPtrArray *) value;
- if (srcArray->len == 0)
- return retArray;
-
- struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
- g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
- if (arrayErr.err) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
- g_ptr_array_set_free_func(retArray, g_free);
- g_ptr_array_free(retArray, TRUE);
- return NULL;
- }
-
- return retArray;
-}
diff --git a/src/osinfo_filter.c b/src/osinfo_filter.c
deleted file mode 100644
index fe65e45..0000000
--- a/src/osinfo_filter.c
+++ /dev/null
@@ -1,298 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoFilter, osinfo_filter, G_TYPE_OBJECT);
-
-#define OSINFO_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_FILTER, OsinfoFilterPrivate))
-
-static void osinfo_filter_finalize (GObject *object);
-
-static void
-osinfo_filter_finalize (GObject *object)
-{
- OsinfoFilter *self = OSINFO_FILTER (object);
-
- g_tree_destroy(self->priv->propertyConstraints);
- g_tree_destroy(self->priv->relationshipConstraints);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_filter_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_filter_class_init (OsinfoFilterClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_filter_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoFilterPrivate));
-}
-
-static void
-osinfo_filter_init (OsinfoFilter *self)
-{
- OsinfoFilterPrivate *priv;
- priv = OSINFO_FILTER_GET_PRIVATE(self);
- self->priv = priv;
-
- self->priv->propertyConstraints = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreePtrArray);
-
-
- self->priv->relationshipConstraints = g_tree_new_full(__osinfoIntCompare,
- NULL,
- NULL,
- __osinfoFreePtrArray);
-}
-
-void osinfoFreeFilter(OsinfoFilter *self)
-{
- g_object_unref(self);
-}
-
-gint osinfoAddFilterConstraint(OsinfoFilter *self, gchar *propName, gchar *propVal, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return -EINVAL;
-
- if (!OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return -EINVAL;
- }
-
- if (!propName) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return -EINVAL;
- }
-
- if (!propVal) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPVAL);
- return -EINVAL;
- }
-
- // First check if there exists an array of entries for this key
- // If not, create a ptrarray of strings for this key and insert into map
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *valueArray;
- gchar *valueDup = NULL, *keyDup = NULL;
-
- valueDup = g_strdup(propVal);
-
- if (!valueDup)
- goto error_free;
-
- found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &foundValue);
- if (!found) {
- keyDup = g_strdup(propName);
- valueArray = g_ptr_array_new_with_free_func(g_free);
-
- if (!valueArray)
- goto error_free;
- if (!keyDup) {
- g_ptr_array_free(valueArray, TRUE);
- goto error_free;
- }
-
- g_tree_insert(self->priv->propertyConstraints, keyDup, valueArray);
- }
- else
- valueArray = (GPtrArray *) foundValue;
-
- // Add a copy of the value to the array
- g_ptr_array_add(valueArray, valueDup);
- return 0;
-
-error_free:
- g_free(keyDup);
- g_free(valueDup);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return -ENOMEM;
-}
-
-// Only applicable to OSes, ignored by other types of objects
-gint osinfoAddRelationConstraint(OsinfoFilter *self, osinfoRelationship relshp, OsinfoOs *os, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return -EINVAL;
-
- if (!OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return -EINVAL;
- }
-
- if (!__osinfoCheckRelationshipValid(relshp)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
- return -EINVAL;
- }
-
- if (!OSINFO_IS_OS(os)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
- return -EINVAL;
- }
-
- // First check if there exists an array of entries for this key
- // If not, create a ptrarray of strings for this key and insert into map
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *valueArray;
-
- found = g_tree_lookup_extended(self->priv->relationshipConstraints, (gpointer) relshp, &origKey, &foundValue);
- if (!found) {
- valueArray = g_ptr_array_new();
- if (!valueArray)
- goto error_nomem;
-
- g_tree_insert(self->priv->relationshipConstraints, (gpointer) relshp, valueArray);
- }
- else
- valueArray = (GPtrArray *) foundValue;
-
- // Add to the array
- g_ptr_array_add(valueArray, os);
- return 0;
-
-error_nomem:
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return -ENOMEM;
-}
-
-void osinfoClearFilterConstraint(OsinfoFilter *self, gchar *propName)
-{
- g_tree_remove(self->priv->propertyConstraints, propName);
-}
-
-void osinfoClearRelationshipConstraint(OsinfoFilter *self, osinfoRelationship relshp)
-{
- g_tree_remove(self->priv->relationshipConstraints, (gpointer) relshp);
-}
-
-static gboolean __osinfoRemoveTreeEntry(gpointer key, gpointer value, gpointer data)
-{
- GTree *tree = (GTree *) data;
- g_tree_remove(tree, key);
- return FALSE; // continue iterating
-}
-
-void osinfoClearAllFilterConstraints(OsinfoFilter *self)
-{
- g_tree_foreach(self->priv->propertyConstraints, __osinfoRemoveTreeEntry, self->priv->propertyConstraints);
- g_tree_foreach(self->priv->relationshipConstraints, __osinfoRemoveTreeEntry, self->priv->relationshipConstraints);
-}
-
-// get keyset for constraints map
-GPtrArray *osinfoGetFilterConstraintKeys(OsinfoFilter *self, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- GPtrArray *constraints = g_ptr_array_new();
- if (!constraints) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- struct __osinfoPtrArrayErr arrayErr = {constraints, 0};
- g_tree_foreach(self->priv->propertyConstraints, __osinfoGetKeys, &arrayErr);
-
- // If we had an error, cleanup and return NULL
- if (arrayErr.err != 0) {
- int i;
- for (i = 0; i < constraints->len; i++)
- g_free(g_ptr_array_index(constraints, i));
- g_ptr_array_free(constraints, TRUE);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
- return NULL;
- }
-
- return constraints;
-}
-
-// get values for given key
-GPtrArray *osinfoGetFilterConstraintValues(OsinfoFilter *self, gchar *propName, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- if (!propName) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_PROPNAME);
- return NULL;
- }
-
- gboolean found;
- gpointer origKey, value;
- GPtrArray *srcArray, *retArray;
-
- retArray = g_ptr_array_new();
- if (!retArray) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- found = g_tree_lookup_extended(self->priv->propertyConstraints, propName, &origKey, &value);
- if (!found)
- return retArray;
- srcArray = (GPtrArray *) value;
- if (srcArray->len == 0)
- return retArray;
-
- struct __osinfoPtrArrayErr arrayErr = {retArray, 0};
- g_ptr_array_foreach(srcArray, __osinfoDupArray, &arrayErr);
- if (arrayErr.err) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), arrayErr.err, __osinfoErrorToString(arrayErr.err));
- g_ptr_array_set_free_func(retArray, g_free);
- g_ptr_array_free(retArray, TRUE);
- return NULL;
- }
-
- return retArray;
-}
-
-// get oses for given relshp
-OsinfoOsList *osinfoGetRelationshipConstraintValue(OsinfoFilter *self, osinfoRelationship relshp, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- if (!__osinfoCheckRelationshipValid(relshp)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
- return NULL;
- }
-
- // Create our list
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- GPtrArray *relatedOses = NULL;
- relatedOses = g_tree_lookup(self->priv->relationshipConstraints, (gpointer) relshp);
- if (relatedOses) {
- int i, len;
- len = relatedOses->len;
- for (i = 0; i < len; i++) {
- OsinfoOs *os = g_ptr_array_index(relatedOses, i);
- __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (os));
- }
- }
-
- return newList;
-}
diff --git a/src/osinfo_hypervisor.c b/src/osinfo_hypervisor.c
deleted file mode 100644
index 30eb445..0000000
--- a/src/osinfo_hypervisor.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoHypervisor, osinfo_hypervisor, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_HYPERVISOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISOR, OsinfoHypervisorPrivate))
-
-static void osinfo_hypervisor_finalize (GObject *object);
-
-static void
-osinfo_hypervisor_finalize (GObject *object)
-{
- OsinfoHypervisor *self = OSINFO_HYPERVISOR (object);
-
- g_tree_destroy (self->priv->sections);
- g_tree_destroy (self->priv->sectionsAsList);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_hypervisor_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_hypervisor_class_init (OsinfoHypervisorClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_hypervisor_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoHypervisorPrivate));
-}
-
-static void
-osinfo_hypervisor_init (OsinfoHypervisor *self)
-{
- OsinfoHypervisorPrivate *priv;
- self->priv = priv = OSINFO_HYPERVISOR_GET_PRIVATE(self);
-
- self->priv->sections = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceSection);
- self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreePtrArray);
-}
-
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver)
-{
- if( !OSINFO_IS_HYPERVISOR(self) || !section || !id || !driver)
- return -EINVAL;
-
- return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section)
-{
- if (!OSINFO_IS_HYPERVISOR(self) || !section)
- return;
-
- __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
-
-GPtrArray *osinfoGetHypervisorDeviceTypes(OsinfoHypervisor *self, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_HYPERVISOR(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
- return NULL;
- }
-
- GPtrArray *deviceTypes = g_ptr_array_sized_new(g_tree_nnodes(self->priv->sections));
- if (!deviceTypes) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- // For each key in our tree of device sections, dup and add to the array
- struct __osinfoPtrArrayErr arrayErr = {deviceTypes, 0};
- g_tree_foreach(self->priv->sections, __osinfoGetKeys, &arrayErr);
- return deviceTypes;
-}
-
-OsinfoDeviceList *osinfoGetHypervisorDevicesByType(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_HYPERVISOR(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- if (!devType) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
- return NULL;
- }
-
- // Create our device list
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- // If section does not exist, return empty list
- GPtrArray *sectionList = NULL;
- sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
- if (!sectionList)
- return newList;
-
- // For each device in section list, apply filter. If filter passes, add device to list.
- int i;
- struct __osinfoDeviceLink *deviceLink;
- for (i = 0; i < sectionList->len; i++) {
- deviceLink = g_ptr_array_index(sectionList, i);
- if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
- __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
- }
-
- return newList;
-}
diff --git a/src/osinfo_hypervisorlist.c b/src/osinfo_hypervisorlist.c
deleted file mode 100644
index be42df7..0000000
--- a/src/osinfo_hypervisorlist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoHypervisorList, osinfo_hypervisorlist, OSINFO_TYPE_LIST);
-
-#define OSINFO_HYPERVISORLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_HYPERVISORLIST, OsinfoHypervisorListPrivate))
-
-static void osinfo_hypervisorlist_finalize (GObject *object);
-
-struct _OsinfoHypervisorListPrivate
-{
- int tmp;
-};
-
-static void
-osinfo_hypervisorlist_finalize (GObject *object)
-{
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_hypervisorlist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_hypervisorlist_class_init (OsinfoHypervisorListClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_hypervisorlist_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoHypervisorListPrivate));
-}
-
-static void
-osinfo_hypervisorlist_init (OsinfoHypervisorList *self)
-{
- OsinfoHypervisorListPrivate *priv;
- self->priv = priv = OSINFO_HYPERVISORLIST_GET_PRIVATE(self);
-
-}
-
-OsinfoHypervisor *osinfoGetHypervisorAtIndex(OsinfoHypervisorList *self, gint idx, GError **err)
-{
- if (!OSINFO_IS_HYPERVISORLIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
- return NULL;
- }
-
- OsinfoList *selfAsList = OSINFO_LIST (self);
- OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
- return OSINFO_HYPERVISOR (entity);
-}
-
-OsinfoHypervisorList *osinfoHypervisorListFilter(OsinfoHypervisorList *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_HYPERVISORLIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // For each element in self, if passes filter, add to new list.
- OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
- return newList;
-}
-
-OsinfoHypervisorList *osinfoHypervisorListIntersect(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
-{
- if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
- return NULL;
- }
-
- OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
-
- ret = __osinfoDoIntersect(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-OsinfoHypervisorList *osinfoHypervisorListUnion(OsinfoHypervisorList *self, OsinfoHypervisorList *otherList, GError **err)
-{
- if (!OSINFO_IS_HYPERVISORLIST(self) || !OSINFO_IS_HYPERVISORLIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HYPERVISORLIST);
- return NULL;
- }
-
- OsinfoHypervisorList *newList = g_object_new(OSINFO_TYPE_HYPERVISORLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoDoUnion(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
diff --git a/src/osinfo_list.c b/src/osinfo_list.c
deleted file mode 100644
index 964e01d..0000000
--- a/src/osinfo_list.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoList, osinfo_list, G_TYPE_OBJECT);
-
-#define OSINFO_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_LIST, OsinfoListPrivate))
-
-static void osinfo_list_finalize (GObject *object);
-
-struct _OsinfoListPrivate
-{
- GPtrArray *array;
-};
-
-static void
-osinfo_list_finalize (GObject *object)
-{
- OsinfoList *self = OSINFO_LIST (object);
-
- g_ptr_array_free(self->priv->array, TRUE);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_list_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_list_class_init (OsinfoListClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_list_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoListPrivate));
-}
-
-static void
-osinfo_list_init (OsinfoList *self)
-{
- OsinfoListPrivate *priv;
- self->priv = priv = OSINFO_LIST_GET_PRIVATE(self);
-
- self->priv->array = g_ptr_array_new();
-}
-
-void osinfoFreeList(OsinfoList *self)
-{
- g_object_unref(self);
-}
-
-gint osinfoListLength(OsinfoList *self)
-{
- return self->priv->array->len;
-}
-
-OsinfoEntity *osinfoGetEntityAtIndex(OsinfoList *self, gint idx)
-{
- return g_ptr_array_index(self->priv->array, idx);
-}
-
-void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity)
-{
- g_ptr_array_add(self->priv->array, entity);
-}
-
-void __osinfoDoFilter(OsinfoList *src, OsinfoList *dst, OsinfoFilter *filter)
-{
- int i, len;
- len = osinfoListLength(src);
- for (i = 0; i < len; i++) {
- OsinfoEntity *entity = osinfoGetEntityAtIndex(src, i);
- if (__osinfoEntityPassesFilter(filter, entity))
- __osinfoListAdd(dst, entity);
- }
-}
-
-OsinfoList *osinfoListFilter(OsinfoList *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_LIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // For each element in self, if passes filter, add to new list.
- OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- __osinfoDoFilter(self, newList, filter);
- return newList;
-}
-
-int __osinfoDoIntersect(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
-{
- int i, len;
-
- // Make set representation of otherList and newList
- GTree *otherSet = g_tree_new(__osinfoStringCompareBase);
- if (!otherSet)
- return -ENOMEM;
-
- GTree *newSet = g_tree_new(__osinfoStringCompareBase);
- if (!newSet) {
- g_tree_destroy(otherSet);
- return -ENOMEM;
- }
-
- // Add all from otherList to otherSet
- len = osinfoListLength(src2);
- for (i = 0; i < len; i++) {
- OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
- gchar *id = entity->priv->id;
- g_tree_insert(otherSet, id, entity);
- }
-
- // If other contains entity, and new list does not, add to new list
- len = osinfoListLength(src1);
- for (i = 0; i < len; i++) {
- OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
- gchar *id = entity->priv->id;
-
- if (g_tree_lookup(otherSet, entity->priv->id) &&
- !g_tree_lookup(newSet, entity->priv->id)) {
- g_tree_insert(newSet, id, entity);
- __osinfoListAdd(dst, entity);
- }
- }
-
- g_tree_destroy(otherSet);
- g_tree_destroy(newSet);
- return 0;
-}
-
-OsinfoList *osinfoListIntersect(OsinfoList *self, OsinfoList *otherList, GError **err)
-{
- if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
- return NULL;
- }
-
- OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
-
- ret = __osinfoDoIntersect(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-int __osinfoDoUnion(OsinfoList *src1, OsinfoList *src2, OsinfoList *dst)
-{
- // Make set version of new list
- GTree *newSet = g_tree_new(__osinfoStringCompareBase);
- if (!newSet)
- return -ENOMEM;
-
- // Add all from other list to new list
- int i, len;
- len = osinfoListLength(src2);
- for (i = 0; i < len; i++) {
- OsinfoEntity *entity = osinfoGetEntityAtIndex(src2, i);
- gchar *id = entity->priv->id;
- __osinfoListAdd(dst, entity);
- g_tree_insert(newSet, id, entity);
- }
-
- // Add remaining elements from this list to new list
- len = osinfoListLength(src1);
- for (i = 0; i < len; i++) {
- OsinfoEntity *entity = osinfoGetEntityAtIndex(src1, i);
- gchar *id = entity->priv->id;
- // If new list does not contain element, add to new list
- if (!g_tree_lookup(newSet, id)) {
- __osinfoListAdd(dst, entity);
- g_tree_insert(newSet, id, entity);
- }
- }
-
- g_tree_destroy(newSet);
- return 0;
-}
-
-OsinfoList *osinfoListUnion(OsinfoList *self, OsinfoList *otherList, GError **err)
-{
- if (!OSINFO_IS_LIST(self) || !OSINFO_IS_LIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_LIST);
- return NULL;
- }
-
- OsinfoList *newList = g_object_new(OSINFO_TYPE_LIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoDoUnion(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
diff --git a/src/osinfo_os.c b/src/osinfo_os.c
deleted file mode 100644
index db02271..0000000
--- a/src/osinfo_os.c
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoOs, osinfo_os, OSINFO_TYPE_ENTITY);
-
-#define OSINFO_OS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OS, OsinfoOsPrivate))
-
-static void osinfo_os_finalize (GObject *object);
-
-static void
-osinfo_os_finalize (GObject *object)
-{
- OsinfoOs *self = OSINFO_OS (object);
-
- g_tree_destroy (self->priv->sections);
- g_tree_destroy (self->priv->sectionsAsList);
- g_tree_destroy (self->priv->hypervisors);
- g_tree_destroy (self->priv->relationshipsByOs);
- g_tree_destroy (self->priv->relationshipsByType);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_os_class_init (OsinfoOsClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_os_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoOsPrivate));
-}
-
-static void
-osinfo_os_init (OsinfoOs *self)
-{
- OsinfoOsPrivate *priv;
- self->priv = priv = OSINFO_OS_GET_PRIVATE(self);
-
- self->priv->sections = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreeDeviceSection);
-
- self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreePtrArray);
-
- self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreeRelationship);
- self->priv->relationshipsByType = g_tree_new(__osinfoIntCompareBase);
-
- self->priv->hypervisors = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreeHvSection);
-}
-
-static int __osinfoAddOsRelationshipByOs(OsinfoOs *self,
- gchar *otherOsId,
- osinfoRelationship rel,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForOs;
- gchar *otherOsIdDup = NULL;
-
- found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
- if (!found) {
- otherOsIdDup = g_strdup(otherOsId);
- relationshipsForOs = g_ptr_array_new_with_free_func(__osinfoFreeOsLink);
-
- if (!relationshipsForOs)
- return -ENOMEM;
- if (!otherOsIdDup) {
- g_ptr_array_free(relationshipsForOs, TRUE);
- return -ENOMEM;
- }
- g_tree_insert(self->priv->relationshipsByOs, otherOsIdDup, relationshipsForOs);
- }
- else
- relationshipsForOs = (GPtrArray *) foundValue;
-
- g_ptr_array_add(relationshipsForOs, osLink);
- return 0;
-}
-
-static int __osinfoAddOsRelationshipByType(OsinfoOs *self,
- osinfoRelationship relshp,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForType;
-
- found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
- if (!found) {
- relationshipsForType = g_ptr_array_new();
- if (!relationshipsForType)
- return -ENOMEM;
-
- g_tree_insert(self->priv->relationshipsByType, (gpointer) relshp, relationshipsForType);
- }
- else
- relationshipsForType = (GPtrArray *) foundValue;
-
- g_ptr_array_add(relationshipsForType, osLink);
- return 0;
-}
-
-static void __osinfoRemoveOsLink(OsinfoOs *self,
- gchar *otherOsId,
- osinfoRelationship relshp,
- struct __osinfoOsLink *osLink)
-{
- gboolean found;
- gpointer origKey, foundValue;
- GPtrArray *relationshipsForOs;
- GPtrArray *relationshipsForType;
-
- // First from by-os list
- found = g_tree_lookup_extended(self->priv->relationshipsByOs, otherOsId, &origKey, &foundValue);
- if (found) {
- relationshipsForOs = (GPtrArray *) foundValue;
- g_ptr_array_remove(relationshipsForOs, osLink);
- }
-
- // Now from by-relshp list
- found = g_tree_lookup_extended(self->priv->relationshipsByType, (gpointer) relshp, &origKey, &foundValue);
- if (found) {
- relationshipsForType = (GPtrArray *) foundValue;
- g_ptr_array_remove(relationshipsForType, osLink);
- }
-}
-
-int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel)
-{
- if ( !OSINFO_IS_OS(self) || !otherOsId)
- return -EINVAL;
-
- struct __osinfoOsLink *osLink = NULL;
- osLink = g_malloc(sizeof(*osLink));
- if (!osLink)
- return -ENOMEM;
-
- osLink->subjectOs = self;
- osLink->verb = rel;
-
- int ret;
- ret = __osinfoAddOsRelationshipByOs(self, otherOsId, rel, osLink);
- if (ret != 0)
- goto error_free;
-
- ret = __osinfoAddOsRelationshipByType(self, rel, osLink);
- if (ret != 0)
- goto error_cleanup;
-
- return ret;
-
-error_cleanup:
- __osinfoRemoveOsLink(self, otherOsId, rel, osLink);
-error_free:
- g_free(osLink);
- return ret;
-}
-
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver)
-{
- if( !OSINFO_IS_OS(self) || !section || !id || !driver)
- return -EINVAL;
-
- return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section)
-{
- if (!OSINFO_IS_OS(self) || !section)
- return;
-
- __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
-
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId)
-{
- if (!OSINFO_IS_OS(self) || !hvId)
- return NULL;
-
- gboolean found;
- gpointer origKey, foundValue;
- struct __osinfoHvSection *hvSection = NULL;
- gchar *hvIdDup = NULL;
- GTree *deviceSections;
- GTree *deviceSectionsAsList;
-
- found = g_tree_lookup_extended(self->priv->hypervisors, hvId, &origKey, &foundValue);
- if (!found) {
- hvSection = g_malloc(sizeof(*hvSection));
- hvIdDup = g_strdup(hvId);
- deviceSections = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreeDeviceSection);
-
- if (!deviceSections)
- goto error_free;
-
- deviceSectionsAsList = g_tree_new_full(__osinfoStringCompare,
- NULL,
- g_free,
- __osinfoFreePtrArray);
- if (!deviceSectionsAsList) {
- g_tree_destroy(deviceSections);
- goto error_free;
- }
-
- if (!hvSection || !hvIdDup) {
- g_tree_destroy(deviceSectionsAsList);
- g_tree_destroy(deviceSections);
- goto error_free;
- }
-
- hvSection->os = self;
- // Will set hv link later
- hvSection->sections = deviceSections;
- hvSection->sectionsAsList = deviceSectionsAsList;
-
- g_tree_insert(self->priv->hypervisors, hvIdDup, hvSection);
- return hvSection;
- }
- else
- return (struct __osinfoHvSection *) foundValue;
-
-error_free:
- g_free(hvSection);
- g_free(hvIdDup);
- return NULL;
-}
-
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId)
-{
- g_tree_remove(self->priv->hypervisors, hvId);
-}
-
-OsinfoDevice *osinfoGetPreferredDeviceForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_OS(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
- return NULL;
- }
-
- if (hv && !OSINFO_IS_HYPERVISOR(hv)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
- return NULL;
- }
-
- if (!devType) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // Check if device type info present for <os,hv>, else return NULL.
-
- GPtrArray *sectionList = NULL;
- if (hv) {
- // Check if hypervisor specific info present for Os, else return NULL.
- struct __osinfoHvSection *hvSection = NULL;
- hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
- if (!hvSection)
- return NULL;
-
- sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
- if (!sectionList)
- return NULL;
- }
- else {
- sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
- if (!sectionList)
- return NULL;
- }
-
- // For each device in section list, apply filter. If filter passes, return device.
- int i;
- struct __osinfoDeviceLink *deviceLink;
- for (i = 0; i < sectionList->len; i++) {
- deviceLink = g_ptr_array_index(sectionList, i);
- if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
- return deviceLink->dev;
- }
-
- // If no devices pass filter, return NULL.
- return NULL;
-}
-
-OsinfoOsList *osinfoGetRelatedOs(OsinfoOs *self, osinfoRelationship relshp, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_OS(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
- return NULL;
- }
-
- if (!__osinfoCheckRelationshipValid(relshp)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_INVALID_RELATIONSHIP);
- return NULL;
- }
-
- // Create our list
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- GPtrArray *relatedOses = NULL;
- relatedOses = g_tree_lookup(self->priv->relationshipsByType, (gpointer) relshp);
- if (relatedOses) {
- int i, len;
- len = relatedOses->len;
- for (i = 0; i < len; i++) {
- struct __osinfoOsLink *osLink = g_ptr_array_index(relatedOses, i);
- __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (osLink->directObjectOs));
- }
- }
-
- return newList;
-}
-
-OsinfoDeviceList *osinfoGetDevicesForOs(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter, GError **err)
-{
- if (!__osinfoCheckGErrorParamValid(err))
- return NULL;
-
- if (!OSINFO_IS_OS(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OS);
- return NULL;
- }
-
- if (!OSINFO_IS_HYPERVISOR(hv)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_HV);
- return NULL;
- }
-
- if (!devType) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_NO_DEVTYPE);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(filter)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- GPtrArray *sectionList = NULL;
-
- // Create our device list
- OsinfoDeviceList *newList = g_object_new(OSINFO_TYPE_DEVICELIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- if (hv) {
- struct __osinfoHvSection *hvSection = NULL;
- hvSection = g_tree_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
- if (!hvSection)
- return newList;
-
- sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
- if (!sectionList)
- return newList;
- }
- else {
- sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
- if (!sectionList)
- return newList;
- }
-
- // For each device in section list, apply filter. If filter passes, add device to list.
- int i;
- struct __osinfoDeviceLink *deviceLink;
- for (i = 0; i < sectionList->len; i++) {
- deviceLink = g_ptr_array_index(sectionList, i);
- if (__osinfoDevicePassesFilter(filter, deviceLink->dev))
- __osinfoListAdd(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
- }
-
- return NULL;
-}
diff --git a/src/osinfo_oslist.c b/src/osinfo_oslist.c
deleted file mode 100644
index d723703..0000000
--- a/src/osinfo_oslist.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <osinfo.h>
-
-G_DEFINE_TYPE (OsinfoOsList, osinfo_oslist, OSINFO_TYPE_LIST);
-
-#define OSINFO_OSLIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), OSINFO_TYPE_OSLIST, OsinfoOsListPrivate))
-
-static void osinfo_oslist_finalize (GObject *object);
-
-struct _OsinfoOsListPrivate
-{
- int tmp;
-};
-
-static void
-osinfo_oslist_finalize (GObject *object)
-{
- /* Chain up to the parent class */
- G_OBJECT_CLASS (osinfo_oslist_parent_class)->finalize (object);
-}
-
-/* Init functions */
-static void
-osinfo_oslist_class_init (OsinfoOsListClass *klass)
-{
- GObjectClass *g_klass = G_OBJECT_CLASS (klass);
-
- g_klass->finalize = osinfo_oslist_finalize;
- g_type_class_add_private (klass, sizeof (OsinfoOsListPrivate));
-}
-
-static void
-osinfo_oslist_init (OsinfoOsList *self)
-{
- OsinfoOsListPrivate *priv;
- self->priv = priv = OSINFO_OSLIST_GET_PRIVATE(self);
-
-}
-
-OsinfoOs *osinfoGetOsAtIndex(OsinfoOsList *self, gint idx, GError **err)
-{
- if (!OSINFO_IS_OSLIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
- return NULL;
- }
-
- OsinfoList *selfAsList = OSINFO_LIST (self);
- OsinfoEntity *entity = osinfoGetEntityAtIndex(selfAsList, idx);
- return OSINFO_OS (entity);
-}
-
-OsinfoOsList *osinfoOsListFilter(OsinfoOsList *self, OsinfoFilter *filter, GError **err)
-{
- if (!OSINFO_IS_OSLIST(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
- return NULL;
- }
-
- if (filter && !OSINFO_IS_FILTER(self)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_FILTER);
- return NULL;
- }
-
- // For each element in self, if passes filter, add to new list.
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- __osinfoDoFilter(OSINFO_LIST (self), OSINFO_LIST (newList), filter);
- return newList;
-}
-
-OsinfoOsList *osinfoOsListIntersect(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
-{
- if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
- return NULL;
- }
-
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
-
- ret = __osinfoDoIntersect(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
-
-OsinfoOsList *osinfoOsListUnion(OsinfoOsList *self, OsinfoOsList *otherList, GError **err)
-{
- if (!OSINFO_IS_OSLIST(self) || !OSINFO_IS_OSLIST(otherList)) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -EINVAL, OSINFO_OBJ_NOT_OSLIST);
- return NULL;
- }
-
- OsinfoOsList *newList = g_object_new(OSINFO_TYPE_OSLIST, NULL);
- if (!newList) {
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), -ENOMEM, OSINFO_NO_MEM);
- return NULL;
- }
-
- int ret;
- ret = __osinfoDoUnion(self, otherList, newList);
- if (ret != 0) {
- g_object_unref(newList);
- g_set_error_literal(err, g_quark_from_static_string("libosinfo"), ret, __osinfoErrorToString(ret));
- return NULL;
- }
-
- return newList;
-}
--
1.7.2.1
More information about the virt-tools-list
mailing list