[gupnp] resource-factory: Version-independent typeregister
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gupnp] resource-factory: Version-independent typeregister
- Date: Tue, 28 May 2019 09:36:11 +0000 (UTC)
commit 75521fe1eb317f6657383912c3aea0adae2febd0
Author: Jens Georg <mail jensge org>
Date: Tue May 28 11:31:49 2019 +0200
resource-factory: Version-independent typeregister
Until now the types registered in the GUPnPResourceFactory had to be an
exact match. For example, egistering a type for
urn:schemas-upnp-org:service:AVTransport:2 would only return this type
for AVTransport:2 but not for a detected AVTransport:1. It is now
possible to register for AVTransport only without a concrete version.
https://bugzilla.gnome.org/show_bug.cgi?id=764498
libgupnp/gupnp-resource-factory.c | 137 ++++++++++++++++++++++----------------
1 file changed, 79 insertions(+), 58 deletions(-)
---
diff --git a/libgupnp/gupnp-resource-factory.c b/libgupnp/gupnp-resource-factory.c
index 6a91e73..b32b6d5 100644
--- a/libgupnp/gupnp-resource-factory.c
+++ b/libgupnp/gupnp-resource-factory.c
@@ -133,6 +133,59 @@ gupnp_resource_factory_get_default (void)
return default_factory;
}
+static GType
+lookup_type_with_fallback (GHashTable *resource_types,
+ const char *requested_type,
+ const char *child_node,
+ xmlNode *element,
+ GType fallback)
+{
+ GType type = fallback;
+ char *upnp_type = NULL;
+
+ if (requested_type == NULL) {
+ g_debug ("Looking up type from XML");
+ upnp_type = xml_util_get_child_element_content_glib (element,
+ child_node);
+ } else {
+ g_debug ("Using passed type %s", requested_type);
+ upnp_type = g_strdup (requested_type);
+ }
+
+
+ if (upnp_type != NULL) {
+ g_debug ("Found type from XML: %s", upnp_type);
+ gpointer value;
+ char *needle = NULL;
+
+ value = g_hash_table_lookup (resource_types, upnp_type);
+
+ if (value == NULL) {
+ g_debug ("Trying to use version-less type...");
+ needle = g_strrstr (upnp_type, ":");
+ if (needle != NULL) {
+ *needle = '\0';
+ g_debug ("Version-less type is %s", upnp_type);
+
+ value = g_hash_table_lookup (resource_types, upnp_type);
+ }
+ }
+
+ if (value != NULL) {
+ type = GPOINTER_TO_SIZE (value);
+ }
+
+ g_debug ("Will return type %s for UPnP type %s", g_type_name (type), upnp_type);
+ g_free (upnp_type);
+ } else {
+ g_debug ("Will return fall-back type %s", upnp_type);
+ }
+
+
+ return type;
+}
+
+
/**
* gupnp_resource_factory_create_device_proxy:
* @factory: A #GUPnPResourceFactory
@@ -160,7 +213,6 @@ gupnp_resource_factory_create_device_proxy
const SoupURI *url_base)
{
GUPnPDeviceProxy *proxy;
- char *upnp_type;
GType proxy_type = GUPNP_TYPE_DEVICE_PROXY;
GUPnPResourceFactoryPrivate *priv;
@@ -173,18 +225,11 @@ gupnp_resource_factory_create_device_proxy
priv = gupnp_resource_factory_get_instance_private (factory);
- upnp_type = xml_util_get_child_element_content_glib (element,
- "deviceType");
- if (upnp_type) {
- gpointer value;
-
- value = g_hash_table_lookup (priv->proxy_type_hash,
- upnp_type);
- if (value)
- proxy_type = GPOINTER_TO_SIZE (value);
-
- g_free (upnp_type);
- }
+ proxy_type = lookup_type_with_fallback (priv->proxy_type_hash,
+ NULL,
+ "deviceType",
+ element,
+ GUPNP_TYPE_DEVICE_PROXY);
proxy = g_object_new (proxy_type,
"resource-factory", factory,
@@ -204,7 +249,7 @@ gupnp_resource_factory_create_device_proxy
* @factory: A #GUPnPResourceFactory
* @context: A #GUPnPContext
* @doc: A #GUPnPXMLDoc
- * @element: The #xmlNode ponting to the right service element
+ * @element: The #xmlNode pointing to the right service element
* @location: The location of the service description file
* @udn: The UDN of the device the service is contained in
* @service_type: (allow-none): The service type, or %NULL to use service
@@ -227,7 +272,6 @@ gupnp_resource_factory_create_service_proxy
const char *location,
const SoupURI *url_base)
{
- char *type_from_xml = NULL;
GUPnPServiceProxy *proxy;
GType proxy_type = GUPNP_TYPE_SERVICE_PROXY;
GUPnPResourceFactoryPrivate *priv;
@@ -241,21 +285,11 @@ gupnp_resource_factory_create_service_proxy
priv = gupnp_resource_factory_get_instance_private (factory);
- if (!service_type) {
- type_from_xml =
- xml_util_get_child_element_content_glib (element,
- "serviceType");
- service_type = type_from_xml;
- }
-
- if (service_type) {
- gpointer value;
-
- value = g_hash_table_lookup (priv->proxy_type_hash,
- service_type);
- if (value)
- proxy_type = GPOINTER_TO_SIZE (value);
- }
+ proxy_type = lookup_type_with_fallback (priv->proxy_type_hash,
+ service_type,
+ "serviceType",
+ element,
+ GUPNP_TYPE_SERVICE_PROXY);
proxy = g_object_new (proxy_type,
"context", context,
@@ -267,8 +301,6 @@ gupnp_resource_factory_create_service_proxy
"element", element,
NULL);
- g_free (type_from_xml);
-
return proxy;
}
@@ -298,7 +330,6 @@ gupnp_resource_factory_create_device
const SoupURI *url_base)
{
GUPnPDevice *device;
- char *upnp_type;
GType device_type = GUPNP_TYPE_DEVICE;
GUPnPResourceFactoryPrivate *priv;
@@ -310,18 +341,11 @@ gupnp_resource_factory_create_device
priv = gupnp_resource_factory_get_instance_private (factory);
- upnp_type = xml_util_get_child_element_content_glib (element,
- "deviceType");
- if (upnp_type) {
- gpointer value;
-
- value = g_hash_table_lookup (priv->resource_type_hash,
- upnp_type);
- if (value)
- device_type = GPOINTER_TO_SIZE (value);
-
- g_free (upnp_type);
- }
+ device_type = lookup_type_with_fallback (priv->resource_type_hash,
+ NULL,
+ "deviceType",
+ element,
+ GUPNP_TYPE_DEVICE);
device = g_object_new (device_type,
"resource-factory", factory,
@@ -362,7 +386,6 @@ gupnp_resource_factory_create_service
const SoupURI *url_base)
{
GUPnPService *service;
- char *upnp_type;
GType service_type = GUPNP_TYPE_SERVICE;
GUPnPResourceFactoryPrivate *priv;
@@ -375,18 +398,11 @@ gupnp_resource_factory_create_service
priv = gupnp_resource_factory_get_instance_private (factory);
- upnp_type = xml_util_get_child_element_content_glib (element,
- "serviceType");
- if (upnp_type) {
- gpointer value;
-
- value = g_hash_table_lookup (priv->resource_type_hash,
- upnp_type);
- if (value)
- service_type = GPOINTER_TO_SIZE (value);
-
- g_free (upnp_type);
- }
+ service_type = lookup_type_with_fallback (priv->resource_type_hash,
+ NULL,
+ "serviceType",
+ element,
+ GUPNP_TYPE_SERVICE);
service = g_object_new (service_type,
"context", context,
@@ -410,6 +426,11 @@ gupnp_resource_factory_create_service
* this call, the factory @factory will create object of GType @type each time
* it is asked to create a resource object for UPnP type @upnp_type.
*
+ * You can either register a type for a concrete version of a device or service
+ * such as urn:schemas-upnp-org:service:AVTransport:2 or version-independently,
+ * urn:schemas-upnp-org:service:AVTransport. If you register for an explicit
+ * version of a service, it will be an exact match.
+ *
* Note: GType @type must be a derived type of #GUPNP_TYPE_DEVICE if resource is
* a device or #GUPNP_TYPE_SERVICE if its a service.
**/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]