[gupnp-av] Add ContentDirectory FeatureList state variable XML parser



commit 0ba56f38227beb00c25dbaa260c64d86028c2d9a
Author: Regis Merlino <regis merlino intel com>
Date:   Thu Oct 11 09:45:56 2012 +0200

    Add ContentDirectory FeatureList state variable XML parser
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685963

 libgupnp-av/Makefile.am                 |    6 +
 libgupnp-av/gupnp-av.h                  |    2 +
 libgupnp-av/gupnp-feature-list-parser.c |  195 ++++++++++++++++++++++++++
 libgupnp-av/gupnp-feature-list-parser.h |   72 ++++++++++
 libgupnp-av/gupnp-feature.c             |  232 +++++++++++++++++++++++++++++++
 libgupnp-av/gupnp-feature.h             |   76 ++++++++++
 6 files changed, 583 insertions(+), 0 deletions(-)
---
diff --git a/libgupnp-av/Makefile.am b/libgupnp-av/Makefile.am
index 464fea5..3fbb02a 100644
--- a/libgupnp-av/Makefile.am
+++ b/libgupnp-av/Makefile.am
@@ -27,6 +27,8 @@ libgupnp_av_inc_HEADERS = gupnp-didl-lite-object.h \
 			  gupnp-protocol-info.h \
 		          gupnp-search-criteria-parser.h \
 			  gupnp-last-change-parser.h \
+			  gupnp-feature.h \
+			  gupnp-feature-list-parser.h \
 			  gupnp-dlna.h \
 			  gupnp-av-error.h \
 			  gupnp-av.h
@@ -61,6 +63,8 @@ libgupnp_av_1_0_la_SOURCES = gupnp-didl-lite-object.c \
 			     gupnp-protocol-info.c \
 			     gupnp-search-criteria-parser.c \
 			     gupnp-last-change-parser.c \
+			     gupnp-feature.c \
+			     gupnp-feature-list-parser.c \
 			     gupnp-dlna.c \
 			     gupnp-av-error.c \
 			     xml-util.c \
@@ -94,6 +98,8 @@ introspection_sources = \
 	    $(top_srcdir)/libgupnp-av/gupnp-protocol-info.c \
 	    $(top_srcdir)/libgupnp-av/gupnp-search-criteria-parser.c \
 	    $(top_srcdir)/libgupnp-av/gupnp-last-change-parser.c \
+	    $(top_srcdir)/libgupnp-av/gupnp-feature.c \
+	    $(top_srcdir)/libgupnp-av/gupnp-feature-list-parser.c \
 	    $(top_srcdir)/libgupnp-av/gupnp-dlna.c \
 	    $(top_srcdir)/libgupnp-av/gupnp-av-error.c
 
diff --git a/libgupnp-av/gupnp-av.h b/libgupnp-av/gupnp-av.h
index 0a822a3..005cf0a 100644
--- a/libgupnp-av/gupnp-av.h
+++ b/libgupnp-av/gupnp-av.h
@@ -32,5 +32,7 @@
 #include "gupnp-protocol-info.h"
 #include "gupnp-search-criteria-parser.h"
 #include "gupnp-last-change-parser.h"
+#include "gupnp-feature.h"
+#include "gupnp-feature-list-parser.h"
 #include "gupnp-dlna.h"
 
