2 * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd.
4 * Author: Jorn Baayen <jorn@openedhand.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 * SECTION:gupnp-device-info
24 * @short_description: Base abstract class for querying device information.
26 * The #GUPnPDeviceInfo base abstract class provides methods for querying
32 #include "gupnp-device-info.h"
33 #include "gupnp-device-info-private.h"
34 #include "gupnp-resource-factory-private.h"
37 G_DEFINE_ABSTRACT_TYPE (GUPnPDeviceInfo,
41 struct _GUPnPDeviceInfoPrivate {
42 GUPnPResourceFactory *factory;
43 GUPnPContext *context;
58 PROP_RESOURCE_FACTORY,
69 gupnp_device_info_init (GUPnPDeviceInfo *info)
71 info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info,
72 GUPNP_TYPE_DEVICE_INFO,
73 GUPnPDeviceInfoPrivate);
77 gupnp_device_info_set_property (GObject *object,
82 GUPnPDeviceInfo *info;
84 info = GUPNP_DEVICE_INFO (object);
86 switch (property_id) {
87 case PROP_RESOURCE_FACTORY:
89 GUPNP_RESOURCE_FACTORY (g_value_dup_object (value));
92 info->priv->context = g_object_ref (g_value_get_object (value));
95 info->priv->location = g_value_dup_string (value);
98 info->priv->udn = g_value_dup_string (value);
100 case PROP_DEVICE_TYPE:
101 info->priv->device_type = g_value_dup_string (value);
104 info->priv->url_base = g_value_dup_boxed (value);
107 info->priv->doc = g_value_dup_object (value);
110 info->priv->element = g_value_get_pointer (value);
113 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
119 gupnp_device_info_get_property (GObject *object,
124 GUPnPDeviceInfo *info;
126 info = GUPNP_DEVICE_INFO (object);
128 switch (property_id) {
129 case PROP_RESOURCE_FACTORY:
130 g_value_set_object (value,
131 info->priv->factory);
134 g_value_set_object (value,
135 info->priv->context);
138 g_value_set_string (value,
139 info->priv->location);
142 g_value_set_string (value,
143 gupnp_device_info_get_udn (info));
145 case PROP_DEVICE_TYPE:
146 g_value_set_string (value,
147 gupnp_device_info_get_device_type (info));
150 g_value_set_boxed (value, info->priv->url_base);
153 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
159 gupnp_device_info_dispose (GObject *object)
161 GUPnPDeviceInfo *info;
163 info = GUPNP_DEVICE_INFO (object);
165 if (info->priv->factory) {
166 g_object_unref (info->priv->factory);
167 info->priv->factory = NULL;
170 if (info->priv->context) {
171 g_object_unref (info->priv->context);
172 info->priv->context = NULL;
175 if (info->priv->doc) {
176 g_object_unref (info->priv->doc);
177 info->priv->doc = NULL;
180 G_OBJECT_CLASS (gupnp_device_info_parent_class)->dispose (object);
184 gupnp_device_info_finalize (GObject *object)
186 GUPnPDeviceInfo *info;
188 info = GUPNP_DEVICE_INFO (object);
190 g_free (info->priv->location);
191 g_free (info->priv->udn);
192 g_free (info->priv->device_type);
194 soup_uri_free (info->priv->url_base);
196 G_OBJECT_CLASS (gupnp_device_info_parent_class)->finalize (object);
200 gupnp_device_info_class_init (GUPnPDeviceInfoClass *klass)
202 GObjectClass *object_class;
204 object_class = G_OBJECT_CLASS (klass);
206 object_class->set_property = gupnp_device_info_set_property;
207 object_class->get_property = gupnp_device_info_get_property;
208 object_class->dispose = gupnp_device_info_dispose;
209 object_class->finalize = gupnp_device_info_finalize;
211 g_type_class_add_private (klass, sizeof (GUPnPDeviceInfoPrivate));
214 * GUPnPDeviceInfo:resource-factory:
216 * The resource factory to use. Set to NULL for default factory.
218 g_object_class_install_property
220 PROP_RESOURCE_FACTORY,
221 g_param_spec_object ("resource-factory",
223 "The resource factory to use",
224 GUPNP_TYPE_RESOURCE_FACTORY,
226 G_PARAM_CONSTRUCT_ONLY |
227 G_PARAM_STATIC_NAME |
228 G_PARAM_STATIC_NICK |
229 G_PARAM_STATIC_BLURB));
232 * GUPnPDeviceInfo:context:
234 * The #GUPnPContext to use.
236 g_object_class_install_property
239 g_param_spec_object ("context",
244 G_PARAM_CONSTRUCT_ONLY |
245 G_PARAM_STATIC_NAME |
246 G_PARAM_STATIC_NICK |
247 G_PARAM_STATIC_BLURB));
250 * GUPnPDeviceInfo:location:
252 * The location of the device description file.
254 g_object_class_install_property
257 g_param_spec_string ("location",
259 "The location of the device description "
263 G_PARAM_CONSTRUCT_ONLY |
264 G_PARAM_STATIC_NAME |
265 G_PARAM_STATIC_NICK |
266 G_PARAM_STATIC_BLURB));
269 * GUPnPDeviceInfo:udn:
271 * The UDN of this device.
273 g_object_class_install_property
276 g_param_spec_string ("udn",
281 G_PARAM_CONSTRUCT_ONLY |
282 G_PARAM_STATIC_NAME |
283 G_PARAM_STATIC_NICK |
284 G_PARAM_STATIC_BLURB));
287 * GUPnPDeviceInfo:device-type:
291 g_object_class_install_property
294 g_param_spec_string ("device-type",
299 G_PARAM_CONSTRUCT_ONLY |
300 G_PARAM_STATIC_NAME |
301 G_PARAM_STATIC_NICK |
302 G_PARAM_STATIC_BLURB));
305 * GUPnPDeviceInfo:url-base:
307 * The URL base (#SoupURI).
309 g_object_class_install_property
312 g_param_spec_boxed ("url-base",
317 G_PARAM_CONSTRUCT_ONLY |
318 G_PARAM_STATIC_NAME |
319 G_PARAM_STATIC_NICK |
320 G_PARAM_STATIC_BLURB));
323 * GUPnPDeviceInfo:document:
329 g_object_class_install_property
332 g_param_spec_object ("document",
334 "The XML document related to this "
338 G_PARAM_CONSTRUCT_ONLY |
339 G_PARAM_STATIC_NAME |
340 G_PARAM_STATIC_NICK |
341 G_PARAM_STATIC_BLURB));
344 * GUPnPDeviceInfo:element:
350 g_object_class_install_property
353 g_param_spec_pointer ("element",
355 "The XML element related to this "
358 G_PARAM_CONSTRUCT_ONLY |
359 G_PARAM_STATIC_NAME |
360 G_PARAM_STATIC_NICK |
361 G_PARAM_STATIC_BLURB));
365 * gupnp_device_info_get_resource_factory:
366 * @device_info: A #GUPnPDeviceInfo
368 * Get the #GUPnPResourceFactory used by the @device_info.
370 * Returns: (transfer none): A #GUPnPResourceFactory.
372 GUPnPResourceFactory *
373 gupnp_device_info_get_resource_factory (GUPnPDeviceInfo *info)
375 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
377 return info->priv->factory;
381 * gupnp_device_info_get_context:
382 * @info: A #GUPnPDeviceInfo
384 * Get the associated #GUPnPContext.
386 * Returns: (transfer none): A #GUPnPContext.
389 gupnp_device_info_get_context (GUPnPDeviceInfo *info)
391 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
393 return info->priv->context;
397 * gupnp_device_info_get_location:
398 * @info: A #GUPnPDeviceInfo
400 * Get the location of the device description file.
402 * Returns: A constant string.
405 gupnp_device_info_get_location (GUPnPDeviceInfo *info)
407 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
409 return info->priv->location;
413 * gupnp_device_info_get_url_base:
414 * @info: A #GUPnPDeviceInfo
416 * Get the URL base of this device.
418 * Returns: A #SoupURI.
421 gupnp_device_info_get_url_base (GUPnPDeviceInfo *info)
423 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
425 return info->priv->url_base;
429 * gupnp_device_info_get_udn:
430 * @info: A #GUPnPDeviceInfo
432 * Get the Unique Device Name of the device.
434 * Returns: A constant string.
437 gupnp_device_info_get_udn (GUPnPDeviceInfo *info)
439 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
441 if (!info->priv->udn) {
443 xml_util_get_child_element_content_glib
444 (info->priv->element, "UDN");
447 return info->priv->udn;
451 * gupnp_device_info_get_device_type:
452 * @info: A #GUPnPDeviceInfo
454 * Get the UPnP device type.
456 * Returns: A constant string, or %NULL.
459 gupnp_device_info_get_device_type (GUPnPDeviceInfo *info)
461 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
463 if (!info->priv->device_type) {
464 info->priv->device_type =
465 xml_util_get_child_element_content_glib
466 (info->priv->element, "deviceType");
469 return info->priv->device_type;
473 * gupnp_device_info_get_friendly_name:
474 * @info: A #GUPnPDeviceInfo
476 * Get the friendly name of the device.
478 * Return value: A string, or %NULL. g_free() after use.
481 gupnp_device_info_get_friendly_name (GUPnPDeviceInfo *info)
483 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
485 return xml_util_get_child_element_content_glib (info->priv->element,
490 * gupnp_device_info_get_manufacturer:
491 * @info: A #GUPnPDeviceInfo
493 * Get the manufacturer of the device.
495 * Return value: A string, or %NULL. g_free() after use.
498 gupnp_device_info_get_manufacturer (GUPnPDeviceInfo *info)
500 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
502 return xml_util_get_child_element_content_glib (info->priv->element,
507 * gupnp_device_info_get_manufacturer_url:
508 * @info: A #GUPnPDeviceInfo
510 * Get a URL pointing to the manufacturer's website.
512 * Return value: A string, or %NULL. g_free() after use.
515 gupnp_device_info_get_manufacturer_url (GUPnPDeviceInfo *info)
517 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
519 return xml_util_get_child_element_content_url (info->priv->element,
521 info->priv->url_base);
525 * gupnp_device_info_get_model_description:
526 * @info: A #GUPnPDeviceInfo
528 * Get the description of the device model.
530 * Return value: A string, or %NULL. g_free() after use.
533 gupnp_device_info_get_model_description (GUPnPDeviceInfo *info)
535 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
537 return xml_util_get_child_element_content_glib (info->priv->element,
542 * gupnp_device_info_get_model_name:
543 * @info: A #GUPnPDeviceInfo
545 * Get the model name of the device.
547 * Return value: A string, or %NULL. g_free() after use.
550 gupnp_device_info_get_model_name (GUPnPDeviceInfo *info)
552 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
554 return xml_util_get_child_element_content_glib (info->priv->element,
559 * gupnp_device_info_get_model_number:
560 * @info: A #GUPnPDeviceInfo
562 * Get the model number of the device.
564 * Return value: A string, or %NULL. g_free() after use.
567 gupnp_device_info_get_model_number (GUPnPDeviceInfo *info)
569 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
571 return xml_util_get_child_element_content_glib (info->priv->element,
576 * gupnp_device_info_get_model_url:
577 * @info: A #GUPnPDeviceInfo
579 * Get a URL pointing to the device model's website.
581 * Return value: A string, or %NULL. g_free() after use.
584 gupnp_device_info_get_model_url (GUPnPDeviceInfo *info)
586 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
588 return xml_util_get_child_element_content_url (info->priv->element,
590 info->priv->url_base);
594 * gupnp_device_info_get_serial_number:
595 * @info: A #GUPnPDeviceInfo
597 * Get the serial number of the device.
599 * Return value: A string, or %NULL. g_free() after use.
602 gupnp_device_info_get_serial_number (GUPnPDeviceInfo *info)
604 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
606 return xml_util_get_child_element_content_glib (info->priv->element,
611 * gupnp_device_info_get_upc:
612 * @info: A #GUPnPDeviceInfo
614 * Get the Universal Product Code of the device.
616 * Return value: A string, or %NULL. g_free() after use.
619 gupnp_device_info_get_upc (GUPnPDeviceInfo *info)
621 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
623 return xml_util_get_child_element_content_glib (info->priv->element,
628 * gupnp_device_info_get_presentation_url:
629 * @info: A #GUPnPDeviceInfo
631 * Get a URL pointing to the device's presentation page, for web-based
634 * Return value: A string, or %NULL. g_free() after use.
637 gupnp_device_info_get_presentation_url (GUPnPDeviceInfo *info)
639 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
641 return xml_util_get_child_element_content_url (info->priv->element,
643 info->priv->url_base);
657 icon_parse (G_GNUC_UNUSED GUPnPDeviceInfo *info, xmlNode *element)
661 icon = g_slice_new0 (Icon);
663 icon->mime_type = xml_util_get_child_element_content (element,
665 icon->width = xml_util_get_child_element_content_int (element,
667 icon->height = xml_util_get_child_element_content_int (element,
669 icon->depth = xml_util_get_child_element_content_int (element,
671 icon->url = xml_util_get_child_element_content (element,
678 icon_free (Icon *icon)
681 xmlFree (icon->mime_type);
686 g_slice_free (Icon, icon);
690 * gupnp_device_info_get_icon_url:
691 * @info: A #GUPnPDeviceInfo
692 * @requested_mime_type: (allow-none) (transfer none): The requested file
693 * format, or %NULL for any
694 * @requested_depth: The requested color depth, or -1 for any
695 * @requested_width: The requested width, or -1 for any
696 * @requested_height: The requested height, or -1 for any
697 * @prefer_bigger: %TRUE if a bigger, rather than a smaller icon should be
698 * returned if no exact match could be found
699 * @mime_type: (out) (allow-none): The location where to store the the format
700 * of the returned icon, or %NULL. The returned string should be freed after
702 * @depth: (out) (allow-none) : The location where to store the depth of the
703 * returned icon, or %NULL
704 * @width: (out) (allow-none) : The location where to store the width of the
705 * returned icon, or %NULL
706 * @height: (out) (allow-none) : The location where to store the height of the
707 * returned icon, or %NULL
709 * Get a URL pointing to the icon most closely matching the
710 * given criteria, or %NULL. If @requested_mime_type is set, only icons with
711 * this mime type will be returned. If @requested_depth is set, only icons with
712 * this or lower depth will be returned. If @requested_width and/or
713 * @requested_height are set, only icons that are this size or smaller are
714 * returned, unless @prefer_bigger is set, in which case the next biggest icon
715 * will be returned. The returned strings should be freed.
717 * Return value: (transfer full): a string, or %NULL. g_free() after use.
720 gupnp_device_info_get_icon_url (GUPnPDeviceInfo *info,
721 const char *requested_mime_type,
724 int requested_height,
725 gboolean prefer_bigger,
733 Icon *icon, *closest;
736 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
738 /* List available icons */
741 element = xml_util_get_element (info->priv->element,
747 for (element = element->children; element; element = element->next) {
748 if (!strcmp ("icon", (char *) element->name)) {
749 gboolean mime_type_ok;
751 icon = icon_parse (info, element);
753 if (requested_mime_type) {
755 mime_type_ok = !strcmp (
757 (char *) icon->mime_type);
759 mime_type_ok = FALSE;
763 if (requested_depth >= 0)
764 icon->weight = requested_depth - icon->depth;
766 /* Filter out icons with incorrect mime type or
767 * incorrect depth. */
768 if (mime_type_ok && icon->weight >= 0) {
769 if (requested_width >= 0) {
781 if (requested_height >= 0) {
793 icons = g_list_prepend (icons, icon);
802 /* Find closest match */
804 for (l = icons; l; l = l->next) {
807 /* Look between icons with positive weight first */
808 if (icon->weight >= 0) {
809 if (!closest || icon->weight < closest->weight)
815 for (l = icons; l; l = l->next) {
818 /* No icons with positive weight, look at ones with
820 if (!closest || icon->weight > closest->weight)
825 /* Fill in return values */
830 if (icon->mime_type) {
831 *mime_type = g_strdup
832 ((char *) icon->mime_type);
838 *depth = icon->depth;
840 *width = icon->width;
842 *height = icon->height;
847 uri = soup_uri_new_with_base (info->priv->url_base,
848 (const char *) icon->url);
849 ret = soup_uri_to_string (uri, FALSE);
867 g_list_free_full (icons, (GDestroyNotify) icon_free);
872 /* Returns TRUE if @query matches against @base.
873 * - If @query does not specify a version, it matches any version specified
875 * - If @query specifies a version, it matches any version specified in @base
876 * that is greater or equal.
879 resource_type_match (const char *query,
885 guint query_ver, base_ver;
887 /* Inspect last colon (if any!) on @base */
888 colon = strrchr (base, ':');
889 if (G_UNLIKELY (colon == NULL))
890 return !strcmp (query, base); /* No colon */
892 /* Length of type until last colon */
893 type_len = strlen (base) - strlen (colon);
895 /* Match initial portions */
896 match = (strncmp (query, base, type_len) == 0);
900 /* Initial portions matched. Try to position pointers after
901 * last colons of both @query and @base. */
903 if (G_UNLIKELY (*colon == 0))
909 return TRUE; /* @query does not specify a version */
912 if (G_UNLIKELY (*query == 0))
917 return FALSE; /* Hmm, not EOS, nor colon.. bad */
921 query_ver = atoi (query);
922 base_ver = atoi (colon);
924 /* Compare versions */
925 return (query_ver <= base_ver);
929 * gupnp_device_info_list_dlna_device_class_identifier:
930 * @info: A #GUPnPDeviceInfo
932 * Get a #GList of strings that represent the device class and version as
933 * announced in the device description file using the <dlna:X_DLNADOC>
935 * Returns: (transfer full) (element-type utf8): a #GList of newly allocated strings or
936 * %NULL if the device description doesn't contain the <dlna:X_DLNADOC>
942 gupnp_device_info_list_dlna_device_class_identifier (GUPnPDeviceInfo *info)
947 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
949 element = info->priv->element;
951 for (element = element->children; element; element = element->next) {
952 /* No early exit since the node explicitly may appear multiple
954 if (!strcmp ("X_DLNADOC", (char *) element->name)) {
955 xmlChar *content = NULL;
957 content = xmlNodeGetContent (element);
962 list = g_list_prepend (list,
963 g_strdup ((char *) content));
968 /* Return in order of appearance in document */
969 return g_list_reverse (list);
973 * gupnp_device_info_list_dlna_capabilities:
974 * @info: A #GUPnPDeviceInfo
976 * Get a #GList of strings that represent the device capabilities as announced
977 * in the device description file using the <dlna:X_DLNACAP> element.
979 * Returns: (transfer full) (element-type utf8): a #GList of newly allocated strings or
980 * %NULL if the device description doesn't contain the <dlna:X_DLNACAP>
986 gupnp_device_info_list_dlna_capabilities (GUPnPDeviceInfo *info)
990 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
992 caps = xml_util_get_child_element_content (info->priv->element,
997 const xmlChar *start = caps;
1000 const xmlChar *end = start;
1002 while (*end && *end != ',')
1008 value = g_strndup ((const gchar *) start,
1011 list = g_list_prepend (list, value);
1022 return g_list_reverse (list);
1029 * gupnp_device_info_get_description_value:
1030 * @info: A #GUPnPDeviceInfo
1031 * @element: Name of the description element to retrieve
1033 * This function provides generic access to the contents of arbitrary elements
1034 * in the device description file.
1036 * Return value: a newly allocated string or %NULL if the device
1037 * description doesn't contain the given @element
1042 gupnp_device_info_get_description_value (GUPnPDeviceInfo *info,
1043 const char *element)
1045 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1046 g_return_val_if_fail (element != NULL, NULL);
1048 return xml_util_get_child_element_content_glib (info->priv->element,
1053 * gupnp_device_info_list_devices:
1054 * @info: A #GUPnPDeviceInfo
1056 * Get a #GList of new objects implementing #GUPnPDeviceInfo
1057 * representing the devices directly contained in @info. The returned list
1058 * should be g_list_free()'d and the elements should be g_object_unref()'d.
1060 * Note that devices are not cached internally, so that every time you
1061 * call this function new objects are created. The application
1062 * must cache any used devices if it wishes to keep them around and re-use
1065 * Return value: (element-type GUPnP.DeviceInfo) (transfer full): a #GList of
1066 * new #GUPnPDeviceInfo objects.
1069 gupnp_device_info_list_devices (GUPnPDeviceInfo *info)
1071 GUPnPDeviceInfoClass *class;
1075 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1077 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1079 g_return_val_if_fail (class->get_device, NULL);
1083 element = xml_util_get_element (info->priv->element,
1089 for (element = element->children; element; element = element->next) {
1090 if (!strcmp ("device", (char *) element->name)) {
1091 GUPnPDeviceInfo *child;
1093 child = class->get_device (info, element);
1094 devices = g_list_prepend (devices, child);
1102 * gupnp_device_info_list_device_types:
1103 * @info: A #GUPnPDeviceInfo
1105 * Get a #GList of strings representing the types of the devices
1106 * directly contained in @info.
1108 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1109 * elements should be g_free()'d and the list should be g_list_free()'d.
1112 gupnp_device_info_list_device_types (GUPnPDeviceInfo *info)
1114 GList *device_types;
1117 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1119 device_types = NULL;
1121 element = xml_util_get_element (info->priv->element,
1127 for (element = element->children; element; element = element->next) {
1128 if (!strcmp ("device", (char *) element->name)) {
1131 type = xml_util_get_child_element_content_glib
1132 (element, "deviceType");
1136 device_types = g_list_prepend (device_types, type);
1140 return device_types;
1144 * gupnp_device_info_get_device:
1145 * @info: A #GUPnPDeviceInfo
1146 * @type: The type of the device to be retrieved.
1148 * Get the service with type @type directly contained in @info as
1149 * a new object implementing #GUPnPDeviceInfo, or %NULL if no such device
1150 * was found. The returned object should be unreffed when done.
1152 * Note that devices are not cached internally, so that every time you call
1153 * this function a new object is created. The application must cache any used
1154 * devices if it wishes to keep them around and re-use them.
1156 * Returns: (transfer full)(allow-none): A new #GUPnPDeviceInfo.
1159 gupnp_device_info_get_device (GUPnPDeviceInfo *info,
1162 GUPnPDeviceInfoClass *class;
1163 GUPnPDeviceInfo *device;
1166 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1167 g_return_val_if_fail (type != NULL, NULL);
1169 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1171 g_return_val_if_fail (class->get_device, NULL);
1175 element = xml_util_get_element (info->priv->element,
1181 for (element = element->children; element; element = element->next) {
1182 if (!strcmp ("device", (char *) element->name)) {
1183 xmlNode *type_element;
1186 type_element = xml_util_get_element (element,
1192 type_str = xmlNodeGetContent (type_element);
1196 if (resource_type_match (type, (char *) type_str))
1197 device = class->get_device (info, element);
1209 * gupnp_device_info_list_services:
1210 * @info: A #GUPnPDeviceInfo
1212 * Get a #GList of new objects implementing #GUPnPServiceInfo representing the
1213 * services directly contained in @info. The returned list should be
1214 * g_list_free()'d and the elements should be g_object_unref()'d.
1216 * Note that services are not cached internally, so that every time you call
1217 * function new objects are created. The application must cache any used
1218 * services if it wishes to keep them around and re-use them.
1220 * Return value: (element-type GUPnP.ServiceInfo) (transfer full) : A #GList of
1221 * new #GUPnPServiceInfo objects.
1224 gupnp_device_info_list_services (GUPnPDeviceInfo *info)
1226 GUPnPDeviceInfoClass *class;
1230 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1232 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1234 g_return_val_if_fail (class->get_service, NULL);
1238 element = xml_util_get_element (info->priv->element,
1244 for (element = element->children; element; element = element->next) {
1245 if (!strcmp ("service", (char *) element->name)) {
1246 GUPnPServiceInfo *service;
1248 service = class->get_service (info, element);
1249 services = g_list_prepend (services, service);
1257 * gupnp_device_info_list_service_types:
1258 * @info: A #GUPnPDeviceInfo
1260 * Get a #GList of strings representing the types of the services
1261 * directly contained in @info.
1263 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1264 * elements should be g_free()'d and the list should be g_list_free()'d.
1267 gupnp_device_info_list_service_types (GUPnPDeviceInfo *info)
1269 GList *service_types;
1272 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1274 service_types = NULL;
1276 element = xml_util_get_element (info->priv->element,
1282 for (element = element->children; element; element = element->next) {
1283 if (!strcmp ("service", (char *) element->name)) {
1286 type = xml_util_get_child_element_content_glib
1287 (element, "serviceType");
1291 service_types = g_list_prepend (service_types, type);
1295 return service_types;
1299 * gupnp_device_info_get_service:
1300 * @info: A #GUPnPDeviceInfo
1301 * @type: The type of the service to be retrieved.
1303 * Get the service with type @type directly contained in @info as a new object
1304 * implementing #GUPnPServiceInfo, or %NULL if no such device was found. The
1305 * returned object should be unreffed when done.
1307 * Note that services are not cached internally, so that every time you call
1308 * this function a new object is created. The application must cache any used
1309 * services if it wishes to keep them around and re-use them.
1311 * Returns: (transfer full): A #GUPnPServiceInfo.
1314 gupnp_device_info_get_service (GUPnPDeviceInfo *info,
1317 GUPnPDeviceInfoClass *class;
1318 GUPnPServiceInfo *service;
1321 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1322 g_return_val_if_fail (type != NULL, NULL);
1324 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1326 g_return_val_if_fail (class->get_service, NULL);
1330 element = xml_util_get_element (info->priv->element,
1336 for (element = element->children; element; element = element->next) {
1337 if (!strcmp ("service", (char *) element->name)) {
1338 xmlNode *type_element;
1341 type_element = xml_util_get_element (element,
1347 type_str = xmlNodeGetContent (type_element);
1351 if (resource_type_match (type, (char *) type_str))
1352 service = class->get_service (info, element);
1364 /* Return associated xmlDoc */
1366 _gupnp_device_info_get_document (GUPnPDeviceInfo *info)
1368 return info->priv->doc;