📄 gupnp-root-device.c
字号:
/* * Copyright (C) 2007, 2008 OpenedHand Ltd. * * Author: Jorn Baayen <jorn@openedhand.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//** * SECTION:gupnp-root-device * @short_description: Class for root device implementations. * * #GUPnPRootDevice allows for implementing root devices. */#include <string.h>#include <libgssdp/gssdp-resource-group.h>#include "gupnp-root-device.h"#include "gupnp-context-private.h"#include "http-headers.h"#include "xml-util.h"G_DEFINE_TYPE (GUPnPRootDevice, gupnp_root_device, GUPNP_TYPE_DEVICE);struct _GUPnPRootDevicePrivate { xmlDoc *description_doc; gboolean own_description_doc; GSSDPResourceGroup *group; char *relative_location;};enum { PROP_0, PROP_DESCRIPTION_DOC, PROP_RELATIVE_LOCATION, PROP_AVAILABLE};static voidgupnp_root_device_finalize (GObject *object){ GUPnPRootDevice *device; GObjectClass *object_class; device = GUPNP_ROOT_DEVICE (object); g_free (device->priv->relative_location); if (device->priv->own_description_doc) xmlFreeDoc (device->priv->description_doc); /* Call super */ object_class = G_OBJECT_CLASS (gupnp_root_device_parent_class); object_class->finalize (object);}static voidgupnp_root_device_dispose (GObject *object){ GUPnPRootDevice *device; GObjectClass *object_class; device = GUPNP_ROOT_DEVICE (object); if (device->priv->group) { g_object_unref (device->priv->group); device->priv->group = NULL; } /* Call super */ object_class = G_OBJECT_CLASS (gupnp_root_device_parent_class); object_class->dispose (object);}static voidgupnp_root_device_init (GUPnPRootDevice *device){ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GUPNP_TYPE_ROOT_DEVICE, GUPnPRootDevicePrivate); device->priv->own_description_doc = FALSE;}static voidgupnp_root_device_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec){ GUPnPRootDevice *device; device = GUPNP_ROOT_DEVICE (object); switch (property_id) { case PROP_DESCRIPTION_DOC: device->priv->description_doc = g_value_get_pointer (value); break; case PROP_RELATIVE_LOCATION: device->priv->relative_location = g_value_dup_string (value); break; case PROP_AVAILABLE: gupnp_root_device_set_available (device, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; }}static voidgupnp_root_device_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec){ GUPnPRootDevice *device; device = GUPNP_ROOT_DEVICE (object); switch (property_id) { case PROP_RELATIVE_LOCATION: g_value_set_string (value, device->priv->relative_location); break; case PROP_AVAILABLE: g_value_set_boolean (value, gupnp_root_device_get_available (device)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; }}/* Adds @udn::@resource_type to @group, together with all earlier versions * of @resource_type. * * Note: @resource_type is modified in this function. */static voidadd_resource_with_earlier_versions (GSSDPResourceGroup *group, const char *udn, const char *resource_type, const char *location){ char *colon, *usn; int version, i; /* Add specified version */ usn = g_strdup_printf ("%s::%s", (char *) udn, (char *) resource_type); gssdp_resource_group_add_resource_simple (group, (const char *) resource_type, usn, location); g_free (usn); /* Try to parse version */ colon = strrchr (resource_type, ':'); if (G_UNLIKELY (*colon == 0)) return; colon += 1; if (G_UNLIKELY (*colon == 0)) return; version = atoi (colon); /* Add earlier versions */ *colon = 0; for (i = 1; i < version; i++) { char *type; type = g_strdup_printf ("%s%d", (char *) resource_type, i); usn = g_strdup_printf ("%s::%s", (char *) udn, (char *) type); gssdp_resource_group_add_resource_simple (group, type, usn, location); g_free (usn); g_free (type); }}static voidfill_resource_group (xmlNode *element, const char *location, GSSDPResourceGroup *group){ xmlNode *child; xmlChar *udn, *device_type; /* Add device */ udn = xml_util_get_child_element_content (element, "UDN"); if (!udn) { g_warning ("No UDN specified."); return; } device_type = xml_util_get_child_element_content (element, "deviceType"); if (!device_type) { g_warning ("No deviceType specified."); return; } gssdp_resource_group_add_resource_simple (group, (const char *) udn, (const char *) udn, location); add_resource_with_earlier_versions (group, (const char *) udn, (const char *) device_type, location); xmlFree (device_type); /* Add embedded services */ child = xml_util_get_element (element, "serviceList", NULL); if (child) { for (child = child->children; child; child = child->next) { xmlChar *service_type; if (strcmp ("service", (char *) child->name)) continue; service_type = xml_util_get_child_element_content (child, "serviceType"); if (!service_type) continue; add_resource_with_earlier_versions (group, (const char *) udn, (const char *) service_type, location); xmlFree (service_type); } } /* Cleanup */ xmlFree (udn); /* Add embedded devices */ child = xml_util_get_element (element, "deviceList", NULL); if (child) { for (child = child->children; child; child = child->next) if (!strcmp ("device", (char *) child->name)) fill_resource_group (child, location, group); }}/* Download and parse @location as an XML document, synchronously. */static xmlDoc *download_and_parse (GUPnPContext *context, const char *location){ xmlDoc *description_doc; SoupSession *session; SoupMessage *msg; int status; session = _gupnp_context_get_session (context); msg = soup_message_new (SOUP_METHOD_GET, location); if (msg == NULL) { g_warning ("Invalid URL: %s", location); return NULL; } http_request_set_user_agent (msg); http_request_set_accept_language (msg); status = soup_session_send_message (session, msg); if (!SOUP_STATUS_IS_SUCCESSFUL (status)) { g_warning ("Unable to download description document " "from %s", location); g_object_unref (msg); return NULL; } description_doc = xmlParseMemory (msg->response_body->data, msg->response_body->length); g_object_unref (msg); if (description_doc == NULL) { g_warning ("Failed to parse %s\n", location); return NULL; } return description_doc;}static GObject *gupnp_root_device_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params){ GObjectClass *object_class; GObject *object;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -