static gboolean verify_didl_attributes (xmlNode *node) { const char *content; content = xml_util_get_child_element_content (node, "date"); if (content) { /* try to roughly verify the passed date with ^\d{4}-\d{2}-\d{2} */ char *ptr = (char *) content; int state = 0; while (*ptr) { if (state == 4 || state == 7) { if (*ptr != '-') return FALSE; } else { if (!isdigit (*ptr)) return FALSE; } ptr++; state++; if (state == 10) break; } } if (xml_util_get_attribute_content (node, "restricted") != NULL) { return xml_util_verify_attribute_is_boolean (node, "restricted"); } return TRUE; }
static Icon * icon_parse (GUPnPDeviceInfo *info, xmlNode *element) { Icon *icon; icon = g_slice_new0 (Icon); icon->mime_type = xml_util_get_child_element_content (element, "mimetype"); icon->width = xml_util_get_child_element_content_int (element, "width"); icon->height = xml_util_get_child_element_content_int (element, "height"); icon->depth = xml_util_get_child_element_content_int (element, "depth"); icon->url = xml_util_get_child_element_content (element, "url"); return icon; }
/* Search @element for matching services */ static void process_service_list (xmlNode *element, GUPnPControlPoint *control_point, GUPnPXMLDoc *doc, const char *udn, const char *service_type, const char *description_url, SoupURI *url_base) { g_object_ref (control_point); for (element = element->children; element; element = element->next) { xmlChar *prop; gboolean match; if (strcmp ((char *) element->name, "service") != 0) continue; /* See if this is a matching service */ prop = xml_util_get_child_element_content (element, "serviceType"); if (!prop) continue; match = compare_service_types_versioned (service_type, (char *) prop); xmlFree (prop); if (!match) continue; /* Match */ create_and_report_service_proxy (control_point, doc, element, udn, service_type, description_url, url_base); } g_object_unref (control_point); }
/** * gupnp_device_info_list_dlna_capabilities * @info: A #GUPnPDeviceInfo * * Get a #GList of strings that represent the device capabilities as announced * in the device description file using the <dlna:X_DLNACAP> element. * * Return value: (element-type utf8): a #GList of newly allocated strings or * %NULL if the device description doesn't contain the <dlna:X_DLNACAP> * element. **/ GList * gupnp_device_info_list_dlna_capabilities (GUPnPDeviceInfo *info) { xmlChar *caps; g_return_val_if_fail (GUPNP_IS_DEVICE_INFO (info), NULL); caps = xml_util_get_child_element_content (info->priv->element, "X_DLNACAP"); if (caps) { GList *list = NULL; const xmlChar *start = caps; while (*start) { const xmlChar *end = start; while (*end && *end != ',') end++; if (end > start) { gchar *value; value = g_strndup ((const gchar *) start, end - start); list = g_list_prepend (list, value); } if (*end) start = end + 1; else break; } xmlFree (caps); return g_list_reverse (list); } return NULL; }
/* Recursively search @element for matching devices */ static void process_device_list (xmlNode *element, GUPnPControlPoint *control_point, GUPnPXMLDoc *doc, const char *udn, const char *service_type, const char *description_url, SoupURI *url_base) { g_object_ref (control_point); for (element = element->children; element; element = element->next) { xmlNode *children; xmlChar *prop; gboolean match; if (strcmp ((char *) element->name, "device") != 0) continue; /* Recurse into children */ children = xml_util_get_element (element, "deviceList", NULL); if (children) { process_device_list (children, control_point, doc, udn, service_type, description_url, url_base); } /* See if this is a matching device */ prop = xml_util_get_child_element_content (element, "UDN"); if (!prop) continue; match = (strcmp ((char *) prop, udn) == 0); xmlFree (prop); if (!match) continue; /* Match */ if (service_type) { /* Dive into serviceList */ children = xml_util_get_element (element, "serviceList", NULL); if (children) { process_service_list (children, control_point, doc, udn, service_type, description_url, url_base); } } else create_and_report_device_proxy (control_point, doc, element, udn, description_url, url_base); } g_object_unref (control_point); }