diff audacious/xml_document.c @ 0:cb178e5ad177 trunk

[svn] Import audacious source.
author nenolod
date Mon, 24 Oct 2005 03:06:47 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/audacious/xml_document.c	Mon Oct 24 03:06:47 2005 -0700
@@ -0,0 +1,312 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "xml_document.h"
+
+#include <glib.h>
+#include <string.h>
+
+/* document builder callbacks */
+
+static void bmp_xml_doc_build_start_element(GMarkupParseContext * context,
+                                            const gchar * element_name,
+                                            const gchar ** attrib_names,
+                                            const gchar ** attrib_values,
+                                            gpointer user_data,
+                                            GError ** error);
+
+static void bmp_xml_doc_build_end_element(GMarkupParseContext * context,
+                                          const gchar * element_name,
+                                          gpointer user_data,
+                                          GError ** error);
+
+static void bmp_xml_doc_build_text(GMarkupParseContext * context,
+                                   const gchar * text,
+                                   gsize text_len,
+                                   gpointer user_data,
+                                   GError ** error);
+
+static void bmp_xml_doc_build_ignore(GMarkupParseContext * context,
+                                     const gchar * text,
+                                     gsize text_len,
+                                     gpointer user_data,
+                                     GError ** error);
+
+static void bmp_xml_doc_build_error(GMarkupParseContext * context,
+                                    GError * error,
+                                    gpointer user_data);
+
+static void bmp_xml_doc_build_destroy(BmpXmlDocument * data);
+
+static GMarkupParser bmp_xml_doc_builder = {
+    bmp_xml_doc_build_start_element,
+    bmp_xml_doc_build_end_element,
+    bmp_xml_doc_build_text,
+    bmp_xml_doc_build_ignore,
+    bmp_xml_doc_build_error
+};
+
+static GDestroyNotify bmp_xml_node_data_free_func[] = {
+    (GDestroyNotify) bmp_xml_doc_node_data_free,
+    (GDestroyNotify) bmp_xml_element_node_data_free,
+    (GDestroyNotify) bmp_xml_attrib_node_data_free,
+    (GDestroyNotify) bmp_xml_text_node_data_free
+};
+
+GNode *
+bmp_xml_doc_node_new(void)
+{
+    BmpXmlDocNodeData *data;
+    data = g_new0(BmpXmlDocNodeData, 1);
+    data->type = BMP_XML_NODE_DOC;
+    return g_node_new(data);
+}
+
+void
+bmp_xml_doc_node_data_free(BmpXmlDocNodeData * data)
+{
+    g_return_if_fail(data != NULL);
+    g_free(data);
+}
+
+GNode *
+bmp_xml_element_node_new(const gchar * name)
+{
+    BmpXmlElementNodeData *data;
+    data = g_new0(BmpXmlElementNodeData, 1);
+    data->type = BMP_XML_NODE_ELEMENT;
+    data->name = g_strdup(name);
+    return g_node_new(data);
+}
+
+void
+bmp_xml_element_node_data_free(BmpXmlElementNodeData * data)
+{
+    g_return_if_fail(data != NULL);
+    g_free(data->name);
+    g_free(data);
+}
+
+GNode *
+bmp_xml_attrib_node_new(const gchar * name,
+                        const gchar * value)
+{
+    BmpXmlAttribNodeData *data;
+    data = g_new0(BmpXmlAttribNodeData, 1);
+    data->type = BMP_XML_NODE_ATTRIB;
+    data->name = g_strdup(name);
+    data->value = g_strdup(value);
+    return g_node_new(data);
+}
+
+void
+bmp_xml_attrib_node_data_free(BmpXmlAttribNodeData * data)
+{
+    g_assert(data != NULL);
+    g_free(data->name);
+    g_free(data->value);
+    g_free(data);
+}
+
+GNode *
+bmp_xml_text_node_new(const gchar * text, gsize length)
+{
+    BmpXmlTextNodeData *data;
+    data = g_new0(BmpXmlTextNodeData, 1);
+    data->type = BMP_XML_NODE_TEXT;
+    data->text = g_new0(gchar, length);
+    memcpy(data->text, text, length);
+    data->length = length;
+    return g_node_new(data);
+}
+
+void
+bmp_xml_text_node_data_free(BmpXmlTextNodeData * data)
+{
+    g_return_if_fail(data != NULL);
+    g_free(data->text);
+    g_free(data);
+}
+
+void
+bmp_xml_node_data_free(GNode * node)
+{
+    BmpXmlNodeData *data;
+
+    g_return_if_fail(node != NULL);
+    g_return_if_fail(node->data != NULL);
+
+    data = BMP_XML_NODE_DATA(node->data);
+    (*bmp_xml_node_data_free_func[data->type]) (data);
+}
+
+BmpXmlDocument *
+bmp_xml_document_new(void)
+{
+    BmpXmlDocument *document;
+
+    document = g_new0(BmpXmlDocument, 1);
+
+    document->parse_context =
+        g_markup_parse_context_new(&bmp_xml_doc_builder, 0,
+                                   document, (GDestroyNotify)
+                                   bmp_xml_doc_build_destroy);
+    document->current_depth = 0;
+
+    document->tree = bmp_xml_doc_node_new();
+    document->current_node = document->tree;
+
+    return document;
+}
+
+void
+bmp_xml_document_free(BmpXmlDocument * document)
+{
+    g_return_if_fail(document != NULL);
+
+    g_node_traverse(document->tree, G_IN_ORDER, G_TRAVERSE_ALL, -1,
+                    (GNodeTraverseFunc) bmp_xml_node_data_free, NULL);
+    g_node_destroy(document->tree);
+
+    g_free(document);
+}
+
+GNode *
+bmp_xml_document_get_tree(BmpXmlDocument * document)
+{
+    return document->tree;
+}
+
+gboolean
+bmp_xml_document_load(BmpXmlDocument ** document_ref,
+                      const gchar * filename, GError ** error_out)
+{
+    BmpXmlDocument *document;
+    gchar *buffer;
+    gsize buffer_size;
+    GError *error = NULL;
+
+    g_assert(document_ref != NULL);
+    g_assert(filename != NULL);
+
+    *document_ref = NULL;
+
+    if (!g_file_get_contents(filename, &buffer, &buffer_size, &error)) {
+        g_propagate_error(error_out, error);
+        return FALSE;
+    }
+
+    if (!(document = bmp_xml_document_new())) {
+        g_free(buffer);
+        return FALSE;
+    }
+
+    if (!g_markup_parse_context_parse(document->parse_context, buffer,
+                                      buffer_size, &error)) {
+        bmp_xml_document_free(document);
+        g_free(buffer);
+        g_propagate_error(error_out, error);
+        return FALSE;
+    }
+
+    g_free(buffer);
+
+    if (!g_markup_parse_context_end_parse(document->parse_context, &error)) {
+        bmp_xml_document_free(document);
+        g_propagate_error(error_out, error);
+        return FALSE;
+    }
+
+    *document_ref = document;
+
+    return TRUE;
+}
+
+
+static void
+bmp_xml_doc_build_start_element(GMarkupParseContext * context,
+                                const gchar * element_name,
+                                const gchar ** attrib_names,
+                                const gchar ** attrib_values,
+                                gpointer user_data,
+                                GError ** error)
+{
+    BmpXmlDocument *document;
+
+    document = BMP_XML_DOCUMENT(user_data);
+
+    document->current_node =
+        g_node_append(document->current_node,
+                      bmp_xml_element_node_new(element_name));
+
+    while (*attrib_names) {
+        g_node_append(document->current_node,
+                      bmp_xml_attrib_node_new(*attrib_names++,
+                                              *attrib_values++));
+    }
+
+    document->current_depth++;
+}
+
+static void
+bmp_xml_doc_build_end_element(GMarkupParseContext * context,
+                              const gchar * element_name,
+                              gpointer user_data,
+                              GError ** error)
+{
+    BmpXmlDocument *document;
+
+    document = BMP_XML_DOCUMENT(user_data);
+    document->current_node = document->current_node->parent;
+    document->current_depth--;
+}
+
+static void
+bmp_xml_doc_build_text(GMarkupParseContext * context,
+                       const gchar * text,
+                       gsize text_len,
+                       gpointer user_data,
+                       GError ** error)
+{
+    BmpXmlDocument *document;
+    document = BMP_XML_DOCUMENT(user_data);
+    g_node_append(document->current_node,
+                  bmp_xml_text_node_new(text, text_len));
+}
+
+static void
+bmp_xml_doc_build_ignore(GMarkupParseContext * context,
+                         const gchar * text,
+                         gsize text_len,
+                         gpointer user_data,
+                         GError ** error)
+{
+}
+
+static void
+bmp_xml_doc_build_error(GMarkupParseContext * context,
+                        GError * error,
+                        gpointer user_data)
+{
+}
+
+static void
+bmp_xml_doc_build_destroy(BmpXmlDocument * document)
+{
+    g_markup_parse_context_free(document->parse_context);
+}