diff --git a/libgupnp-av/gupnp-feature-list-parser.c b/libgupnp-av/gupnp-feature-list-parser.c
new file mode 100644
index 0000000..df7c81c
--- /dev/null
+++ b/libgupnp-av/gupnp-feature-list-parser.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Regis Merlino <regis merlino intel com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gupnp-feature-list-parser
+ * @short_description: FeatureList state variable XML parser
+ *
+ * #GUPnPFeatureListParser parses XML strings from ContentDirectory
+ * FeatureList state variable.
+ *
+ */
+
+#include <string.h>
+#include "gupnp-feature-list-parser.h"
+#include "gupnp-av.h"
+#include "xml-util.h"
+
+/* GUPnPFeatureListParser */
+G_DEFINE_TYPE (GUPnPFeatureListParser,
+               gupnp_feature_list_parser,
+               G_TYPE_OBJECT);
+
+static void
+gupnp_feature_list_parser_init (GUPnPFeatureListParser *parser)
+{
+        /* Nothing to do here */
+}
+
+static void
+gupnp_feature_list_parser_finalize (GObject *object)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (gupnp_feature_list_parser_parent_class);
+        object_class->finalize (object);
+}
+
+static void
+gupnp_feature_list_parser_class_init (GUPnPFeatureListParserClass *klass)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = gupnp_feature_list_parser_finalize;
+}
+
+/**
+ * gupnp_feature_list_parser_new:
+ *
+ * Return value: A new #GUPnPFeatureListParser object.
+ **/
+GUPnPFeatureListParser *
+gupnp_feature_list_parser_new (void)
+{
+        return g_object_new (GUPNP_TYPE_FEATURE_LIST_PARSER, NULL);
+}
+
+static char *
+get_feature_object_ids (xmlNode *feature)
+{
+        xmlNode    *element;
+        char       *object_ids = NULL;
+        const char *content;
+
+        object_ids = (char *) g_malloc0(1);
+
+        for (element = feature->children; element; element = element->next) {
+                gsize new_size;
+
+                if (g_ascii_strcasecmp ((char *) element->name,
+                                        "objectIDs") == 0) {
+                        content = (const char *) xmlNodeGetContent (element);
+
+                        new_size = strlen (object_ids) + strlen (content) + 1;
+                        if (*object_ids)
+                                new_size++;
+
+                        object_ids = g_realloc (object_ids, new_size);
+
+                        if (*object_ids)
+                                strcat (object_ids, ",");
+                        strcat (object_ids, content);
+                }
+        }
+
+        return object_ids;
+}
+
+/**
+ * gupnp_feature_list_parser_parse_text:
+ * @parser: A #GUPnPFeatureListParser
+ * @text: The feature list string to be parsed
+ * @error: The location where to store the error information if any, or NULL
+ *
+ * Parses @text and returns the list of available features.
+ * If an error occured @error will be set.
+ *
+ * Return value: The list of features or %NULL if an error occured.
+ **/
+GList *
+gupnp_feature_list_parser_parse_text (GUPnPFeatureListParser *parser,
+                                         const char          *text,
+                                         GError              **error)
+{
+        xmlDoc       *doc;
+        xmlNode      *element;
+        GList        *feature_list = NULL;
+
+        doc = xmlRecoverMemory (text, strlen (text));
+        if (doc == NULL) {
+                g_set_error (error,
+                             GUPNP_XML_ERROR,
+                             GUPNP_XML_ERROR_PARSE,
+                             "Could not parse FeatureList XML:\n%s", text);
+
+                return NULL;
+        }
+
+        /* Get a pointer to root element */
+        element = xml_util_get_element ((xmlNode *) doc, "Features", NULL);
+        if (element == NULL) {
+                g_set_error (error,
+                             GUPNP_XML_ERROR,
+                             GUPNP_XML_ERROR_NO_NODE,
+                             "No 'Features' node in the XML:\n%s",
+                             text);
+                xmlFreeDoc (doc);
+
+                return NULL;
+        }
+
+        for (element = element->children; element; element = element->next) {
+                GUPnPFeature *feature;
+                const char   *name;
+                const char   *version;
+                char         *object_ids;
+
+                if (g_ascii_strcasecmp ((char *) element->name,
+                                        "Feature") == 0) {
+                        name = xml_util_get_attribute_content (element, "name");
+                        version = xml_util_get_attribute_content (element,
+                                                                  "version");
+                        if (!name || !version) {
+                                g_set_error (error,
+                                             GUPNP_XML_ERROR,
+                                             GUPNP_XML_ERROR_INVALID_ATTRIBUTE,
+                                             "Invalid attributes in 'Feature' "
+                                             "node in the XML:\n%s",
+                                             text);
+
+                                xmlFreeDoc (doc);
+                                if (feature_list)
+                                        g_list_free_full (feature_list,
+                                                          g_object_unref);
+
+                                return NULL;
+                        }
+
+                        object_ids = get_feature_object_ids (element);
+
+                        feature = g_object_new (GUPNP_TYPE_FEATURE,
+                                                "name", name,
+                                                "version", version,
+                                                "object-ids", object_ids,
+                                                NULL);
+
+                        feature_list = g_list_append (feature_list, feature);
+
+                        g_free (object_ids);
+                }
+        }
+
+        xmlFreeDoc (doc);
+
+        return feature_list;
+}
diff --git a/libgupnp-av/gupnp-feature-list-parser.h b/libgupnp-av/gupnp-feature-list-parser.h
new file mode 100644
index 0000000..aa7cc68
--- /dev/null
+++ b/libgupnp-av/gupnp-feature-list-parser.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Regis Merlino <regis merlino intel com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_FEATURE_LIST_PARSER_H_
+#define __GUPNP_FEATURE_LIST_PARSER_H_
+
+#include <glib-object.h>
+#include "gupnp-feature.h"
+
+G_BEGIN_DECLS
+
+GType
+gupnp_feature_list_parser_get_type (void) G_GNUC_CONST;
+
+#define GUPNP_TYPE_FEATURE_LIST_PARSER \
+                (gupnp_feature_list_parser_get_type ())
+#define GUPNP_FEATURE_LIST_PARSER(obj) \
+                (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                 GUPNP_TYPE_FEATURE_LIST_PARSER, \
+                 GUPnPFeatureListParser))
+#define GUPNP_FEATURE_LIST_PARSER_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_CAST ((obj), \
+                 GUPNP_TYPE_FEATURE_LIST_PARSER, \
+                 GUPnPFeatureListParserClass))
+#define GUPNP_IS_FEATURE_LIST_PARSER(obj) \
+                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+                 GUPNP_TYPE_FEATURE_LIST_PARSER))
+#define GUPNP_IS_FEATURE_LIST_PARSER_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_TYPE ((obj), \
+                 GUPNP_TYPE_FEATURE_LIST_PARSER))
+#define GUPNP_FEATURE_LIST_PARSER_GET_CLASS(obj) \
+                (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                 GUPNP_TYPE_FEATURE_LIST_PARSER, \
+                 GUPnPFeatureListParserClass))
+
+typedef struct {
+        GObject parent;
+} GUPnPFeatureListParser;
+
+typedef struct {
+        GObjectClass parent_class;
+} GUPnPFeatureListParserClass;
+
+GUPnPFeatureListParser *
+gupnp_feature_list_parser_new        (void);
+
+GList *
+gupnp_feature_list_parser_parse_text (GUPnPFeatureListParser *parser,
+                                      const char             *text,
+                                      GError                 **error);
+
+G_END_DECLS
+
+#endif /* __GUPNP_FEATURE_LIST_PARSER_H_ */
diff --git a/libgupnp-av/gupnp-feature.c b/libgupnp-av/gupnp-feature.c
new file mode 100644
index 0000000..668b1f5
--- /dev/null
+++ b/libgupnp-av/gupnp-feature.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Authors: Regis Merlino <regis merlino intel com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gupnp-feature
+ * @short_description: ContentDirectory feature
+ *
+ * #GUPnPFeature respresent a Feature element.
+ */
+
+#include "gupnp-feature.h"
+
+G_DEFINE_TYPE (GUPnPFeature,
+               gupnp_feature,
+               G_TYPE_OBJECT);
+
+struct _GUPnPFeaturePrivate {
+        char *name;
+        char *version;
+        char *object_ids;
+};
+
+enum {
+        PROP_0,
+        PROP_NAME,
+        PROP_VERSION,
+        PROP_OBJECT_IDS
+};
+
+static void
+gupnp_feature_init (GUPnPFeature *object)
+{
+        object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object,
+                                                    GUPNP_TYPE_FEATURE,
+                                                    GUPnPFeaturePrivate);
+}
+
+static void
+gupnp_feature_finalize (GObject *object)
+{
+        GObjectClass        *object_class;
+        GUPnPFeaturePrivate *priv;
+
+        priv = GUPNP_FEATURE (object)->priv;
+        g_free (priv->name);
+        g_free (priv->version);
+        g_free (priv->object_ids);
+
+        object_class = G_OBJECT_CLASS (gupnp_feature_parent_class);
+        object_class->finalize (object);
+}
+
+static void
+gupnp_feature_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+        GUPnPFeature *feature;
+
+        feature = GUPNP_FEATURE (object);
+
+        switch (property_id) {
+        case PROP_NAME:
+                g_value_set_string (value, gupnp_feature_get_name (feature));
+                break;
+        case PROP_VERSION:
+                g_value_set_string (value, gupnp_feature_get_version (feature));
+                break;
+        case PROP_OBJECT_IDS:
+                g_value_set_string (value,
+                                    gupnp_feature_get_object_ids (feature));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+gupnp_feature_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+        GUPnPFeature *feature;
+
+        feature = GUPNP_FEATURE (object);
+
+        switch (property_id) {
+        case PROP_NAME:
+                feature->priv->name = g_value_dup_string (value);
+                break;
+        case PROP_VERSION:
+                feature->priv->version = g_value_dup_string (value);
+                break;
+        case PROP_OBJECT_IDS:
+                feature->priv->object_ids = g_value_dup_string (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+                break;
+        }
+}
+
+static void
+gupnp_feature_class_init (GUPnPFeatureClass *klass)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gupnp_feature_get_property;
+        object_class->set_property = gupnp_feature_set_property;
+        object_class->finalize = gupnp_feature_finalize;
+
+        g_type_class_add_private (klass, sizeof (GUPnPFeaturePrivate));
+
+        /**
+         * GUPnPFeature:name:
+         *
+         * The name of this feature.
+         **/
+        g_object_class_install_property
+                (object_class,
+                 PROP_NAME,
+                 g_param_spec_string ("name",
+                                      "Name",
+                                      "The name of this feature.",
+                                      NULL,
+                                      G_PARAM_READWRITE |
+                                      G_PARAM_CONSTRUCT_ONLY |
+                                      G_PARAM_STATIC_NAME |
+                                      G_PARAM_STATIC_NICK |
+                                      G_PARAM_STATIC_BLURB));
+
+        /**
+         * GUPnPFeature:version:
+         *
+         * The version of this feature.
+         **/
+        g_object_class_install_property
+                (object_class,
+                 PROP_VERSION,
+                 g_param_spec_string ("version",
+                                      "Version",
+                                      "The version of this feature.",
+                                      NULL,
+                                      G_PARAM_READWRITE |
+                                      G_PARAM_CONSTRUCT_ONLY |
+                                      G_PARAM_STATIC_NAME |
+                                      G_PARAM_STATIC_NICK |
+                                      G_PARAM_STATIC_BLURB));
+
+        /**
+         * GUPnPFeature:object-ids:
+         *
+         * The object IDs related to this feature.
+         **/
+        g_object_class_install_property
+                (object_class,
+                 PROP_OBJECT_IDS,
+                 g_param_spec_string ("object-ids",
+                                      "Object IDs",
+                                      "The object IDs of this feature.",
+                                      NULL,
+                                      G_PARAM_READWRITE |
+                                      G_PARAM_CONSTRUCT_ONLY |
+                                      G_PARAM_STATIC_NAME |
+                                      G_PARAM_STATIC_NICK |
+                                      G_PARAM_STATIC_BLURB));
+}
+
+/**
+ * gupnp_feature_get_name:
+ * @v: #GUPnPFeature
+ *
+ * Get the name of the @feature.
+ *
+ * Return value: The name of the @feature.
+ **/
+const char *
+gupnp_feature_get_name (GUPnPFeature *feature)
+{
+        return feature->priv->name;
+}
+
+/**
+ * gupnp_feature_get_version:
+ * @feature: #GUPnPFeature
+ *
+ * Get the version of the @feature.
+ *
+ * Return value: The version of the @feature.
+ **/
+const char *
+gupnp_feature_get_version (GUPnPFeature *feature)
+{
+        return feature->priv->version;
+}
+
+/**
+ * gupnp_feature_get_object_ids:
+ * @feature: #GUPnPFeature
+ *
+ * Get the object IDs related to the @feature.
+ *
+ * Return value: The object IDs related to the @feature.
+ **/
+const char *
+gupnp_feature_get_object_ids (GUPnPFeature *feature)
+{
+        return feature->priv->object_ids;
+}
diff --git a/libgupnp-av/gupnp-feature.h b/libgupnp-av/gupnp-feature.h
new file mode 100644
index 0000000..cc3e259
--- /dev/null
+++ b/libgupnp-av/gupnp-feature.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Authors: Regis Merlino <regis merlino intel com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GUPNP_FEATURE_H_
+#define __GUPNP_FEATURE_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+GType
+gupnp_feature_get_type (void) G_GNUC_CONST;
+
+#define GUPNP_TYPE_FEATURE \
+                (gupnp_feature_get_type ())
+#define GUPNP_FEATURE(obj) \
+                (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                 GUPNP_TYPE_FEATURE, \
+                 GUPnPFeature))
+#define GUPNP_FEATURE_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_CAST ((obj), \
+                 GUPNP_TYPE_FEATURE, \
+                 GUPnPFeatureClass))
+#define GUPNP_IS_FEATURE(obj) \
+                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+                 GUPNP_TYPE_FEATURE))
+#define GUPNP_IS_FEATURE_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_TYPE ((obj), \
+                 GUPNP_TYPE_FEATURE))
+#define GUPNP_FEATURE_GET_CLASS(obj) \
+                (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                 GUPNP_TYPE_FEATURE, \
+                 GUPnPFeatureClass))
+
+typedef struct _GUPnPFeaturePrivate GUPnPFeaturePrivate;
+
+typedef struct {
+        GObject parent;
+
+        GUPnPFeaturePrivate *priv;
+} GUPnPFeature;
+
+typedef struct {
+        GObjectClass parent_class;
+} GUPnPFeatureClass;
+
+const char *
+gupnp_feature_get_name       (GUPnPFeature *feature);
+
+const char *
+gupnp_feature_get_version    (GUPnPFeature *feature);
+
+const char *
+gupnp_feature_get_object_ids (GUPnPFeature *feature);
+
+G_END_DECLS
+
+#endif /* __GUPNP_FEATURE_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]