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_get_pointer (value);
105 if (info->priv->url_base)
106 info->priv->url_base =
107 soup_uri_copy (info->priv->url_base);
111 info->priv->doc = g_value_dup_object (value);
114 info->priv->element = g_value_get_pointer (value);
117 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123 gupnp_device_info_get_property (GObject *object,
128 GUPnPDeviceInfo *info;
130 info = GUPNP_DEVICE_INFO (object);
132 switch (property_id) {
133 case PROP_RESOURCE_FACTORY:
134 g_value_set_object (value,
135 info->priv->factory);
138 g_value_set_object (value,
139 info->priv->context);
142 g_value_set_string (value,
143 info->priv->location);
146 g_value_set_string (value,
147 gupnp_device_info_get_udn (info));
149 case PROP_DEVICE_TYPE:
150 g_value_set_string (value,
151 gupnp_device_info_get_device_type (info));
154 g_value_set_pointer (value,
155 info->priv->url_base);
158 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
164 gupnp_device_info_dispose (GObject *object)
166 GUPnPDeviceInfo *info;
168 info = GUPNP_DEVICE_INFO (object);
170 if (info->priv->factory) {
171 g_object_unref (info->priv->factory);
172 info->priv->factory = NULL;
175 if (info->priv->context) {
176 g_object_unref (info->priv->context);
177 info->priv->context = NULL;
180 if (info->priv->doc) {
181 g_object_unref (info->priv->doc);
182 info->priv->doc = NULL;
185 G_OBJECT_CLASS (gupnp_device_info_parent_class)->dispose (object);
189 gupnp_device_info_finalize (GObject *object)
191 GUPnPDeviceInfo *info;
193 info = GUPNP_DEVICE_INFO (object);
195 g_free (info->priv->location);
196 g_free (info->priv->udn);
197 g_free (info->priv->device_type);
199 soup_uri_free (info->priv->url_base);
201 G_OBJECT_CLASS (gupnp_device_info_parent_class)->finalize (object);
205 gupnp_device_info_class_init (GUPnPDeviceInfoClass *klass)
207 GObjectClass *object_class;
209 object_class = G_OBJECT_CLASS (klass);
211 object_class->set_property = gupnp_device_info_set_property;
212 object_class->get_property = gupnp_device_info_get_property;
213 object_class->dispose = gupnp_device_info_dispose;
214 object_class->finalize = gupnp_device_info_finalize;
216 g_type_class_add_private (klass, sizeof (GUPnPDeviceInfoPrivate));
219 * GUPnPDeviceInfo:resource-factory:
221 * The resource factory to use. Set to NULL for default factory.
223 g_object_class_install_property
225 PROP_RESOURCE_FACTORY,
226 g_param_spec_object ("resource-factory",
228 "The resource factory to use",
229 GUPNP_TYPE_RESOURCE_FACTORY,
231 G_PARAM_CONSTRUCT_ONLY |
232 G_PARAM_STATIC_NAME |
233 G_PARAM_STATIC_NICK |
234 G_PARAM_STATIC_BLURB));
237 * GUPnPDeviceInfo:context:
239 * The #GUPnPContext to use.
241 g_object_class_install_property
244 g_param_spec_object ("context",
249 G_PARAM_CONSTRUCT_ONLY |
250 G_PARAM_STATIC_NAME |
251 G_PARAM_STATIC_NICK |
252 G_PARAM_STATIC_BLURB));
255 * GUPnPDeviceInfo:location:
257 * The location of the device description file.
259 g_object_class_install_property
262 g_param_spec_string ("location",
264 "The location of the device description "
268 G_PARAM_CONSTRUCT_ONLY |
269 G_PARAM_STATIC_NAME |
270 G_PARAM_STATIC_NICK |
271 G_PARAM_STATIC_BLURB));
274 * GUPnPDeviceInfo:udn:
276 * The UDN of this device.
278 g_object_class_install_property
281 g_param_spec_string ("udn",
286 G_PARAM_CONSTRUCT_ONLY |
287 G_PARAM_STATIC_NAME |
288 G_PARAM_STATIC_NICK |
289 G_PARAM_STATIC_BLURB));
292 * GUPnPDeviceInfo:device-type:
296 g_object_class_install_property
299 g_param_spec_string ("device-type",
304 G_PARAM_CONSTRUCT_ONLY |
305 G_PARAM_STATIC_NAME |
306 G_PARAM_STATIC_NICK |
307 G_PARAM_STATIC_BLURB));
310 * GUPnPDeviceInfo:url-base:
312 * The URL base (#SoupURI).
314 g_object_class_install_property
317 g_param_spec_pointer ("url-base",
321 G_PARAM_CONSTRUCT_ONLY |
322 G_PARAM_STATIC_NAME |
323 G_PARAM_STATIC_NICK |
324 G_PARAM_STATIC_BLURB));
327 * GUPnPDeviceInfo:document:
333 g_object_class_install_property
336 g_param_spec_object ("document",
338 "The XML document related to this "
342 G_PARAM_CONSTRUCT_ONLY |
343 G_PARAM_STATIC_NAME |
344 G_PARAM_STATIC_NICK |
345 G_PARAM_STATIC_BLURB));
348 * GUPnPDeviceInfo:element:
354 g_object_class_install_property
357 g_param_spec_pointer ("element",
359 "The XML element related to this "
362 G_PARAM_CONSTRUCT_ONLY |
363 G_PARAM_STATIC_NAME |
364 G_PARAM_STATIC_NICK |
365 G_PARAM_STATIC_BLURB));
369 * gupnp_device_info_get_resource_factory:
370 * @device_info: A #GUPnPDeviceInfo
372 * Get the #GUPnPResourceFactory used by the @device_info.
374 * Returns: (transfer none): A #GUPnPResourceFactory.
376 GUPnPResourceFactory *
377 gupnp_device_info_get_resource_factory (GUPnPDeviceInfo *info)
379 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
381 return info->priv->factory;
385 * gupnp_device_info_get_context:
386 * @info: A #GUPnPDeviceInfo
388 * Get the associated #GUPnPContext.
390 * Returns: (transfer none): A #GUPnPContext.
393 gupnp_device_info_get_context (GUPnPDeviceInfo *info)
395 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
397 return info->priv->context;
401 * gupnp_device_info_get_location:
402 * @info: A #GUPnPDeviceInfo
404 * Get the location of the device description file.
406 * Returns: A constant string.
409 gupnp_device_info_get_location (GUPnPDeviceInfo *info)
411 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
413 return info->priv->location;
417 * gupnp_device_info_get_url_base:
418 * @info: A #GUPnPDeviceInfo
420 * Get the URL base of this device.
422 * Returns: A #SoupURI.
425 gupnp_device_info_get_url_base (GUPnPDeviceInfo *info)
427 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
429 return info->priv->url_base;
433 * gupnp_device_info_get_udn:
434 * @info: A #GUPnPDeviceInfo
436 * Get the Unique Device Name of the device.
438 * Returns: A constant string.
441 gupnp_device_info_get_udn (GUPnPDeviceInfo *info)
443 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
445 if (!info->priv->udn) {
447 xml_util_get_child_element_content_glib
448 (info->priv->element, "UDN");
451 return info->priv->udn;
455 * gupnp_device_info_get_device_type:
456 * @info: A #GUPnPDeviceInfo
458 * Get the UPnP device type.
460 * Returns: A constant string, or %NULL.
463 gupnp_device_info_get_device_type (GUPnPDeviceInfo *info)
465 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
467 if (!info->priv->device_type) {
468 info->priv->device_type =
469 xml_util_get_child_element_content_glib
470 (info->priv->element, "deviceType");
473 return info->priv->device_type;
477 * gupnp_device_info_get_friendly_name:
478 * @info: A #GUPnPDeviceInfo
480 * Get the friendly name of the device.
482 * Return value: A string, or %NULL. g_free() after use.
485 gupnp_device_info_get_friendly_name (GUPnPDeviceInfo *info)
487 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
489 return xml_util_get_child_element_content_glib (info->priv->element,
494 * gupnp_device_info_get_manufacturer:
495 * @info: A #GUPnPDeviceInfo
497 * Get the manufacturer of the device.
499 * Return value: A string, or %NULL. g_free() after use.
502 gupnp_device_info_get_manufacturer (GUPnPDeviceInfo *info)
504 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
506 return xml_util_get_child_element_content_glib (info->priv->element,
511 * gupnp_device_info_get_manufacturer_url:
512 * @info: A #GUPnPDeviceInfo
514 * Get a URL pointing to the manufacturer's website.
516 * Return value: A string, or %NULL. g_free() after use.
519 gupnp_device_info_get_manufacturer_url (GUPnPDeviceInfo *info)
521 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
523 return xml_util_get_child_element_content_url (info->priv->element,
525 info->priv->url_base);
529 * gupnp_device_info_get_model_description:
530 * @info: A #GUPnPDeviceInfo
532 * Get the description of the device model.
534 * Return value: A string, or %NULL. g_free() after use.
537 gupnp_device_info_get_model_description (GUPnPDeviceInfo *info)
539 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
541 return xml_util_get_child_element_content_glib (info->priv->element,
546 * gupnp_device_info_get_model_name:
547 * @info: A #GUPnPDeviceInfo
549 * Get the model name of the device.
551 * Return value: A string, or %NULL. g_free() after use.
554 gupnp_device_info_get_model_name (GUPnPDeviceInfo *info)
556 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
558 return xml_util_get_child_element_content_glib (info->priv->element,
563 * gupnp_device_info_get_model_number:
564 * @info: A #GUPnPDeviceInfo
566 * Get the model number of the device.
568 * Return value: A string, or %NULL. g_free() after use.
571 gupnp_device_info_get_model_number (GUPnPDeviceInfo *info)
573 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
575 return xml_util_get_child_element_content_glib (info->priv->element,
580 * gupnp_device_info_get_model_url:
581 * @info: A #GUPnPDeviceInfo
583 * Get a URL pointing to the device model's website.
585 * Return value: A string, or %NULL. g_free() after use.
588 gupnp_device_info_get_model_url (GUPnPDeviceInfo *info)
590 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
592 return xml_util_get_child_element_content_url (info->priv->element,
594 info->priv->url_base);
598 * gupnp_device_info_get_serial_number:
599 * @info: A #GUPnPDeviceInfo
601 * Get the serial number of the device.
603 * Return value: A string, or %NULL. g_free() after use.
606 gupnp_device_info_get_serial_number (GUPnPDeviceInfo *info)
608 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
610 return xml_util_get_child_element_content_glib (info->priv->element,
615 * gupnp_device_info_get_upc:
616 * @info: A #GUPnPDeviceInfo
618 * Get the Universal Product Code of the device.
620 * Return value: A string, or %NULL. g_free() after use.
623 gupnp_device_info_get_upc (GUPnPDeviceInfo *info)
625 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
627 return xml_util_get_child_element_content_glib (info->priv->element,
632 * gupnp_device_info_get_presentation_url:
633 * @info: A #GUPnPDeviceInfo
635 * Get a URL pointing to the device's presentation page, for web-based
638 * Return value: A string, or %NULL. g_free() after use.
641 gupnp_device_info_get_presentation_url (GUPnPDeviceInfo *info)
643 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
645 return xml_util_get_child_element_content_url (info->priv->element,
647 info->priv->url_base);
661 icon_parse (GUPnPDeviceInfo *info, xmlNode *element)
665 icon = g_slice_new0 (Icon);
667 icon->mime_type = xml_util_get_child_element_content (element,
669 icon->width = xml_util_get_child_element_content_int (element,
671 icon->height = xml_util_get_child_element_content_int (element,
673 icon->depth = xml_util_get_child_element_content_int (element,
675 icon->url = xml_util_get_child_element_content (element,
682 icon_free (Icon *icon)
685 xmlFree (icon->mime_type);
690 g_slice_free (Icon, icon);
694 * gupnp_device_info_get_icon_url:
695 * @info: A #GUPnPDeviceInfo
696 * @requested_mime_type: (allow-none) (transfer none): The requested file
697 * format, or %NULL for any
698 * @requested_depth: The requested color depth, or -1 for any
699 * @requested_width: The requested width, or -1 for any
700 * @requested_height: The requested height, or -1 for any
701 * @prefer_bigger: %TRUE if a bigger, rather than a smaller icon should be
702 * returned if no exact match could be found
703 * @mime_type: (out) (allow-none): The location where to store the the format
704 * of the returned icon, or %NULL. The returned string should be freed after
706 * @depth: (out) (allow-none) : The location where to store the depth of the
707 * returned icon, or %NULL
708 * @width: (out) (allow-none) : The location where to store the width of the
709 * returned icon, or %NULL
710 * @height: (out) (allow-none) : The location where to store the height of the
711 * returned icon, or %NULL
713 * Get a URL pointing to the icon most closely matching the
714 * given criteria, or %NULL. If @requested_mime_type is set, only icons with
715 * this mime type will be returned. If @requested_depth is set, only icons with
716 * this or lower depth will be returned. If @requested_width and/or
717 * @requested_height are set, only icons that are this size or smaller are
718 * returned, unless @prefer_bigger is set, in which case the next biggest icon
719 * will be returned. The returned strings should be freed.
721 * Return value: (transfer full): a string, or %NULL. g_free() after use.
724 gupnp_device_info_get_icon_url (GUPnPDeviceInfo *info,
725 const char *requested_mime_type,
728 int requested_height,
729 gboolean prefer_bigger,
737 Icon *icon, *closest;
740 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
742 /* List available icons */
745 element = xml_util_get_element (info->priv->element,
751 for (element = element->children; element; element = element->next) {
752 if (!strcmp ("icon", (char *) element->name)) {
753 gboolean mime_type_ok;
755 icon = icon_parse (info, element);
757 if (requested_mime_type) {
759 !strcmp (requested_mime_type,
760 (char *) icon->mime_type);
764 if (requested_depth >= 0)
765 icon->weight = requested_depth - icon->depth;
767 /* Filter out icons with incorrect mime type or
768 * incorrect depth. */
769 if (mime_type_ok && icon->weight >= 0) {
770 if (requested_width >= 0) {
782 if (requested_height >= 0) {
794 icons = g_list_prepend (icons, icon);
803 /* Find closest match */
805 for (l = icons; l; l = l->next) {
808 /* Look between icons with positive weight first */
809 if (icon->weight >= 0) {
810 if (!closest || icon->weight < closest->weight)
816 for (l = icons; l; l = l->next) {
819 /* No icons with positive weight, look at ones with
821 if (!closest || icon->weight > closest->weight)
826 /* Fill in return values */
831 if (icon->mime_type) {
832 *mime_type = g_strdup
833 ((char *) icon->mime_type);
839 *depth = icon->depth;
841 *width = icon->width;
843 *height = icon->height;
848 uri = soup_uri_new_with_base (info->priv->url_base,
849 (const char *) icon->url);
850 ret = soup_uri_to_string (uri, FALSE);
869 icon_free (icons->data);
870 icons = g_list_delete_link (icons, icons);
876 /* Returns TRUE if @query matches against @base.
877 * - If @query does not specify a version, it matches any version specified
879 * - If @query specifies a version, it matches any version specified in @base
880 * that is greater or equal.
883 resource_type_match (const char *query,
889 guint query_ver, base_ver;
891 /* Inspect last colon (if any!) on @base */
892 colon = strrchr (base, ':');
893 if (G_UNLIKELY (colon == NULL))
894 return !strcmp (query, base); /* No colon */
896 /* Length of type until last colon */
897 type_len = strlen (base) - strlen (colon);
899 /* Match initial portions */
900 match = (strncmp (query, base, type_len) == 0);
904 /* Initial portions matched. Try to position pointers after
905 * last colons of both @query and @base. */
907 if (G_UNLIKELY (*colon == 0))
913 return TRUE; /* @query does not specify a version */
916 if (G_UNLIKELY (*query == 0))
921 return FALSE; /* Hmm, not EOS, nor colon.. bad */
925 query_ver = atoi (query);
926 base_ver = atoi (colon);
928 /* Compare versions */
929 return (query_ver <= base_ver);
933 * gupnp_device_info_list_dlna_capabilities:
934 * @info: A #GUPnPDeviceInfo
936 * Get a #GList of strings that represent the device capabilities as announced
937 * in the device description file using the <dlna:X_DLNACAP> element.
939 * Returns: (transfer full) (element-type utf8): a #GList of newly allocated strings or
940 * %NULL if the device description doesn't contain the <dlna:X_DLNACAP>
944 gupnp_device_info_list_dlna_capabilities (GUPnPDeviceInfo *info)
948 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
950 caps = xml_util_get_child_element_content (info->priv->element,
955 const xmlChar *start = caps;
958 const xmlChar *end = start;
960 while (*end && *end != ',')
966 value = g_strndup ((const gchar *) start,
969 list = g_list_prepend (list, value);
980 return g_list_reverse (list);
987 * gupnp_device_info_get_description_value:
988 * @info: A #GUPnPDeviceInfo
989 * @element: Name of the description element to retrieve
991 * This function provides generic access to the contents of arbitrary elements
992 * in the device description file.
994 * Return value: a newly allocated string or %NULL if the device
995 * description doesn't contain the given @element
998 gupnp_device_info_get_description_value (GUPnPDeviceInfo *info,
1001 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1002 g_return_val_if_fail (element != NULL, NULL);
1004 return xml_util_get_child_element_content_glib (info->priv->element,
1009 * gupnp_device_info_list_devices:
1010 * @info: A #GUPnPDeviceInfo
1012 * Get a #GList of new objects implementing #GUPnPDeviceInfo
1013 * representing the devices directly contained in @info. The returned list
1014 * should be g_list_free()'d and the elements should be g_object_unref()'d.
1016 * Note that devices are not cached internally, so that every time you
1017 * call this function new objects are created. The application
1018 * must cache any used devices if it wishes to keep them around and re-use
1021 * Return value: (element-type GUPnP.DeviceInfo) (transfer full): a #GList of
1022 * new #GUPnPDeviceInfo objects.
1025 gupnp_device_info_list_devices (GUPnPDeviceInfo *info)
1027 GUPnPDeviceInfoClass *class;
1031 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1033 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1035 g_return_val_if_fail (class->get_device, NULL);
1039 element = xml_util_get_element (info->priv->element,
1045 for (element = element->children; element; element = element->next) {
1046 if (!strcmp ("device", (char *) element->name)) {
1047 GUPnPDeviceInfo *child;
1049 child = class->get_device (info, element);
1050 devices = g_list_prepend (devices, child);
1058 * gupnp_device_info_list_device_types:
1059 * @info: A #GUPnPDeviceInfo
1061 * Get a #GList of strings representing the types of the devices
1062 * directly contained in @info.
1064 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1065 * elements should be g_free()'d and the list should be g_list_free()'d.
1068 gupnp_device_info_list_device_types (GUPnPDeviceInfo *info)
1070 GList *device_types;
1073 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1075 device_types = NULL;
1077 element = xml_util_get_element (info->priv->element,
1083 for (element = element->children; element; element = element->next) {
1084 if (!strcmp ("device", (char *) element->name)) {
1087 type = xml_util_get_child_element_content_glib
1088 (element, "deviceType");
1092 device_types = g_list_prepend (device_types, type);
1096 return device_types;
1100 * gupnp_device_info_get_device:
1101 * @info: A #GUPnPDeviceInfo
1102 * @type: The type of the device to be retrieved.
1104 * Get the service with type @type directly contained in @info as
1105 * a new object implementing #GUPnPDeviceInfo, or %NULL if no such device
1106 * was found. The returned object should be unreffed when done.
1108 * Note that devices are not cached internally, so that every time you call
1109 * this function a new object is created. The application must cache any used
1110 * devices if it wishes to keep them around and re-use them.
1112 * Returns: (transfer full): A new #GUPnPDeviceInfo.
1115 gupnp_device_info_get_device (GUPnPDeviceInfo *info,
1118 GUPnPDeviceInfoClass *class;
1119 GUPnPDeviceInfo *device;
1122 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1124 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1126 g_return_val_if_fail (class->get_device, NULL);
1130 element = xml_util_get_element (info->priv->element,
1136 for (element = element->children; element; element = element->next) {
1137 if (!strcmp ("device", (char *) element->name)) {
1138 xmlNode *type_element;
1141 type_element = xml_util_get_element (element,
1147 type_str = xmlNodeGetContent (type_element);
1151 if (resource_type_match (type, (char *) type_str))
1152 device = class->get_device (info, element);
1164 * gupnp_device_info_list_services:
1165 * @info: A #GUPnPDeviceInfo
1167 * Get a #GList of new objects implementing #GUPnPServiceInfo representing the
1168 * services directly contained in @info. The returned list should be
1169 * g_list_free()'d and the elements should be g_object_unref()'d.
1171 * Note that services are not cached internally, so that every time you call
1172 * function new objects are created. The application must cache any used
1173 * services if it wishes to keep them around and re-use them.
1175 * Return value: (element-type GUPnP.ServiceInfo) (transfer full) : A #GList of
1176 * new #GUPnPServiceInfo objects.
1179 gupnp_device_info_list_services (GUPnPDeviceInfo *info)
1181 GUPnPDeviceInfoClass *class;
1185 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1187 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1189 g_return_val_if_fail (class->get_service, NULL);
1193 element = xml_util_get_element (info->priv->element,
1199 for (element = element->children; element; element = element->next) {
1200 if (!strcmp ("service", (char *) element->name)) {
1201 GUPnPServiceInfo *service;
1203 service = class->get_service (info, element);
1204 services = g_list_prepend (services, service);
1212 * gupnp_device_info_list_service_types:
1213 * @info: A #GUPnPDeviceInfo
1215 * Get a #GList of strings representing the types of the services
1216 * directly contained in @info.
1218 * Return value: (element-type utf8) (transfer full): A #GList of strings. The
1219 * elements should be g_free()'d and the list should be g_list_free()'d.
1222 gupnp_device_info_list_service_types (GUPnPDeviceInfo *info)
1224 GList *service_types;
1227 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1229 service_types = NULL;
1231 element = xml_util_get_element (info->priv->element,
1237 for (element = element->children; element; element = element->next) {
1238 if (!strcmp ("service", (char *) element->name)) {
1241 type = xml_util_get_child_element_content_glib
1242 (element, "serviceType");
1246 service_types = g_list_prepend (service_types, type);
1250 return service_types;
1254 * gupnp_device_info_get_service:
1255 * @info: A #GUPnPDeviceInfo
1256 * @type: The type of the service to be retrieved.
1258 * Get the service with type @type directly contained in @info as a new object
1259 * implementing #GUPnPServiceInfo, or %NULL if no such device was found. The
1260 * returned object should be unreffed when done.
1262 * Note that services are not cached internally, so that every time you call
1263 * this function a new object is created. The application must cache any used
1264 * services if it wishes to keep them around and re-use them.
1266 * Returns: (transfer full): A #GUPnPServiceInfo.
1269 gupnp_device_info_get_service (GUPnPDeviceInfo *info,
1272 GUPnPDeviceInfoClass *class;
1273 GUPnPServiceInfo *service;
1276 g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL);
1278 class = GUPNP_DEVICE_INFO_GET_CLASS (info);
1280 g_return_val_if_fail (class->get_service, NULL);
1284 element = xml_util_get_element (info->priv->element,
1290 for (element = element->children; element; element = element->next) {
1291 if (!strcmp ("service", (char *) element->name)) {
1292 xmlNode *type_element;
1295 type_element = xml_util_get_element (element,
1301 type_str = xmlNodeGetContent (type_element);
1305 if (resource_type_match (type, (char *) type_str))
1306 service = class->get_service (info, element);
1318 /* Return associated xmlDoc */
1320 _gupnp_device_info_get_document (GUPnPDeviceInfo *info)
1322 return info->priv->doc;