Blame libgupnp-av/xml-util.c

Packit 712bc5
/*
Packit 712bc5
 * Copyright (C) 2006, 2007 OpenedHand Ltd.
Packit 712bc5
 * Copyright (C) 2007 Zeeshan Ali.
Packit 712bc5
 * Copyright (C) 2012 Intel Corporation
Packit 712bc5
 *
Packit 712bc5
 * Author: Jorn Baayen <jorn@openedhand.com>
Packit 712bc5
 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Packit 712bc5
 * Author: Krzesimir Nowak <krnowak@openismus.com>
Packit 712bc5
 *
Packit 712bc5
 * This library is free software; you can redistribute it and/or
Packit 712bc5
 * modify it under the terms of the GNU Library General Public
Packit 712bc5
 * License as published by the Free Software Foundation; either
Packit 712bc5
 * version 2 of the License, or (at your option) any later version.
Packit 712bc5
 *
Packit 712bc5
 * This library is distributed in the hope that it will be useful,
Packit 712bc5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 712bc5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 712bc5
 * Library General Public License for more details.
Packit 712bc5
 *
Packit 712bc5
 * You should have received a copy of the GNU Library General Public
Packit 712bc5
 * License along with this library; if not, write to the
Packit 712bc5
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit 712bc5
 * Boston, MA 02110-1301, USA.
Packit 712bc5
 */
