Blame libgupnp-av/gupnp-feature-list-parser.c

Packit 712bc5
/*
Packit 712bc5
 * Copyright (C) 2012 Intel Corporation.
Packit 712bc5
 *
Packit 712bc5
 * Authors: Regis Merlino <regis.merlino@intel.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
/**
Packit 712bc5
 * SECTION:gupnp-feature-list-parser
Packit 712bc5
 * @short_description: FeatureList state variable XML parser
Packit 712bc5
 *
Packit 712bc5
 * #GUPnPFeatureListParser parses XML strings from ContentDirectory
Packit 712bc5
 * FeatureList state variable.
Packit 712bc5
 *
Packit 712bc5
 */
Packit 712bc5
Packit 712bc5
#include <string.h>
Packit 712bc5
#include "gupnp-feature-list-parser.h"
Packit 712bc5
#include "gupnp-av.h"
Packit 712bc5
#include "xml-util.h"
Packit 712bc5
Packit 712bc5
/* GUPnPFeatureListParser */
Packit 712bc5
G_DEFINE_TYPE (GUPnPFeatureListParser,
Packit 712bc5
               gupnp_feature_list_parser,
Packit 712bc5
               G_TYPE_OBJECT);
Packit 712bc5
Packit 712bc5
static void
Packit 712bc5
gupnp_feature_list_parser_init (G_GNUC_UNUSED GUPnPFeatureListParser *parser)
Packit 712bc5
{
Packit 712bc5
        /* Nothing to do here */
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
static void
Packit 712bc5
gupnp_feature_list_parser_finalize (GObject *object)
Packit 712bc5
{
Packit 712bc5
        GObjectClass *object_class;
Packit 712bc5
Packit 712bc5
        object_class = G_OBJECT_CLASS (gupnp_feature_list_parser_parent_class);
Packit 712bc5
        object_class->finalize (object);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
static void
Packit 712bc5
gupnp_feature_list_parser_class_init (GUPnPFeatureListParserClass *klass)
Packit 712bc5
{
Packit 712bc5
        GObjectClass *object_class;
Packit 712bc5
Packit 712bc5
        object_class = G_OBJECT_CLASS (klass);
Packit 712bc5
Packit 712bc5
        object_class->finalize = gupnp_feature_list_parser_finalize;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
/**
Packit 712bc5
 * gupnp_feature_list_parser_new:
Packit 712bc5
 *
Packit 712bc5
 * Return value: A new #GUPnPFeatureListParser object.
Packit 712bc5
 **/
Packit 712bc5
GUPnPFeatureListParser *
Packit 712bc5
gupnp_feature_list_parser_new (void)
Packit 712bc5
{
Packit 712bc5
        return g_object_new (GUPNP_TYPE_FEATURE_LIST_PARSER, NULL);
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
static char *
Packit 712bc5
get_feature_object_ids (xmlNode *feature)
Packit 712bc5
{
Packit 712bc5
        xmlNode    *element;
Packit 712bc5
        char       *object_ids = NULL;
Packit 712bc5
        const char *content;
Packit 712bc5
Packit 712bc5
        object_ids = (char *) g_malloc0(1);
Packit 712bc5
Packit 712bc5
        for (element = feature->children; element; element = element->next) {
Packit 712bc5
                gsize new_size;
Packit 712bc5
Packit 712bc5
                if (g_ascii_strcasecmp ((char *) element->name,
Packit 712bc5
                                        "objectIDs") == 0) {
Packit 712bc5
                        content = (const char *) xmlNodeGetContent (element);
Packit 712bc5
Packit 712bc5
                        new_size = strlen (object_ids) + strlen (content) + 1;
Packit 712bc5
                        if (*object_ids)
Packit 712bc5
                                new_size++;
Packit 712bc5
Packit 712bc5
                        object_ids = g_realloc (object_ids, new_size);
Packit 712bc5
Packit 712bc5
                        if (*object_ids)
Packit 712bc5
                                strcat (object_ids, ",");
Packit 712bc5
                        strcat (object_ids, content);
Packit 712bc5
                }
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        return object_ids;
Packit 712bc5
}
Packit 712bc5
Packit 712bc5
/**
Packit 712bc5
 * gupnp_feature_list_parser_parse_text:
Packit 712bc5
 * @parser: A #GUPnPFeatureListParser
Packit 712bc5
 * @text: The feature list string to be parsed
Packit 712bc5
 * @error: The location where to store the error information if any, or NULL
Packit 712bc5
 *
Packit 712bc5
 * Parses @text and returns the list of available features.
Packit 712bc5
 * If an error occured @error will be set.
Packit 712bc5
 *
Packit 712bc5
 * Return value: (transfer full) (element-type GUPnPFeature): The list of
Packit 712bc5
 * features or %NULL if an error occured.
Packit 712bc5
 **/
Packit 712bc5
GList *
Packit 712bc5
gupnp_feature_list_parser_parse_text
Packit 712bc5
                                 (G_GNUC_UNUSED GUPnPFeatureListParser *parser,
Packit 712bc5
                                  const char             *text,
Packit 712bc5
                                  GError                **error)
Packit 712bc5
{
Packit 712bc5
        xmlDoc       *doc;
Packit 712bc5
        xmlNode      *element;
Packit 712bc5
        GList        *feature_list = NULL;
Packit 712bc5
Packit 712bc5
        doc = xmlRecoverMemory (text, strlen (text));
Packit 712bc5
        if (doc == NULL) {
Packit 712bc5
                g_set_error (error,
Packit 712bc5
                             G_MARKUP_ERROR,
Packit 712bc5
                             G_MARKUP_ERROR_PARSE,
Packit 712bc5
                             "Could not parse FeatureList XML:\n%s", text);
Packit 712bc5
Packit 712bc5
                return NULL;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        /* Get a pointer to root element */
Packit 712bc5
        element = xml_util_get_element ((xmlNode *) doc, "Features", NULL);
Packit 712bc5
        if (element == NULL) {
Packit 712bc5
                g_set_error (error,
Packit 712bc5
                             G_MARKUP_ERROR,
Packit 712bc5
                             G_MARKUP_ERROR_PARSE,
Packit 712bc5
                             "No 'Features' node in the XML:\n%s",
Packit 712bc5
                             text);
Packit 712bc5
                xmlFreeDoc (doc);
Packit 712bc5
Packit 712bc5
                return NULL;
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        for (element = element->children; element; element = element->next) {
Packit 712bc5
                GUPnPFeature *feature;
Packit 712bc5
                const char   *name;
Packit 712bc5
                const char   *version;
Packit 712bc5
                char         *object_ids;
Packit 712bc5
Packit 712bc5
                if (g_ascii_strcasecmp ((char *) element->name,
Packit 712bc5
                                        "Feature") == 0) {
Packit 712bc5
                        name = xml_util_get_attribute_content (element, "name");
Packit 712bc5
                        version = xml_util_get_attribute_content (element,
Packit 712bc5
                                                                  "version");
Packit 712bc5
                        if (!name || !version) {
Packit 712bc5
                                g_set_error (error,
Packit 712bc5
                                             G_MARKUP_ERROR,
Packit 712bc5
                                             G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
Packit 712bc5
                                             "Invalid attributes in 'Feature' "
Packit 712bc5
                                             "node in the XML:\n%s",
Packit 712bc5
                                             text);
Packit 712bc5
Packit 712bc5
                                xmlFreeDoc (doc);
Packit 712bc5
                                if (feature_list)
Packit 712bc5
                                        g_list_free_full (feature_list,
Packit 712bc5
                                                          g_object_unref);
Packit 712bc5
Packit 712bc5
                                return NULL;
Packit 712bc5
                        }
Packit 712bc5
Packit 712bc5
                        object_ids = get_feature_object_ids (element);
Packit 712bc5
Packit 712bc5
                        feature = g_object_new (GUPNP_TYPE_FEATURE,
Packit 712bc5
                                                "name", name,
Packit 712bc5
                                                "version", version,
Packit 712bc5
                                                "object-ids", object_ids,
Packit 712bc5
                                                NULL);
Packit 712bc5
Packit 712bc5
                        feature_list = g_list_append (feature_list, feature);
Packit 712bc5
Packit 712bc5
                        g_free (object_ids);
Packit 712bc5
                }
Packit 712bc5
        }
Packit 712bc5
Packit 712bc5
        xmlFreeDoc (doc);
Packit 712bc5
Packit 712bc5
        return feature_list;
Packit 712bc5
}