[gupnp/wip/phako/initable: 3/4] ServiceIntrospection: Implement GInitable
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp/wip/phako/initable: 3/4] ServiceIntrospection: Implement GInitable
- Date: Fri, 29 Oct 2021 16:37:23 +0000 (UTC)
commit 544d8d1a0be65f748daff380bebc3bf6ad586b56
Author: Jens Georg <mail jensge org>
Date: Sun Oct 24 22:29:20 2021 +0200
ServiceIntrospection: Implement GInitable
Fixes #53
libgupnp/gupnp-error.c | 19 +++++
libgupnp/gupnp-error.h | 14 ++++
libgupnp/gupnp-service-info.c | 2 +-
libgupnp/gupnp-service-introspection-private.h | 2 +-
libgupnp/gupnp-service-introspection.c | 110 ++++++++++++++++++-------
5 files changed, 113 insertions(+), 34 deletions(-)
---
diff --git a/libgupnp/gupnp-error.c b/libgupnp/gupnp-error.c
index 7dcf5db..d93dfe0 100644
--- a/libgupnp/gupnp-error.c
+++ b/libgupnp/gupnp-error.c
@@ -107,6 +107,25 @@ gupnp_rootdevice_error_quark (void)
return quark;
}
+/**
+ * GUPNP_SERVICE_INTROSPECTION_ERROR:
+ *
+ * The #GQuark uniquely used by GUPnP ServiceIntrospection errors.
+ *
+ * Returns: a #GQuark uniquely used by GUPnP ServiceIntrospection creation errors.
+ */
+GQuark
+gupnp_service_introspection_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (!quark)
+ quark = g_quark_from_static_string ("gupnp-root-device-error");
+
+ return quark;
+}
+
+
/* Soup status code => GUPnPServerError */
static int
code_from_status_code (int status_code)
diff --git a/libgupnp/gupnp-error.h b/libgupnp/gupnp-error.h
index cd26e04..d3a7a43 100644
--- a/libgupnp/gupnp-error.h
+++ b/libgupnp/gupnp-error.h
@@ -127,6 +127,20 @@ typedef enum {
GUPNP_ROOT_DEVICE_ERROR_FAIL
} GUPnPRootdeviceError;
+GQuark
+gupnp_service_introspection_error_quark (void) G_GNUC_CONST;
+
+#define GUPNP_SERVICE_INTROSPECTION_ERROR \
+ (gupnp_service_introspection_error_quark ())
+
+/**
+ * GUPnPServiceIntrospectionError:
+ * @GUPNP_SERVICE_INTROSPECTION_ERROR_OTHER@: Unknown error
+ */
+typedef enum
+{
+ GUPNP_SERVICE_INTROSPECTION_ERROR_OTHER,
+} GUPnPServiceIntrospectionError;
G_END_DECLS
#endif /* GUPNP_ERROR_H */
diff --git a/libgupnp/gupnp-service-info.c b/libgupnp/gupnp-service-info.c
index 9a9f4de..1194268 100644
--- a/libgupnp/gupnp-service-info.c
+++ b/libgupnp/gupnp-service-info.c
@@ -595,7 +595,7 @@ got_scpd_url (G_GNUC_UNUSED SoupSession *session,
scpd = xmlRecoverMemory (msg->response_body->data,
msg->response_body->length);
if (scpd) {
- introspection = gupnp_service_introspection_new (scpd);
+ introspection = gupnp_service_introspection_new (scpd, NULL);
xmlFreeDoc (scpd);
}
diff --git a/libgupnp/gupnp-service-introspection-private.h b/libgupnp/gupnp-service-introspection-private.h
index 63741ca..0e73a98 100644
--- a/libgupnp/gupnp-service-introspection-private.h
+++ b/libgupnp/gupnp-service-introspection-private.h
@@ -14,6 +14,6 @@
#include "gupnp-service-introspection.h"
G_GNUC_INTERNAL GUPnPServiceIntrospection *
-gupnp_service_introspection_new (xmlDoc *scpd);
+gupnp_service_introspection_new (xmlDoc *scpd, GError **error);
#endif /* GUPNP_SERVICE_INTROSPECTION_PRIVATE_H */
diff --git a/libgupnp/gupnp-service-introspection.c b/libgupnp/gupnp-service-introspection.c
index a614b7f..68f09d7 100644
--- a/libgupnp/gupnp-service-introspection.c
+++ b/libgupnp/gupnp-service-introspection.c
@@ -37,6 +37,7 @@
#include "gupnp-service-introspection.h"
#include "gupnp-service-introspection-private.h"
+#include "gupnp-error.h"
#include "xml-util.h"
#include "gvalue-util.h"
#include "gupnp-types.h"
@@ -49,6 +50,7 @@ struct _GUPnPServiceIntrospection {
};
struct _GUPnPServiceIntrospectionPrivate {
+ xmlDoc *scpd;
GList *variables;
GList *actions;
@@ -60,17 +62,27 @@ struct _GUPnPServiceIntrospectionPrivate {
typedef struct _GUPnPServiceIntrospectionPrivate
GUPnPServiceIntrospectionPrivate;
-G_DEFINE_TYPE_WITH_PRIVATE (GUPnPServiceIntrospection,
- gupnp_service_introspection,
- G_TYPE_OBJECT)
+
+static GInitableIface *initable_parent_iface = NULL;
+static void
+gupnp_service_introspection_initable_iface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_EXTENDED (
+ GUPnPServiceIntrospection,
+ gupnp_service_introspection,
+ G_TYPE_OBJECT,
+ 0,
+ G_ADD_PRIVATE (GUPnPServiceIntrospection) G_IMPLEMENT_INTERFACE (
+ G_TYPE_INITABLE,
+ gupnp_service_introspection_initable_iface_init))
enum {
PROP_0,
PROP_SCPD
};
-static void
+static gboolean
construct_introspection_info (GUPnPServiceIntrospection *introspection,
- xmlDoc *scpd);
+ GError **error);
/**
* gupnp_service_state_variable_info_free:
@@ -123,12 +135,12 @@ gupnp_service_introspection_set_property (GObject *object,
GUPnPServiceIntrospection *introspection;
introspection = GUPNP_SERVICE_INTROSPECTION (object);
+ GUPnPServiceIntrospectionPrivate *priv =
+ gupnp_service_introspection_get_instance_private (introspection);
switch (property_id) {
case PROP_SCPD:
- /* Construct introspection data */
- construct_introspection_info (introspection,
- g_value_get_pointer (value));
+ priv->scpd = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -220,6 +232,42 @@ gupnp_service_introspection_finalize (GObject *object)
g_list_free (priv->action_names);
}
+static gboolean
+gupnp_service_introspection_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GUPnPServiceIntrospection *self =
+ GUPNP_SERVICE_INTROSPECTION (initable);
+ GUPnPServiceIntrospectionPrivate *priv =
+ gupnp_service_introspection_get_instance_private (self);
+
+ if (priv->scpd == NULL) {
+ g_set_error_literal (
+ error,
+ GUPNP_SERVICE_INTROSPECTION_ERROR,
+ GUPNP_SERVICE_INTROSPECTION_ERROR_OTHER,
+ "SCDP is required for creating a ServiceIntrospection");
+
+ return FALSE;
+ }
+
+ if (priv->actions != NULL || priv->variables != NULL)
+ return TRUE;
+
+ return construct_introspection_info (self, error);
+}
+
+static void
+gupnp_service_introspection_initable_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GInitableIface *iface = (GInitableIface *) g_iface;
+ initable_parent_iface = g_type_interface_peek_parent (iface);
+ iface->init = gupnp_service_introspection_initable_init;
+}
+
+
static void
gupnp_service_introspection_class_init (GUPnPServiceIntrospectionClass *klass)
{
@@ -687,19 +735,16 @@ get_state_variables (xmlNode *list_element)
* Creates the #GHashTable's of action and state variable information
*
* */
-static void
+static gboolean
construct_introspection_info (GUPnPServiceIntrospection *introspection,
- xmlDoc *scpd)
+ GError **error)
{
xmlNode *element;
GUPnPServiceIntrospectionPrivate *priv;
- g_return_if_fail (scpd != NULL);
-
priv = gupnp_service_introspection_get_instance_private (introspection);
-
/* Get actionList element */
- element = xml_util_get_element ((xmlNode *) scpd,
+ element = xml_util_get_element ((xmlNode *) priv->scpd,
"scpd",
"actionList",
NULL);
@@ -707,12 +752,23 @@ construct_introspection_info (GUPnPServiceIntrospection *introspection,
priv->actions = get_actions (element);
/* Get serviceStateTable element */
- element = xml_util_get_element ((xmlNode *) scpd,
+ element = xml_util_get_element ((xmlNode *) priv->scpd,
"scpd",
"serviceStateTable",
NULL);
if (element)
priv->variables = get_state_variables (element);
+
+ if (priv->actions == NULL && priv->variables == NULL) {
+ g_set_error_literal (error,
+ GUPNP_SERVICE_INTROSPECTION_ERROR,
+ GUPNP_SERVICE_INTROSPECTION_ERROR_OTHER,
+ "Service description has neither actions "
+ "nor variables");
+ return FALSE;
+ }
+
+ return TRUE;
}
static void
@@ -746,26 +802,16 @@ collect_variable_names (gpointer data,
* Return value: A new #GUPnPServiceIntrospection.
**/
GUPnPServiceIntrospection *
-gupnp_service_introspection_new (xmlDoc *scpd)
+gupnp_service_introspection_new (xmlDoc *scpd, GError **error)
{
- GUPnPServiceIntrospection *introspection;
- GUPnPServiceIntrospectionPrivate *priv;
-
g_return_val_if_fail (scpd != NULL, NULL);
- introspection = g_object_new (GUPNP_TYPE_SERVICE_INTROSPECTION,
- "scpd", scpd,
- NULL);
-
- priv = gupnp_service_introspection_get_instance_private (introspection);
-
- if (priv->actions == NULL &&
- priv->variables == NULL) {
- g_object_unref (introspection);
- introspection = NULL;
- }
-
- return introspection;
+ return g_initable_new (GUPNP_TYPE_SERVICE_INTROSPECTION,
+ NULL,
+ error,
+ "scpd",
+ scpd,
+ NULL);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]