Packit 712bc5
Packit 712bc5
#include <string.h>
Packit 712bc5
Packit 712bc5
#include "xml-util.h"
Packit 712bc5
Packit 712bc5
typedef struct _GUPnPXMLNamespaceDescription
Packit 712bc5
{
Packit 712bc5
        const char *uri;
Packit 712bc5
        const char *prefix;
Packit 712bc5
} GUPnPXMLNamespaceDescription;
Packit 712bc5
Packit 712bc5
Packit 712bc5
static GUPnPXMLNamespaceDescription gupnp_xml_namespaces[] =
Packit 712bc5
{
Packit 712bc5
        { "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/", NULL },
Packit 712bc5
        { "http://purl.org/dc/elements/1.1/", "dc" },
Packit 712bc5
        { "urn:schemas-dlna-org:metadata-1-0/", "dlna" },
Packit 712bc5
        { "http://www.pv.com/pvns/", "pv" },
Packit 712bc5
        { "urn:schemas-upnp-org:metadata-1-0/upnp/", "upnp" },
Packit 712bc5
        { NULL }
Packit 712bc5
};
Packit 712bc5
Packit 712bc5
GUPnPAVXMLDoc *
Packit 712bc5
xml_doc_new (xmlDoc *doc)
Packit 712bc5
{
Packit 712bc5
        GUPnPAVXMLDoc *ret = NULL;
Packit 712bc5
Packit 712bc5
        g_return_val_if_fail (doc, NULL);
Packit 712bc5
Packit 712bc5
        ret = g_new0 (GUPnPAVXMLDoc, 1);
Packit 712bc5
        ret->refcount = 1;
Packit 712bc5
        ret->doc = doc;
Packit 712bc5
Packit 712bc5
        return ret;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
GUPnPAVXMLDoc *
Packit 712bc5
xml_doc_ref (GUPnPAVXMLDoc *doc)
Packit 712bc5
{
Packit 712bc5
        g_return_val_if_fail (doc, NULL);
Packit 712bc5
        g_return_val_if_fail (doc->refcount > 0, NULL);
Packit 712bc5
        g_atomic_int_inc (&doc->refcount);
Packit 712bc5
Packit 712bc5
        return doc;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
void
Packit 712bc5
xml_doc_unref (GUPnPAVXMLDoc *doc)
Packit 712bc5
{
Packit 712bc5
        g_return_if_fail (doc);
Packit 712bc5
        g_return_if_fail (doc->refcount > 0);
Packit 712bc5
Packit 712bc5
        if (g_atomic_int_dec_and_test (&doc->refcount)) {
Packit 712bc5
                xmlFreeDoc (doc->doc);
Packit 712bc5
                doc->doc = NULL;
Packit 712bc5
        }
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
xmlNode *
Packit 712bc5
xml_util_get_element (xmlNode *node,
Packit 712bc5
                      ...)
Packit 712bc5
{
Packit 712bc5
        va_list var_args;
Packit 712bc5
Packit 712bc5
        va_start (var_args, node);
Packit 712bc5
Packit 712bc5
        while (TRUE) {
Packit 712bc5
                const char *arg;
Packit 712bc5
Packit 712bc5
                arg = va_arg (var_args, const char *);
Packit 712bc5
                if (!arg)
Packit 712bc5
                        break;
Packit 712bc5
Packit 712bc5
                for (node = node->children; node; node = node->next) {
Packit 712bc5
                        if (node->name == NULL)
Packit 712bc5
                                continue;
Packit 712bc5
Packit 712bc5
                        if (!g_ascii_strcasecmp (arg, (char *) node->name))
Packit 712bc5
                                break;
Packit 712bc5
                }
Packit 712bc5
Packit 712bc5
                if (!node)
Packit 712bc5
                        break;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        va_end (var_args);
Packit 712bc5
Packit 712bc5
        return node;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
GList *
Packit 712bc5
xml_util_get_child_elements_by_name (xmlNode *node, const char *name)
Packit 712bc5
{
Packit 712bc5
       GList *children = NULL;
Packit 712bc5
Packit 712bc5
       for (node = node->children; node; node = node->next) {
Packit 712bc5
               if (node->name == NULL)
Packit 712bc5
                       continue;
Packit 712bc5
Packit 712bc5
               if (strcmp (name, (char *) node->name) == 0) {
Packit 712bc5
                       children = g_list_append (children, node);
Packit 712bc5
               }
Packit 712bc5
       }
Packit 712bc5
Packit 712bc5
       return children;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
const char *
Packit 712bc5
xml_util_get_child_element_content (xmlNode    *node,
Packit 712bc5
                                    const char *child_name)
Packit 712bc5
{
Packit 712bc5
        xmlNode *child_node;
Packit 712bc5
        const char *content;
Packit 712bc5
Packit 712bc5
        child_node = xml_util_get_element (node, child_name, NULL);
Packit 712bc5
        if (!child_node || !(child_node->children))
Packit 712bc5
                return NULL;
Packit 712bc5
Packit 712bc5
        content = (const char *) child_node->children->content;
Packit 712bc5
        if (!content)
Packit 712bc5
                return NULL;
Packit 712bc5
Packit 712bc5
        return content;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
guint
Packit 712bc5
xml_util_get_uint_child_element (xmlNode    *node,
Packit 712bc5
                                 const char *child_name,
Packit 712bc5
                                 guint       default_value)
Packit 712bc5
{
Packit 712bc5
        const char *content;
Packit 712bc5
Packit 712bc5
        content = xml_util_get_child_element_content (node, child_name);
Packit 712bc5
        if (!content)
Packit 712bc5
                return default_value;
Packit 712bc5
Packit 712bc5
        return strtoul (content, NULL, 0);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
guint64
Packit 712bc5
xml_util_get_uint64_child_element (xmlNode    *node,
Packit 712bc5
                                   const char *child_name,
Packit 712bc5
                                   guint64     default_value)
Packit 712bc5
{
Packit 712bc5
        const char *content;
Packit 712bc5
Packit 712bc5
        content = xml_util_get_child_element_content (node, child_name);
Packit 712bc5
        if (!content)
Packit 712bc5
                return default_value;
Packit 712bc5
Packit 712bc5
        return g_ascii_strtoull (content, NULL, 0);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
const char *
Packit 712bc5
xml_util_get_attribute_content (xmlNode    *node,
Packit 712bc5
                                const char *attribute_name)
Packit 712bc5
{
Packit 712bc5
        xmlAttr *attribute;
Packit 712bc5
Packit 712bc5
        for (attribute = node->properties;
Packit 712bc5
             attribute;
Packit 712bc5
             attribute = attribute->next) {
Packit 712bc5
                if (attribute->name == NULL)
Packit 712bc5
                        continue;
Packit 712bc5
Packit 712bc5
                if (strcmp (attribute_name, (char *) attribute->name) == 0)
Packit 712bc5
                        break;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        if (attribute)
Packit 712bc5
                return (const char *) attribute->children->content;
Packit 712bc5
        else
Packit 712bc5
                return NULL;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
gboolean
Packit 712bc5
xml_util_get_boolean_attribute (xmlNode    *node,
Packit 712bc5
                                const char *attribute_name)
Packit 712bc5
{
Packit 712bc5
        const char *content;
Packit 712bc5
        gchar   *str;
Packit 712bc5
        gboolean ret;
Packit 712bc5
Packit 712bc5
        content = xml_util_get_attribute_content (node, attribute_name);
Packit 712bc5
        if (!content)
Packit 712bc5
                return FALSE;
Packit 712bc5
Packit 712bc5
        str = (char *) content;
Packit 712bc5
        if (g_ascii_strcasecmp (str, "true") == 0 ||
Packit 712bc5
            g_ascii_strcasecmp (str, "yes") == 0)
Packit 712bc5
                ret = TRUE;
Packit 712bc5
        else if (g_ascii_strcasecmp (str, "false") == 0 ||
Packit 712bc5
                 g_ascii_strcasecmp (str, "no") == 0)
Packit 712bc5
                ret = FALSE;
Packit 712bc5
        else {
Packit 712bc5
                int i;
Packit 712bc5
Packit 712bc5
                i = atoi (str);
Packit 712bc5
                ret = i ? TRUE : FALSE;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        return ret;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
guint
Packit 712bc5
xml_util_get_uint_attribute (xmlNode    *node,
Packit 712bc5
                             const char *attribute_name,
Packit 712bc5
                             guint       default_value)
Packit 712bc5
{
Packit 712bc5
        return (guint) xml_util_get_long_attribute (node,
Packit 712bc5
                                                    attribute_name,
Packit 712bc5
                                                    (glong) default_value);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
gint
Packit 712bc5
xml_util_get_int_attribute (xmlNode    *node,
Packit 712bc5
                            const char *attribute_name,
Packit 712bc5
                            gint        default_value)
Packit 712bc5
{
Packit 712bc5
        return (gint) xml_util_get_long_attribute (node,
Packit 712bc5
                                                   attribute_name,
Packit 712bc5
                                                   (glong) default_value);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
glong
Packit 712bc5
xml_util_get_long_attribute (xmlNode    *node,
Packit 712bc5
                             const char *attribute_name,
Packit 712bc5
                             glong       default_value)
Packit 712bc5
{
Packit 712bc5
    return (glong) xml_util_get_int64_attribute (node,
Packit 712bc5
                                                 attribute_name,
Packit 712bc5
                                                 (gint64) default_value);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
gint64
Packit 712bc5
xml_util_get_int64_attribute (xmlNode    *node,
Packit 712bc5
                              const char *attribute_name,
Packit 712bc5
                              gint64      default_value)
Packit 712bc5
{
Packit 712bc5
        const char *content;
Packit 712bc5
Packit 712bc5
        content = xml_util_get_attribute_content (node, attribute_name);
Packit 712bc5
        if (!content)
Packit 712bc5
                return default_value;
Packit 712bc5
Packit 712bc5
        return g_ascii_strtoll (content, NULL, 0);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
xmlNode *
Packit 712bc5
xml_util_set_child (xmlNode    *parent_node,
Packit 712bc5
                    GUPnPXMLNamespace ns,
Packit 712bc5
                    xmlNsPtr   *xmlns,
Packit 712bc5
                    xmlDoc     *doc,
Packit 712bc5
                    const char *name,
Packit 712bc5
                    const char *value)
Packit 712bc5
{
Packit 712bc5
        xmlNode *node;
Packit 712bc5
        xmlChar *escaped;
Packit 712bc5
Packit 712bc5
        node = xml_util_get_element (parent_node, name, NULL);
Packit 712bc5
        if (node == NULL) {
Packit 712bc5
                xmlNsPtr ns_ptr = NULL;
Packit 712bc5
Packit 712bc5
                ns_ptr = xml_util_get_ns (doc, ns, xmlns);
Packit 712bc5
                node = xmlNewChild (parent_node,
Packit 712bc5
                                    ns_ptr,
Packit 712bc5
                                    (unsigned char *) name,
Packit 712bc5
                                    NULL);
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        escaped = xmlEncodeSpecialChars (doc, (const unsigned char *) value);
Packit 712bc5
        xmlNodeSetContent (node, escaped);
Packit 712bc5
        xmlFree (escaped);
Packit 712bc5
Packit 712bc5
        return node;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
void
Packit 712bc5
xml_util_unset_child (xmlNode    *parent_node,
Packit 712bc5
                      const char *name)
Packit 712bc5
{
Packit 712bc5
        xmlNode *node;
Packit 712bc5
Packit 712bc5
        node = xml_util_get_element (parent_node, name, NULL);
Packit 712bc5
        if (node != NULL) {
Packit 712bc5
                xmlUnlinkNode (node);
Packit 712bc5
                xmlFreeNode (node);
Packit 712bc5
        }
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
gboolean
Packit 712bc5
xml_util_verify_attribute_is_boolean (xmlNode    *node,
Packit 712bc5
                                      const char *attribute_name)
Packit 712bc5
{
Packit 712bc5
        const char *content;
Packit 712bc5
        char *str;
Packit 712bc5
Packit 712bc5
        content = xml_util_get_attribute_content (node, attribute_name);
Packit 712bc5
        if (content == NULL)
Packit 712bc5
            return FALSE;
Packit 712bc5
Packit 712bc5
        str = (char *) content;
Packit 712bc5
Packit 712bc5
        return g_ascii_strcasecmp (str, "true") == 0 ||
Packit 712bc5
               g_ascii_strcasecmp (str, "yes") == 0 ||
Packit 712bc5
               g_ascii_strcasecmp (str, "false") == 0 ||
Packit 712bc5
               g_ascii_strcasecmp (str, "no") == 0 ||
Packit 712bc5
               g_ascii_strcasecmp (str, "0") == 0 ||
Packit 712bc5
               g_ascii_strcasecmp (str, "1") == 0;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
char *
Packit 712bc5
xml_util_get_child_string (xmlNode    *parent_node,
Packit 712bc5
                           xmlDoc     *doc,
Packit 712bc5
                           const char *name)
Packit 712bc5
{
Packit 712bc5
        xmlBuffer *buffer;
Packit 712bc5
        char      *ret;
Packit 712bc5
        xmlNode   *node;
Packit 712bc5
Packit 712bc5
        node = xml_util_get_element (parent_node, name, NULL);
Packit 712bc5
        if (!node)
Packit 712bc5
                return NULL;
Packit 712bc5
Packit 712bc5
        buffer = xmlBufferCreate ();
Packit 712bc5
        xmlNodeDump (buffer,
Packit 712bc5
                     doc,
Packit 712bc5
                     node,
Packit 712bc5
                     0,
Packit 712bc5
                     0);
Packit 712bc5
        ret = g_strndup ((char *) xmlBufferContent (buffer),
Packit 712bc5
                         xmlBufferLength (buffer));
Packit 712bc5
        xmlBufferFree (buffer);
Packit 712bc5
Packit 712bc5
        return ret;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
gboolean
Packit 712bc5
xml_util_node_deep_equal (xmlNode *first,
Packit 712bc5
                          xmlNode *second)
Packit 712bc5
{
Packit 712bc5
        GHashTable *first_attributes;
Packit 712bc5
        xmlAttr *attribute;
Packit 712bc5
        gboolean equal;
Packit 712bc5
Packit 712bc5
        if (first == NULL && second == NULL)
Packit 712bc5
                return TRUE;
Packit 712bc5
        if (first == NULL || second == NULL)
Packit 712bc5
                return FALSE;
Packit 712bc5
Packit 712bc5
        if (xmlStrcmp (first->name, second->name))
Packit 712bc5
                return FALSE;
Packit 712bc5
Packit 712bc5
        equal = FALSE;
Packit 712bc5
        first_attributes = xml_util_get_attributes_map (first);
Packit 712bc5
        /* compare attributes */
Packit 712bc5
        for (attribute = second->properties;
Packit 712bc5
             attribute != NULL;
Packit 712bc5
             attribute = attribute->next) {
Packit 712bc5
                const xmlChar *value = NULL;
Packit 712bc5
                const xmlChar *key = attribute->name;
Packit 712bc5
Packit 712bc5
                if (g_hash_table_lookup_extended (first_attributes,
Packit 712bc5
                                                  key,
Packit 712bc5
                                                  NULL,
Packit 712bc5
                                                  (gpointer *) &value))
Packit 712bc5
                        if (!xmlStrcmp (value, attribute->children->content)) {
Packit 712bc5
                                g_hash_table_remove (first_attributes, key);
Packit 712bc5
Packit 712bc5
                                continue;
Packit 712bc5
                        }
Packit 712bc5
Packit 712bc5
                goto out;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        if (g_hash_table_size (first_attributes))
Packit 712bc5
                goto out;
Packit 712bc5
Packit 712bc5
        /* compare content */
Packit 712bc5
        if (xmlStrcmp (first->content, second->content))
Packit 712bc5
                goto out;
Packit 712bc5
        equal = TRUE;
Packit 712bc5
 out:
Packit 712bc5
        g_hash_table_unref (first_attributes);
Packit 712bc5
        if (equal) {
Packit 712bc5
                xmlNode *first_child;
Packit 712bc5
                xmlNode *second_child;
Packit 712bc5
Packit 712bc5
                for (first_child = first->children,
Packit 712bc5
                     second_child = second->children;
Packit 712bc5
                     first_child != NULL && second_child != NULL;
Packit 712bc5
                     first_child = first_child->next,
Packit 712bc5
                     second_child = second_child->next)
Packit 712bc5
                        if (!xml_util_node_deep_equal (first_child, second_child))
Packit 712bc5
                                return FALSE;
Packit 712bc5
                if (first_child != NULL || second_child != NULL)
Packit 712bc5
                        return FALSE;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        return equal;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
xmlNode *
Packit 712bc5
xml_util_find_node (xmlNode *haystack,
Packit 712bc5
                    xmlNode *needle)
Packit 712bc5
{
Packit 712bc5
        xmlNodePtr iter;
Packit 712bc5
Packit 712bc5
        if (xml_util_node_deep_equal (haystack, needle))
Packit 712bc5
                return haystack;
Packit 712bc5
Packit 712bc5
        for (iter = haystack->children; iter != NULL; iter = iter->next) {
Packit 712bc5
                xmlNodePtr found_node = xml_util_find_node (iter, needle);
Packit 712bc5
Packit 712bc5
                if (found_node != NULL)
Packit 712bc5
                        return found_node;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        return NULL;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
xmlNode *
Packit 712bc5
xml_util_copy_node (xmlNode *node)
Packit 712bc5
{
Packit 712bc5
        xmlNode *dup = xmlCopyNode (node, 1);
Packit 712bc5
Packit 712bc5
        /* TODO: remove useless namespace definition. */
Packit 712bc5
Packit 712bc5
        return dup;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
GHashTable *
Packit 712bc5
xml_util_get_attributes_map (xmlNode *node)
Packit 712bc5
{
Packit 712bc5
        xmlAttr *attribute;
Packit 712bc5
        GHashTable *attributes_map = g_hash_table_new (g_str_hash,
Packit 712bc5
                                                       g_str_equal);
Packit 712bc5
Packit 712bc5
        for (attribute = node->properties;
Packit 712bc5
             attribute != NULL;
Packit 712bc5
             attribute = attribute->next)
Packit 712bc5
                g_hash_table_insert (attributes_map,
Packit 712bc5
                                     (gpointer) attribute->name,
Packit 712bc5
                                     (gpointer) attribute->children->content);
Packit 712bc5
Packit 712bc5
        return attributes_map;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
/**
Packit 712bc5
 * xml_util_create_namespace:
Packit 712bc5
 * @root: (allow-none): Document root node or %NULL for anonymous ns.
Packit 712bc5
 * @ns: Namespace
Packit 712bc5
 * @returns: Newly created namespace on root node
Packit 712bc5
 */
Packit 712bc5
xmlNsPtr
Packit 712bc5
xml_util_create_namespace (xmlNodePtr root, GUPnPXMLNamespace ns)
Packit 712bc5
{
Packit 712bc5
        g_return_val_if_fail (ns < GUPNP_XML_NAMESPACE_COUNT, NULL);
Packit 712bc5
Packit 712bc5
        return xmlNewNs (root,
Packit 712bc5
                         (const xmlChar *) gupnp_xml_namespaces[ns].uri,
Packit 712bc5
                         (const xmlChar *) gupnp_xml_namespaces[ns].prefix);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
/**
Packit 712bc5
 * xml_util_lookup_namespace:
Packit 712bc5
 * @doc: #xmlDoc
Packit 712bc5
 * @ns: namespace to look up (except DIDL-Lite, which doesn't have a prefix)
Packit 712bc5
 * @returns: %NULL if namespace does not exist, a pointer to the namespace
Packit 712bc5
 * otherwise.
Packit 712bc5
 */
Packit 712bc5
xmlNsPtr
Packit 712bc5
xml_util_lookup_namespace (xmlDocPtr doc, GUPnPXMLNamespace ns)
Packit 712bc5
{
Packit 712bc5
        xmlNsPtr *ns_list, *it, retval = NULL;
Packit 712bc5
        const char *ns_prefix = NULL;
Packit 712bc5
        const char *ns_uri = NULL;
Packit 712bc5
Packit 712bc5
        g_return_val_if_fail (ns < GUPNP_XML_NAMESPACE_COUNT, NULL);
Packit 712bc5
Packit 712bc5
        ns_prefix = gupnp_xml_namespaces[ns].prefix;
Packit 712bc5
        ns_uri = gupnp_xml_namespaces[ns].uri;
Packit 712bc5
Packit 712bc5
        ns_list = xmlGetNsList (doc, xmlDocGetRootElement (doc));
Packit 712bc5
        if (ns_list == NULL)
Packit 712bc5
                return NULL;
Packit 712bc5
Packit 712bc5
        for (it = ns_list; *it != NULL; it++) {
Packit 712bc5
                const char *it_prefix = (const char *) (*it)->prefix;
Packit 712bc5
                const char *it_uri = (const char *) (*it)->href;
Packit 712bc5
Packit 712bc5
                if (it_prefix == NULL) {
Packit 712bc5
                        if (ns_prefix != NULL)
Packit 712bc5
                                continue;
Packit 712bc5
Packit 712bc5
                        if (g_ascii_strcasecmp (it_uri, ns_uri) == 0) {
Packit 712bc5
                                retval = *it;
Packit 712bc5
                                break;
Packit 712bc5
                        }
Packit 712bc5
Packit 712bc5
                        continue;
Packit 712bc5
                }
Packit 712bc5
Packit 712bc5
                if (g_ascii_strcasecmp (it_prefix, ns_prefix) == 0) {
Packit 712bc5
                        retval = *it;
Packit 712bc5
                        break;
Packit 712bc5
                }
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        xmlFree (ns_list);
Packit 712bc5
Packit 712bc5
        return retval;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
/**
Packit 712bc5
 * xml_util_get_ns:
Packit 712bc5
 * @doc: A #xmlDoc.
Packit 712bc5
 * @ns: A #GUPnPXMLNamespace.
Packit 712bc5
 * @ns_out: (out) (allow-none): return location for the namespace or %NULL.
Packit 712bc5
 *
Packit 712bc5
 * Lazy-create a XML namespace on @doc.
Packit 712bc5
 *
Packit 712bc5
 * If @ns_out is non-%NULL, the function will return @ns_out immediately.
Packit 712bc5
 * @returns: either the existing #xmlNsPtr or a newly created one.
Packit 712bc5
 */
Packit 712bc5
xmlNsPtr
Packit 712bc5
xml_util_get_ns (xmlDocPtr doc, GUPnPXMLNamespace ns, xmlNsPtr *ns_out)
Packit 712bc5
{
Packit 712bc5
        xmlNsPtr tmp_ns;
Packit 712bc5
Packit 712bc5
        /* User supplied namespace, just return that */
Packit 712bc5
        if (ns_out != NULL && *ns_out != NULL)
Packit 712bc5
                return *ns_out;
Packit 712bc5
Packit 712bc5
        tmp_ns = xml_util_lookup_namespace (doc, ns);
Packit 712bc5
        if (!tmp_ns)
Packit 712bc5
                tmp_ns = xml_util_create_namespace (xmlDocGetRootElement (doc),
Packit 712bc5
                                                    ns);
Packit 712bc5
Packit 712bc5
        if (ns_out != NULL)
Packit 712bc5
                *ns_out = tmp_ns;
Packit 712bc5
Packit 712bc5
        return tmp_ns;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
G_DEFINE_BOXED_TYPE (GUPnPAVXMLDoc, xml_doc, xml_doc_ref, xml_doc_unref)