[gupnp: 12/18] Make GUPnPRootDevice implement GInitable
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp: 12/18] Make GUPnPRootDevice implement GInitable
- Date: Sat, 15 Oct 2016 19:41:29 +0000 (UTC)
commit 638c77aa22ed9d59ff91f64f51d0eb57f225e558
Author: Jens Georg <mail jensge org>
Date: Sat Jul 30 13:51:49 2011 +0200
Make GUPnPRootDevice implement GInitable
https://bugzilla.gnome.org/show_bug.cgi?id=654446
libgupnp/gupnp-device-info.c | 10 +-
libgupnp/gupnp-error.c | 18 ++++
libgupnp/gupnp-error.h | 19 ++++
libgupnp/gupnp-root-device.c | 218 ++++++++++++++++++++----------------------
libgupnp/gupnp-root-device.h | 6 +-
tests/gtest/test-bugs.c | 18 +++-
vala/GUPnP-1.2.metadata | 2 +
vala/gupnp-1.2-custom.vala | 7 ++
8 files changed, 172 insertions(+), 126 deletions(-)
---
diff --git a/libgupnp/gupnp-device-info.c b/libgupnp/gupnp-device-info.c
index 6e932d3..754833d 100644
--- a/libgupnp/gupnp-device-info.c
+++ b/libgupnp/gupnp-device-info.c
@@ -89,7 +89,7 @@ gupnp_device_info_set_property (GObject *object,
GUPNP_RESOURCE_FACTORY (g_value_dup_object (value));
break;
case PROP_CONTEXT:
- info->priv->context = g_object_ref (g_value_get_object (value));
+ info->priv->context = g_value_dup_object (value);
break;
case PROP_LOCATION:
info->priv->location = g_value_dup_string (value);
@@ -191,7 +191,7 @@ gupnp_device_info_finalize (GObject *object)
g_free (info->priv->udn);
g_free (info->priv->device_type);
- soup_uri_free (info->priv->url_base);
+ g_clear_pointer (&info->priv->url_base, soup_uri_free);
G_OBJECT_CLASS (gupnp_device_info_parent_class)->finalize (object);
}
@@ -260,7 +260,7 @@ gupnp_device_info_class_init (GUPnPDeviceInfoClass *klass)
"file",
NULL,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_CONSTRUCT |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
@@ -314,7 +314,7 @@ gupnp_device_info_class_init (GUPnPDeviceInfoClass *klass)
"The URL base",
SOUP_TYPE_URI,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_CONSTRUCT |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
@@ -355,7 +355,7 @@ gupnp_device_info_class_init (GUPnPDeviceInfoClass *klass)
"The XML element related to this "
"device",
G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_CONSTRUCT |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
diff --git a/libgupnp/gupnp-error.c b/libgupnp/gupnp-error.c
index 6a483f4..c7a577e 100644
--- a/libgupnp/gupnp-error.c
+++ b/libgupnp/gupnp-error.c
@@ -99,6 +99,24 @@ gupnp_xml_error_quark (void)
return quark;
}
+/**
+ * GUPNP_ROOT_DEVICE_ERROR:
+ *
+ * The #GQuark uniquely used by GUPnP RootDevice creation errors.
+ *
+ * Returns: a #GQuark uniquely used by GUPnP RootDevice creation errors.
+ */
+GQuark
+gupnp_rootdevice_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 a850857..890fd1b 100644
--- a/libgupnp/gupnp-error.h
+++ b/libgupnp/gupnp-error.h
@@ -118,6 +118,25 @@ typedef enum {
GUPNP_XML_ERROR_OTHER
} GUPnPXMLError;
+GQuark
+gupnp_rootdevice_error_quark (void) G_GNUC_CONST;
+
+#define GUPNP_ROOT_DEVICE_ERROR (gupnp_rootdevice_error_quark ())
+
+/**
+ * GUPnPRootDeviceError:
+ * @GUPNP_ROOT_DEVICE_ERROR_NO_CONTEXT: No #GUPnPContext was passed to the root device.
+ * @GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_PATH: Device description path was missing
+ * @GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_FOLDER: Description folder was missing
+ *
+ * #GError codes used for errors during #GUPnPRootDevice creation
+ */
+typedef enum {
+ GUPNP_ROOT_DEVICE_ERROR_NO_CONTEXT,
+ GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_PATH,
+ GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_FOLDER
+} GUPnPRootdeviceError;
+
G_END_DECLS
#endif /* __GUPNP_ERROR_H__ */
diff --git a/libgupnp/gupnp-root-device.c b/libgupnp/gupnp-root-device.c
index cf207fc..55a2740 100644
--- a/libgupnp/gupnp-root-device.c
+++ b/libgupnp/gupnp-root-device.c
@@ -32,12 +32,26 @@
#include "gupnp-root-device.h"
#include "gupnp-context-private.h"
+#include "gupnp-error.h"
#include "http-headers.h"
#include "xml-util.h"
-G_DEFINE_TYPE (GUPnPRootDevice,
- gupnp_root_device,
- GUPNP_TYPE_DEVICE);
+static void
+gupnp_root_device_initable_iface_init (gpointer g_iface,
+ gpointer iface_data);
+
+static gboolean
+gupnp_root_device_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error);
+
+G_DEFINE_TYPE_EXTENDED (GUPnPRootDevice,
+ gupnp_root_device,
+ GUPNP_TYPE_DEVICE,
+ 0,
+ G_IMPLEMENT_INTERFACE
+ (G_TYPE_INITABLE,
+ gupnp_root_device_initable_iface_init));
struct _GUPnPRootDevicePrivate {
GUPnPXMLDoc *description_doc;
@@ -65,7 +79,7 @@ gupnp_root_device_finalize (GObject *object)
device = GUPNP_ROOT_DEVICE (object);
- g_object_unref (device->priv->description_doc);
+ g_clear_object (&device->priv->description_doc);
g_free (device->priv->description_path);
g_free (device->priv->description_dir);
g_free (device->priv->relative_location);
@@ -102,6 +116,14 @@ gupnp_root_device_init (GUPnPRootDevice *device)
}
static void
+gupnp_root_device_initable_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GInitableIface *iface = (GInitableIface *) g_iface;
+ iface->init = gupnp_root_device_initable_init;
+}
+
+static void
gupnp_root_device_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -262,106 +284,86 @@ load_and_parse (const char *description_path)
return description_doc;
}
-static GObject *
-gupnp_root_device_constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
+static gboolean
+gupnp_root_device_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
{
- GObjectClass *object_class;
- GObject *object;
GUPnPRootDevice *device;
GUPnPContext *context;
- const char *description_path, *description_dir, *udn;
+ const char *udn;
SoupURI *uri;
char *desc_path, *location, *usn, *relative_location;
- unsigned int i;
- GUPnPXMLDoc *description_doc;
xmlNode *root_element, *element;
SoupURI *url_base;
+ gboolean result = FALSE;
- object = NULL;
- location = NULL;
-
- /* Get 'description-doc', 'context', 'description-dir' and
- * 'description-path' property values */
- description_doc = NULL;
- context = NULL;
- description_path = NULL;
- description_dir = NULL;
-
- for (i = 0; i < n_construct_params; i++) {
- const char *par_name;
+ device = GUPNP_ROOT_DEVICE (initable);
- par_name = construct_params[i].pspec->name;
-
- if (strcmp (par_name, "description-doc") == 0) {
- description_doc =
- g_value_get_object (construct_params[i].value);
-
- continue;
- }
-
- if (strcmp (par_name, "context") == 0) {
- context =
- g_value_get_object (construct_params[i].value);
-
- continue;
- }
-
- if (strcmp (par_name, "description-path") == 0) {
- description_path =
- g_value_get_string (construct_params[i].value);
+ location = NULL;
- continue;
- }
+ g_object_get (G_OBJECT (device),
+ "context", &context,
+ NULL);
- if (strcmp (par_name, "description-dir") == 0) {
- description_dir =
- g_value_get_string (construct_params[i].value);
+ if (context == NULL) {
+ g_set_error_literal (error,
+ GUPNP_ROOT_DEVICE_ERROR,
+ GUPNP_ROOT_DEVICE_ERROR_NO_CONTEXT,
+ "No context specified");
- continue;
- }
+ return FALSE;
}
- if (!context) {
- g_warning ("No context specified.");
+ if (device->priv->description_path == NULL) {
+ g_set_error_literal (error,
+ GUPNP_ROOT_DEVICE_ERROR,
+ GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_PATH,
+ "Path to description document not specified.");
- return NULL;
+ return FALSE;
}
- if (!description_path) {
- g_warning ("Path to description document not specified.");
+ if (device->priv->description_dir == NULL) {
+ g_set_error_literal (error,
+ GUPNP_ROOT_DEVICE_ERROR,
+ GUPNP_ROOT_DEVICE_ERROR_NO_DESCRIPTION_FOLDER,
+ "Path to description directory not specified.");
- return NULL;
+ return FALSE;
}
- if (!description_dir) {
- g_warning ("Path to description directory not specified.");
-
- return NULL;
- }
- if (g_path_is_absolute (description_path))
- desc_path = g_strdup (description_path);
+ if (g_path_is_absolute (device->priv->description_path))
+ desc_path = g_strdup (device->priv->description_path);
else
- desc_path = g_build_filename (description_dir,
- description_path,
+ desc_path = g_build_filename (device->priv->description_dir,
+ device->priv->description_path,
NULL);
/* Check whether we have a parsed description document */
- if (!description_doc) {
+ if (device->priv->description_doc == NULL) {
/* We don't, so load and parse it */
- description_doc = load_and_parse (desc_path);
- if (description_doc == NULL)
+ device->priv->description_doc = load_and_parse (desc_path);
+ if (device->priv->description_doc == NULL) {
+ g_set_error_literal (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_PARSE,
+ "Coupld not parse description document");
+
goto DONE;
+ }
}
/* Find correct element */
- root_element = xml_util_get_element ((xmlNode *) description_doc->doc,
+ root_element = xml_util_get_element ((xmlNode *) device->priv->description_doc->doc,
"root",
NULL);
if (!root_element) {
- g_warning ("\"/root\" element not found.");
+ g_set_error_literal (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_NO_NODE,
+ "\"/root\" element not found.");
goto DONE;
}
@@ -370,39 +372,17 @@ gupnp_root_device_constructor (GType type,
"device",
NULL);
if (!element) {
- g_warning ("\"/root/device\" element not found.");
+ g_set_error_literal (error,
+ GUPNP_XML_ERROR,
+ GUPNP_XML_ERROR_NO_NODE,
+ "\"/root/device\" element not found.");
goto DONE;
}
- /* Set 'element' and 'description-doc' properties */
- for (i = 0; i < n_construct_params; i++) {
- const char *par_name;
-
- par_name = construct_params[i].pspec->name;
-
- if (strcmp (par_name, "element") == 0) {
- g_value_set_pointer (construct_params[i].value,
- element);
-
- continue;
- }
-
- if (strcmp (par_name, "description-doc") == 0) {
- g_value_set_object (construct_params[i].value,
- description_doc);
-
- continue;
- }
- }
-
- /* Create object */
- object_class = G_OBJECT_CLASS (gupnp_root_device_parent_class);
-
- object = object_class->constructor (type,
- n_construct_params,
- construct_params);
- device = GUPNP_ROOT_DEVICE (object);
+ g_object_set (G_OBJECT (device),
+ "element", element,
+ NULL);
/* Generate location relative to HTTP root */
udn = gupnp_device_info_get_udn (GUPNP_DEVICE_INFO (device));
@@ -436,7 +416,7 @@ gupnp_root_device_constructor (GType type,
url_base = soup_uri_new (location);
/* Set additional properties */
- g_object_set (object,
+ g_object_set (G_OBJECT (device),
"location", location,
"url-base", url_base,
NULL);
@@ -456,12 +436,14 @@ gupnp_root_device_constructor (GType type,
fill_resource_group (element, location, device->priv->group);
+ result = TRUE;
+
DONE:
/* Cleanup */
g_free (desc_path);
g_free (location);
- return object;
+ return result;
}
static void
@@ -473,7 +455,6 @@ gupnp_root_device_class_init (GUPnPRootDeviceClass *klass)
object_class->set_property = gupnp_root_device_set_property;
object_class->get_property = gupnp_root_device_get_property;
- object_class->constructor = gupnp_root_device_constructor;
object_class->dispose = gupnp_root_device_dispose;
object_class->finalize = gupnp_root_device_finalize;
@@ -563,6 +544,8 @@ gupnp_root_device_class_init (GUPnPRootDeviceClass *klass)
* @description_path: Path to device description document. This could either
* be an absolute path or path relative to @description_dir.
* @description_dir: Path to directory where description documents are provided.
+ * @error: (allow-none): The location for a #GError to report issue with
+ * creation on or %NULL.
*
* Create a new #GUPnPRootDevice object, automatically loading and parsing
* device description document from @description_path.
@@ -572,7 +555,8 @@ gupnp_root_device_class_init (GUPnPRootDeviceClass *klass)
GUPnPRootDevice *
gupnp_root_device_new (GUPnPContext *context,
const char *description_path,
- const char *description_dir)
+ const char *description_dir,
+ GError **error)
{
GUPnPResourceFactory *factory;
@@ -582,7 +566,8 @@ gupnp_root_device_new (GUPnPContext *context,
factory,
NULL,
description_path,
- description_dir);
+ description_dir,
+ error);
}
/**
@@ -593,6 +578,8 @@ gupnp_root_device_new (GUPnPContext *context,
* @description_path: Path to device description document. This could either
* be an absolute path or path relative to @description_dir.
* @description_dir: Path to directory where description documents are provided.
+ * @error: (allow-none): The location for a #GError to report issue with
+ * creation on or %NULL.
*
* Create a new #GUPnPRootDevice, automatically loading and parsing
* device description document from @description_path if @description_doc is
@@ -605,19 +592,22 @@ gupnp_root_device_new_full (GUPnPContext *context,
GUPnPResourceFactory *factory,
GUPnPXMLDoc *description_doc,
const char *description_path,
- const char *description_dir)
+ const char *description_dir,
+ GError **error)
{
g_return_val_if_fail (GUPNP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (GUPNP_IS_RESOURCE_FACTORY (factory), NULL);
- return g_object_new (GUPNP_TYPE_ROOT_DEVICE,
- "context", context,
- "resource-factory", factory,
- "root-device", NULL,
- "description-doc", description_doc,
- "description-path", description_path,
- "description-dir", description_dir,
- NULL);
+ return g_initable_new (GUPNP_TYPE_ROOT_DEVICE,
+ NULL,
+ error,
+ "context", context,
+ "resource-factory", factory,
+ "root-device", NULL,
+ "description-doc", description_doc,
+ "description-path", description_path,
+ "description-dir", description_dir,
+ NULL);
}
/**
diff --git a/libgupnp/gupnp-root-device.h b/libgupnp/gupnp-root-device.h
index 0c08791..54dd599 100644
--- a/libgupnp/gupnp-root-device.h
+++ b/libgupnp/gupnp-root-device.h
@@ -86,14 +86,16 @@ struct _GUPnPRootDeviceClass {
GUPnPRootDevice *
gupnp_root_device_new (GUPnPContext *context,
const char *description_path,
- const char *description_dir);
+ const char *description_dir,
+ GError **error);
GUPnPRootDevice *
gupnp_root_device_new_full (GUPnPContext *context,
GUPnPResourceFactory *factory,
GUPnPXMLDoc *description_doc,
const char *description_path,
- const char *description_dir);
+ const char *description_dir,
+ GError **error);
void
gupnp_root_device_set_available (GUPnPRootDevice *root_device,
diff --git a/tests/gtest/test-bugs.c b/tests/gtest/test-bugs.c
index 0ffac76..89c6a60 100644
--- a/tests/gtest/test-bugs.c
+++ b/tests/gtest/test-bugs.c
@@ -229,7 +229,9 @@ test_bgo_696762 (void)
&data);
- rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH);
+ rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH, &error);
+ g_assert_no_error (error);
+ g_assert (rd != NULL);
gupnp_root_device_set_available (rd, TRUE);
info = gupnp_device_info_get_service (GUPNP_DEVICE_INFO (rd),
"urn:test-gupnp-org:service:TestService:1");
@@ -291,7 +293,9 @@ test_bgo_678701 (void)
"urn:test-gupnp-org:device:TestSubDevice:1",
test_bgo_678701_device_get_type ());
- rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH);
+ rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH, &error);
+ g_assert_no_error (error);
+ g_assert (rd != NULL);
gupnp_root_device_set_available (rd, TRUE);
cp = gupnp_control_point_new (context,
@@ -347,7 +351,9 @@ test_bgo_690400 (void)
G_CALLBACK (test_on_sp_available),
&data);
- rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH);
+ rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH, &error);
+ g_assert_no_error (error);
+ g_assert (rd != NULL);
service = gupnp_device_info_get_service (GUPNP_DEVICE_INFO (rd),
"urn:test-gupnp-org:service:TestService:1");
g_signal_connect (service, "query-variable",
@@ -375,8 +381,8 @@ test_bgo_690400 (void)
g_main_loop_unref (data.loop);
g_object_unref (data.proxy);
g_object_unref (cp);
- g_object_unref (rd);
g_object_unref (service);
+ g_object_unref (rd);
g_object_unref (context);
}
@@ -395,7 +401,9 @@ test_bgo_722696 (void)
g_assert (context != NULL);
g_assert (error == NULL);
- rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH);
+ rd = gupnp_root_device_new (context, "TestDevice.xml", DATA_PATH, &error);
+ g_assert_no_error (error);
+ g_assert (rd != NULL);
/* prefer bigger */
width = -1;
diff --git a/vala/GUPnP-1.2.metadata b/vala/GUPnP-1.2.metadata
index 0d5c136..a62caea 100644
--- a/vala/GUPnP-1.2.metadata
+++ b/vala/GUPnP-1.2.metadata
@@ -42,6 +42,8 @@ ControlError skip
control_error_quark skip
EventingError skip
eventing_error_quark skip
+RootdeviceError skip
+rootdevice_error_quark skip
ServerError skip
server_error_quark skip
XMLError skip
diff --git a/vala/gupnp-1.2-custom.vala b/vala/gupnp-1.2-custom.vala
index 2e48e60..f8474fd 100644
--- a/vala/gupnp-1.2-custom.vala
+++ b/vala/gupnp-1.2-custom.vala
@@ -36,6 +36,13 @@ public interface GUPnP.Acl : GLib.Object {
}
namespace GUPnP {
+ [CCode (cheader_filename = "libgupnp/gupnp.h", cprefix = "GUPNP_ROOT_DEVICEL_ERROR_")]
+ public errordomain RootdeviceError {
+ NO_CONTEXT,
+ NO_DESCRIPTION_PATH,
+ NO_DESCRIPTION_FOLDER;
+ public static GLib.Quark quark ();
+ }
[CCode (cheader_filename = "libgupnp/gupnp.h", cprefix = "GUPNP_CONTROL_ERROR_")]
public errordomain ControlError {
INVALID_ACTION,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]