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);
868 icon_free (icons->data);
869 icons = g_list_delete_link (icons, icons);
875 /* Returns TRUE if @query matches against @base.
876 * - If @query does not specify a version, it matches any version specified
878 * - If @query specifies a version, it matches any version specified in @base
879 * that is greater or equal.
882 resource_type_match (const char *query,
888 guint query_ver, base_ver;
890 /* Inspect last colon (if any!) on @base */
891 colon = strrchr (base, ':');
892 if (G_UNLIKELY (colon == NULL))
893 return !strcmp (query, base); /* No colon */
895 /* Length of type until last colon */
896 type_len = strlen (base) - strlen (colon);
898 /* Match initial portions */
899 match = (strncmp (query, base, type_len) == 0);
903 /* Initial portions matched. Try to position pointers after
904 * last colons of both @query and @base. */
906 if (G_UNLIKELY (*colon == 0))
912 return TRUE; /* @query does not specify a version */
915 if (G_UNLIKELY (*query == 0))
920 return FALSE; /* Hmm, not EOS, nor colon.. bad */
924 query_ver = atoi (query);
925 base_ver = atoi (colon);
927 /* Compare versions */
928 return (query_ver <= base_ver);
932 * gupnp_device_info_list_dlna_device_class_identifier:
933 * @info: A #GUPnPDeviceInfo
935 * Get a #GList of strings that represent the device class and version as
936 * announced in the device description file using the <dlna:X_DLNADOC>
938 * Returns: (transfer full) (element-type utf8): a #GList of newly allocated strings or
939 * %NULL if the device description doesn't contain the <dlna:X_DLNADOC>
943 gupnp_device_info_list_dlna_device_class_identifier (GUPnPDeviceInfo *info)
948 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
950 element = info->priv->element;
952 for (element = element->children; element; element = element->next) {
953 /* No early exit since the node explicitly may appear multiple
955 if (!strcmp ("X_DLNADOC", (char *) element->name))
956 list = g_list_prepend (list,
957 xmlNodeGetContent(element));
960 /* Return in order of appearance in document */
961 return g_list_reverse (list);
965 * gupnp_device_info_list_dlna_capabilities:
966 * @info: A #GUPnPDeviceInfo
968 * Get a #GList of strings that represent the device capabilities as announced
969 * in the device description file using the <dlna:X_DLNACAP> element.
971 * Returns: (transfer full) (element-type utf8): a #GList of newly allocated strings or
972 * %NULL if the device description doesn't contain the <dlna:X_DLNACAP>
976 gupnp_device_info_list_dlna_capabilities (GUPnPDeviceInfo *info)
980 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
982 caps = xml_util_get_child_element_content (info->priv->element,
987 const xmlChar *start = caps;
990 const xmlChar *end = start;
992 while (*end && *end != ',')
998 value = g_strndup ((const gchar *) start,
1001 list = g_list_prepend (list, value);
1012 return g_list_reverse (list);
1019 * gupnp_device_info_get_description_value:
1020 * @info: A #GUPnPDeviceInfo
1021 * @element: Name of the description element to retrieve
1023 * This function provides generic access to the contents of arbitrary elements
1024 * in the device description file.
1026 * Return value: a newly allocated string or %NULL if the device
1027 * description doesn't contain the given @element
1030 gupnp_device_info_get_description_value (GUPnPDeviceInfo *info,
1031 const char *element)
1033 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1034 g_return_val_if_fail (element != NULL, NULL);
1036 return xml_util_get_child_element_content_glib (info->priv->element,
1041 * gupnp_device_info_list_devices:
1042 * @info: A #GUPnPDeviceInfo
1044 * Get a #GList of new objects implementing #GUPnPDeviceInfo
1045 * representing the devices directly contained in @info. The returned list
1046 * should be g_list_free()'d and the elements should be g_object_unref()'d.
1048 * Note that devices are not cached internally, so that every time you
1049 * call this function new objects are created. The application
1050 * must cache any used devices if it wishes to keep them around and re-use
1053 * Return value: (element-type GUPnP.DeviceInfo) (transfer full): a #GList of
1054 * new #GUPnPDeviceInfo objects.
1057 gupnp_device_info_list_devices (GUPnPDeviceInfo *info)
1059 GUPnPDeviceInfoClass *class;
1063 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1065 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1067 g_return_val_if_fail (class->get_device, NULL);
1071 element = xml_util_get_element (info->priv->element,
1077 for (element = element->children; element; element = element->next) {
1078 if (!strcmp ("device", (char *) element->name)) {
1079 GUPnPDeviceInfo *child;
1081 child = class->get_device (info, element);
1082 devices = g_list_prepend (devices, child);
1090 * gupnp_device_info_list_device_types:
1091 * @info: A #GUPnPDeviceInfo
1093 * Get a #GList of strings representing the types of the devices
1094 * directly contained in @info.
1096 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1097 * elements should be g_free()'d and the list should be g_list_free()'d.
1100 gupnp_device_info_list_device_types (GUPnPDeviceInfo *info)
1102 GList *device_types;
1105 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1107 device_types = NULL;
1109 element = xml_util_get_element (info->priv->element,
1115 for (element = element->children; element; element = element->next) {
1116 if (!strcmp ("device", (char *) element->name)) {
1119 type = xml_util_get_child_element_content_glib
1120 (element, "deviceType");
1124 device_types = g_list_prepend (device_types, type);
1128 return device_types;
1132 * gupnp_device_info_get_device:
1133 * @info: A #GUPnPDeviceInfo
1134 * @type: The type of the device to be retrieved.
1136 * Get the service with type @type directly contained in @info as
1137 * a new object implementing #GUPnPDeviceInfo, or %NULL if no such device
1138 * was found. The returned object should be unreffed when done.
1140 * Note that devices are not cached internally, so that every time you call
1141 * this function a new object is created. The application must cache any used
1142 * devices if it wishes to keep them around and re-use them.
1144 * Returns: (transfer full)(allow-none): A new #GUPnPDeviceInfo.
1147 gupnp_device_info_get_device (GUPnPDeviceInfo *info,
1150 GUPnPDeviceInfoClass *class;
1151 GUPnPDeviceInfo *device;
1154 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1155 g_return_val_if_fail (type != NULL, NULL);
1157 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1159 g_return_val_if_fail (class->get_device, NULL);
1163 element = xml_util_get_element (info->priv->element,
1169 for (element = element->children; element; element = element->next) {
1170 if (!strcmp ("device", (char *) element->name)) {
1171 xmlNode *type_element;
1174 type_element = xml_util_get_element (element,
1180 type_str = xmlNodeGetContent (type_element);
1184 if (resource_type_match (type, (char *) type_str))
1185 device = class->get_device (info, element);
1197 * gupnp_device_info_list_services:
1198 * @info: A #GUPnPDeviceInfo
1200 * Get a #GList of new objects implementing #GUPnPServiceInfo representing the
1201 * services directly contained in @info. The returned list should be
1202 * g_list_free()'d and the elements should be g_object_unref()'d.
1204 * Note that services are not cached internally, so that every time you call
1205 * function new objects are created. The application must cache any used
1206 * services if it wishes to keep them around and re-use them.
1208 * Return value: (element-type GUPnP.ServiceInfo) (transfer full) : A #GList of
1209 * new #GUPnPServiceInfo objects.
1212 gupnp_device_info_list_services (GUPnPDeviceInfo *info)
1214 GUPnPDeviceInfoClass *class;
1218 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1220 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1222 g_return_val_if_fail (class->get_service, NULL);
1226 element = xml_util_get_element (info->priv->element,
1232 for (element = element->children; element; element = element->next) {
1233 if (!strcmp ("service", (char *) element->name)) {
1234 GUPnPServiceInfo *service;
1236 service = class->get_service (info, element);
1237 services = g_list_prepend (services, service);
1245 * gupnp_device_info_list_service_types:
1246 * @info: A #GUPnPDeviceInfo
1248 * Get a #GList of strings representing the types of the services
1249 * directly contained in @info.
1251 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1252 * elements should be g_free()'d and the list should be g_list_free()'d.
1255 gupnp_device_info_list_service_types (GUPnPDeviceInfo *info)
1257 GList *service_types;
1260 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1262 service_types = NULL;
1264 element = xml_util_get_element (info->priv->element,
1270 for (element = element->children; element; element = element->next) {
1271 if (!strcmp ("service", (char *) element->name)) {
1274 type = xml_util_get_child_element_content_glib
1275 (element, "serviceType");
1279 service_types = g_list_prepend (service_types, type);
1283 return service_types;
1287 * gupnp_device_info_get_service:
1288 * @info: A #GUPnPDeviceInfo
1289 * @type: The type of the service to be retrieved.
1291 * Get the service with type @type directly contained in @info as a new object
1292 * implementing #GUPnPServiceInfo, or %NULL if no such device was found. The
1293 * returned object should be unreffed when done.
1295 * Note that services are not cached internally, so that every time you call
1296 * this function a new object is created. The application must cache any used
1297 * services if it wishes to keep them around and re-use them.
1299 * Returns: (transfer full): A #GUPnPServiceInfo.
1302 gupnp_device_info_get_service (GUPnPDeviceInfo *info,
1305 GUPnPDeviceInfoClass *class;
1306 GUPnPServiceInfo *service;
1309 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1310 g_return_val_if_fail (type != NULL, NULL);
1312 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1314 g_return_val_if_fail (class->get_service, NULL);
1318 element = xml_util_get_element (info->priv->element,
1324 for (element = element->children; element; element = element->next) {
1325 if (!strcmp ("service", (char *) element->name)) {
1326 xmlNode *type_element;
1329 type_element = xml_util_get_element (element,
1335 type_str = xmlNodeGetContent (type_element);
1339 if (resource_type_match (type, (char *) type_str))
1340 service = class->get_service (info, element);
1352 /* Return associated xmlDoc */
1354 _gupnp_device_info_get_document (GUPnPDeviceInfo *info)
1356 return info->priv->doc;