[aravis/dom: 1/5] dom: initial import from lasem.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [aravis/dom: 1/5] dom: initial import from lasem.
- Date: Sun, 26 Feb 2012 13:45:54 +0000 (UTC)
commit 75a73c5bc5d1847532a66c44b736ffaf15d03ce0
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Sun Feb 19 17:52:44 2012 +0100
dom: initial import from lasem.
src/lsmdom.h | 42 +++
src/lsmdomcharacterdata.c | 114 +++++++
src/lsmdomcharacterdata.h | 59 ++++
src/lsmdomdocument.c | 244 +++++++++++++++
src/lsmdomdocument.h | 82 +++++
src/lsmdomdocumentfragment.c | 81 +++++
src/lsmdomdocumentfragment.h | 55 ++++
src/lsmdomelement.c | 124 ++++++++
src/lsmdomelement.h | 62 ++++
src/lsmdomenumtypes.c | 99 ++++++
src/lsmdomenumtypes.h | 26 ++
src/lsmdomimplementation.c | 73 +++++
src/lsmdomimplementation.h | 43 +++
src/lsmdomnamednodemap.c | 81 +++++
src/lsmdomnamednodemap.h | 64 ++++
src/lsmdomnode.c | 672 ++++++++++++++++++++++++++++++++++++++++++
src/lsmdomnode.h | 120 ++++++++
src/lsmdomnodelist.c | 57 ++++
src/lsmdomnodelist.h | 58 ++++
src/lsmdomparser.c | 423 ++++++++++++++++++++++++++
src/lsmdomparser.h | 52 ++++
src/lsmdomtext.c | 82 +++++
src/lsmdomtext.h | 55 ++++
src/lsmdomtypes.h | 44 +++
24 files changed, 2812 insertions(+), 0 deletions(-)
---
diff --git a/src/lsmdom.h b/src/lsmdom.h
new file mode 100644
index 0000000..71c7515
--- /dev/null
+++ b/src/lsmdom.h
@@ -0,0 +1,42 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_H
+#define LSM_DOM_H
+
+#include <lsm.h>
+
+#include <lsmdomtypes.h>
+
+#include <lsmdomnode.h>
+#include <lsmdomnodelist.h>
+#include <lsmdomdocument.h>
+#include <lsmdomelement.h>
+#include <lsmdomcharacterdata.h>
+#include <lsmdomtext.h>
+#include <lsmdomimplementation.h>
+
+#include <lsmdomparser.h>
+#include <lsmdomview.h>
+
+#endif
diff --git a/src/lsmdomcharacterdata.c b/src/lsmdomcharacterdata.c
new file mode 100644
index 0000000..69c1876
--- /dev/null
+++ b/src/lsmdomcharacterdata.c
@@ -0,0 +1,114 @@
+/* Lasem
+ *
+ * Copyright  2007-2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomcharacterdata
+ * @short_description: Base class for DOM character data nodes
+ */
+
+#include <lsmdomcharacterdata.h>
+#include <lsmdebug.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
+
+/* LsmDomNode implementation */
+
+static void
+lsm_dom_character_data_write_to_stream (LsmDomNode *self, GOutputStream *stream, GError **error)
+{
+ LsmDomCharacterData *character_data = LSM_DOM_CHARACTER_DATA (self);
+
+ if (character_data->data != NULL)
+ g_output_stream_write (stream, character_data->data, strlen (character_data->data), NULL, error);
+}
+
+static const char *
+lsm_dom_character_data_get_node_value (LsmDomNode* self)
+{
+ return lsm_dom_character_data_get_data (LSM_DOM_CHARACTER_DATA (self));
+}
+
+static void
+lsm_dom_character_data_set_node_value (LsmDomNode* self, const char *value)
+{
+ lsm_dom_character_data_set_data (LSM_DOM_CHARACTER_DATA (self), value);
+}
+
+/* LsmDomCharacterData implementation */
+
+const char *
+lsm_dom_character_data_get_data (LsmDomCharacterData* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_CHARACTER_DATA (self), NULL);
+
+ return self->data;
+}
+
+void
+lsm_dom_character_data_set_data (LsmDomCharacterData* self, const char * value)
+{
+ g_return_if_fail (LSM_IS_DOM_CHARACTER_DATA (self));
+ g_return_if_fail (value != NULL);
+
+ g_free (self->data);
+ self->data = g_strdup (value);
+
+ lsm_debug_dom ("[LsmDomCharacterData::set_data] Value = '%s'", value);
+
+ lsm_dom_node_changed (LSM_DOM_NODE (self));
+}
+
+static void
+lsm_dom_character_data_init (LsmDomCharacterData *character_data)
+{
+}
+
+static void
+lsm_dom_character_data_finalize (GObject *object)
+{
+ LsmDomCharacterData *self = LSM_DOM_CHARACTER_DATA (object);
+
+ g_free (self->data);
+
+ parent_class->finalize (object);
+}
+
+/* LsmDomCharacterData class */
+
+static void
+lsm_dom_character_data_class_init (LsmDomCharacterDataClass *character_data_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (character_data_class);
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (character_data_class);
+
+ parent_class = g_type_class_peek_parent (character_data_class);
+
+ object_class->finalize = lsm_dom_character_data_finalize;
+
+ node_class->write_to_stream = lsm_dom_character_data_write_to_stream;
+ node_class->set_node_value = lsm_dom_character_data_set_node_value;
+ node_class->get_node_value = lsm_dom_character_data_get_node_value;
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomCharacterData, lsm_dom_character_data, LSM_TYPE_DOM_NODE)
diff --git a/src/lsmdomcharacterdata.h b/src/lsmdomcharacterdata.h
new file mode 100644
index 0000000..2abedb1
--- /dev/null
+++ b/src/lsmdomcharacterdata.h
@@ -0,0 +1,59 @@
+/* Lasem
+ *
+ * Copyright  2007-2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_CHARACTER_DATA_H
+#define LSM_DOM_CHARACTER_DATA_H
+
+#include <lsmdomnode.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_CHARACTER_DATA (lsm_dom_character_data_get_type ())
+#define LSM_DOM_CHARACTER_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_CHARACTER_DATA, LsmDomCharacterData))
+#define LSM_DOM_CHARACTER_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_CHARACTER_DATA, LsmDomNodeClass))
+#define LSM_IS_DOM_CHARACTER_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_CHARACTER_DATA))
+#define LSM_IS_DOM_CHARACTER_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_CHARACTER_DATA))
+#define LSM_DOM_CHARACTER_DATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_CHARACTER_DATA, LsmDomCharacterDataClass))
+
+typedef struct _LsmDomCharacterDataClass LsmDomCharacterDataClass;
+
+struct _LsmDomCharacterData
+{
+ LsmDomNode node;
+
+ char *data;
+};
+
+struct _LsmDomCharacterDataClass {
+ LsmDomNodeClass parent_class;
+};
+
+GType lsm_dom_character_data_get_type (void);
+
+const char * lsm_dom_character_data_get_data (LsmDomCharacterData* self);
+void lsm_dom_character_data_set_data (LsmDomCharacterData* self, const char* value);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
new file mode 100644
index 0000000..e340e3d
--- /dev/null
+++ b/src/lsmdomdocument.c
@@ -0,0 +1,244 @@
+/* Lasem
+ *
+ * Copyright  2007-2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomdocument
+ * @short_description: Base class for DOM document nodes
+ */
+
+#include <lsmdomdocument.h>
+#include <lsmdomelement.h>
+#include <lsmstr.h>
+#include <lsmdebug.h>
+#include <lsmdomtext.h>
+#include <gio/gio.h>
+#include <string.h>
+
+static GObjectClass *parent_class;
+
+/* LsmDomNode implementation */
+
+static const char *
+lsm_dom_document_get_node_name (LsmDomNode *node)
+{
+ return "#document";
+}
+
+static LsmDomNodeType
+lsm_dom_document_get_node_type (LsmDomNode *node)
+{
+ return LSM_DOM_NODE_TYPE_DOCUMENT_NODE;
+}
+
+/* LsmDomDocument implementation */
+
+LsmDomElement *
+lsm_dom_document_get_document_element (LsmDomDocument *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+
+ return LSM_DOM_ELEMENT (lsm_dom_node_get_first_child (LSM_DOM_NODE (self)));
+}
+
+LsmDomElement *
+lsm_dom_document_create_element (LsmDomDocument *document, const char *tag_name)
+{
+ LsmDomDocumentClass *document_class;
+
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (document), NULL);
+
+ document_class = LSM_DOM_DOCUMENT_GET_CLASS (document);
+ if (document_class->create_element != NULL)
+ return document_class->create_element (document, tag_name);
+
+ return NULL;
+}
+
+LsmDomText *
+lsm_dom_document_create_text_node_base (LsmDomDocument *document, const char *data)
+{
+ return LSM_DOM_TEXT (lsm_dom_text_new (data));
+}
+
+LsmDomText *
+lsm_dom_document_create_text_node (LsmDomDocument *document, const char *data)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (document), NULL);
+
+ return LSM_DOM_DOCUMENT_GET_CLASS (document)->create_text_node (document, data);
+}
+
+LsmDomView *
+lsm_dom_document_create_view (LsmDomDocument *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+
+ return LSM_DOM_DOCUMENT_GET_CLASS (self)->create_view (self);
+}
+
+LsmDomElement *
+lsm_dom_document_get_element_by_id (LsmDomDocument *self, const char *id)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+ g_return_val_if_fail (id != NULL, NULL);
+
+ lsm_debug_dom ("[LsmDomDocument::get_element_by_id] Lookup '%s'", id);
+
+ return g_hash_table_lookup (self->ids, id);
+}
+
+void
+lsm_dom_document_register_element (LsmDomDocument *self, LsmDomElement *element, const char *id)
+{
+ char *old_id;
+
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ old_id = g_hash_table_lookup (self->elements, element);
+ if (old_id != NULL) {
+ lsm_debug_dom ("[LsmDomDocument::register_element] Unregister '%s'", old_id);
+
+ g_hash_table_remove (self->elements, element);
+ g_hash_table_remove (self->ids, old_id);
+ }
+
+ if (id != NULL) {
+ char *new_id = g_strdup (id);
+
+ lsm_debug_dom ("[LsmDomDocument::register_element] Register '%s'", id);
+
+ g_hash_table_replace (self->ids, new_id, element);
+ g_hash_table_replace (self->elements, element, new_id);
+ }
+}
+
+const char *
+lsm_dom_document_get_url (LsmDomDocument *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+
+ return self->url;
+}
+
+void
+lsm_dom_document_set_path (LsmDomDocument *self, const char *path)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+
+ g_free (self->url);
+
+ if (path == NULL) {
+ self->url = NULL;
+ return;
+ }
+
+ self->url = lsm_str_to_uri (path);
+}
+
+void
+lsm_dom_document_set_url (LsmDomDocument *self, const char *url)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (self));
+ g_return_if_fail (url == NULL || lsm_str_is_uri (url));
+
+ g_free (self->url);
+ self->url = g_strdup (url);
+}
+
+void *
+lsm_dom_document_get_href_data (LsmDomDocument *self, const char *href, gsize *size)
+{
+ GFile *file;
+ char *data = NULL;
+
+ g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (self), NULL);
+ g_return_val_if_fail (href != NULL, NULL);
+
+ if (strncmp (href, "data:", 5) == 0) {
+ while (*href != '\0' && *href != ',')
+ href++;
+ return g_base64_decode (href, size);
+ }
+
+ file = g_file_new_for_uri (href);
+
+ if (!g_file_load_contents (file, NULL, &data, size, NULL, NULL) && self->url != NULL) {
+ GFile *document_file;
+ GFile *parent_file;
+
+ g_object_unref (file);
+
+ document_file = g_file_new_for_uri (self->url);
+ parent_file = g_file_get_parent (document_file);
+ file = g_file_resolve_relative_path (parent_file, href);
+ g_object_unref (document_file);
+ g_object_unref (parent_file);
+
+ g_file_load_contents (file, NULL, &data, size, NULL, NULL);
+ }
+
+ g_object_unref (file);
+
+ return data;
+}
+
+static void
+lsm_dom_document_init (LsmDomDocument *document)
+{
+ document->ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ document->elements = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+}
+
+static void
+lsm_dom_document_finalize (GObject *object)
+{
+ LsmDomDocument *document = LSM_DOM_DOCUMENT (object);
+
+ g_hash_table_unref (document->elements);
+ g_hash_table_unref (document->ids);
+
+ g_free (document->url);
+
+ parent_class->finalize (object);
+}
+
+/* LsmDomDocument class */
+
+static void
+lsm_dom_document_class_init (LsmDomDocumentClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = lsm_dom_document_finalize;
+
+ node_class->get_node_name = lsm_dom_document_get_node_name;
+ node_class->get_node_type = lsm_dom_document_get_node_type;
+
+ klass->create_text_node = lsm_dom_document_create_text_node_base;
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomDocument, lsm_dom_document, LSM_TYPE_DOM_NODE)
+
diff --git a/src/lsmdomdocument.h b/src/lsmdomdocument.h
new file mode 100644
index 0000000..597631a
--- /dev/null
+++ b/src/lsmdomdocument.h
@@ -0,0 +1,82 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_DOCUMENT_H
+#define LSM_DOM_DOCUMENT_H
+
+#include <lsmtypes.h>
+#include <lsmdomtypes.h>
+#include <lsmdomnode.h>
+#include <lsmdomview.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_DOCUMENT (lsm_dom_document_get_type ())
+#define LSM_DOM_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_DOCUMENT, LsmDomDocument))
+#define LSM_DOM_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_DOCUMENT, LsmDomDocumentClass))
+#define LSM_IS_DOM_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_DOCUMENT))
+#define LSM_IS_DOM_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_DOCUMENT))
+#define LSM_DOM_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_DOCUMENT, LsmDomDocumentClass))
+
+typedef struct _LsmDomDocumentClass LsmDomDocumentClass;
+
+struct _LsmDomDocument {
+ LsmDomNode node;
+
+ GHashTable * ids;
+ GHashTable * elements;
+
+ char * url;
+
+};
+
+struct _LsmDomDocumentClass {
+ LsmDomNodeClass parent_class;
+
+ LsmDomElement * (*get_document_element) (LsmDomDocument* self);
+ LsmDomElement * (*create_element) (LsmDomDocument* self, const char *tag_name);
+ LsmDomText * (*create_text_node) (LsmDomDocument* self, const char *data);
+
+ LsmDomView* (*create_view) (LsmDomDocument *self);
+};
+
+GType lsm_dom_document_get_type (void);
+
+LsmDomElement* lsm_dom_document_get_document_element (LsmDomDocument* self);
+LsmDomElement* lsm_dom_document_create_element (LsmDomDocument* self, const char *tag_name);
+LsmDomText* lsm_dom_document_create_text_node (LsmDomDocument* self, const char *data);
+LsmDomElement * lsm_dom_document_get_element_by_id (LsmDomDocument *self, const char *id);
+
+void lsm_dom_document_register_element (LsmDomDocument *self, LsmDomElement *element, const char *id);
+
+LsmDomView* lsm_dom_document_create_view (LsmDomDocument *self);
+
+const char * lsm_dom_document_get_url (LsmDomDocument *self);
+void lsm_dom_document_set_url (LsmDomDocument *self, const char *url);
+void lsm_dom_document_set_path (LsmDomDocument *self, const char *path);
+
+void * lsm_dom_document_get_href_data (LsmDomDocument *self, const char *href, gsize *size);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomdocumentfragment.c b/src/lsmdomdocumentfragment.c
new file mode 100644
index 0000000..297db5b
--- /dev/null
+++ b/src/lsmdomdocumentfragment.c
@@ -0,0 +1,81 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomdocumentfragment
+ * @short_description: Base class for DOM document fragments
+ */
+
+#include <lsmdomdocumentfragment.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
+
+/* LsmDomNode implementation */
+
+static const char *
+lsm_dom_document_fragment_get_node_name (LsmDomNode *node)
+{
+ return "#document-fragment";
+}
+
+static const char *
+lsm_dom_document_fragment_get_node_value (LsmDomNode *node)
+{
+ return NULL;
+}
+
+static LsmDomNodeType
+lsm_dom_document_fragment_get_node_type (LsmDomNode *node)
+{
+ return LSM_DOM_NODE_TYPE_DOCUMENT_FRAGMENT_NODE;
+}
+
+/* LsmDomDocumentFragment implementation */
+
+LsmDomDocumentFragment *
+lsm_dom_document_fragment_new (void)
+{
+ return g_object_new (LSM_TYPE_DOM_DOCUMENT_FRAGMENT, NULL);
+}
+
+static void
+lsm_dom_document_fragment_init (LsmDomDocumentFragment *document_fragment)
+{
+}
+
+/* LsmDomDocumentFragment class */
+
+static void
+lsm_dom_document_fragment_class_init (LsmDomDocumentFragmentClass *klass)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ node_class->get_node_name = lsm_dom_document_fragment_get_node_name;
+ node_class->get_node_value = lsm_dom_document_fragment_get_node_value;
+ node_class->get_node_type = lsm_dom_document_fragment_get_node_type;
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomDocumentFragment, lsm_dom_document_fragment, LSM_TYPE_DOM_NODE)
diff --git a/src/lsmdomdocumentfragment.h b/src/lsmdomdocumentfragment.h
new file mode 100644
index 0000000..4a7d4c6
--- /dev/null
+++ b/src/lsmdomdocumentfragment.h
@@ -0,0 +1,55 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_DOCUMENT_FRAGMENT_H
+#define LSM_DOM_DOCUMENT_FRAGMENT_H
+
+#include <lsmdom.h>
+#include <lsmdomnode.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_DOCUMENT_FRAGMENT (lsm_dom_document_fragment_get_type ())
+#define LSM_DOM_DOCUMENT_FRAGMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_DOCUMENT_FRAGMENT, LsmDomDocumentFragment))
+#define LSM_DOM_DOCUMENT_FRAGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_DOCUMENT_FRAGMENT, LsmDomDocumentFragmentClass))
+#define LSM_IS_DOM_DOCUMENT_FRAGMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_DOCUMENT_FRAGMENT))
+#define LSM_IS_DOM_DOCUMENT_FRAGMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_DOCUMENT_FRAGMENT))
+#define LSM_DOM_DOCUMENT_FRAGMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_DOCUMENT_FRAGMENT, LsmDomDocumentFragmentClass))
+
+typedef struct _LsmDomDocumentFragmentClass LsmDomDocumentFragmentClass;
+
+struct _LsmDomDocumentFragment {
+ LsmDomNode node;
+};
+
+struct _LsmDomDocumentFragmentClass {
+ LsmDomNodeClass parent_class;
+};
+
+GType lsm_dom_document_fragment_get_type (void);
+
+LsmDomDocumentFragment * lsm_dom_document_fragment_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomelement.c b/src/lsmdomelement.c
new file mode 100644
index 0000000..bc3be95
--- /dev/null
+++ b/src/lsmdomelement.c
@@ -0,0 +1,124 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomelement
+ * @short_description: Base class for DOM element nodes
+ */
+
+#include <lsmdomelement.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
+
+/* LsmDomNode implementation */
+
+static const char *
+lsm_dom_element_get_node_value (LsmDomNode *node)
+{
+ return NULL;
+}
+
+static LsmDomNodeType
+lsm_dom_element_get_node_type (LsmDomNode *node)
+{
+ return LSM_DOM_NODE_TYPE_ELEMENT_NODE;
+}
+
+static void
+lsm_dom_element_write_to_stream (LsmDomNode *self, GOutputStream *stream, GError **error)
+{
+ LsmDomElementClass *element_class;
+ char *string;
+ char *attributes = NULL;
+
+ element_class = LSM_DOM_ELEMENT_GET_CLASS (self);
+ if (element_class->get_serialized_attributes != NULL)
+ attributes = element_class->get_serialized_attributes (LSM_DOM_ELEMENT (self));
+
+ if (attributes != NULL)
+ string = g_strdup_printf ("<%s %s>", lsm_dom_node_get_node_name (self), attributes);
+ else
+ string = g_strdup_printf ("<%s>", lsm_dom_node_get_node_name (self));
+
+ g_output_stream_write (stream, string, strlen (string), NULL, error);
+ g_free (string);
+ g_free (attributes);
+
+ LSM_DOM_NODE_CLASS (parent_class)->write_to_stream (self, stream, error);
+
+ string = g_strdup_printf ("</\%s>\n", lsm_dom_node_get_node_name (self));
+ g_output_stream_write (stream, string, strlen (string), NULL, error);
+ g_free (string);
+}
+
+/* LsmDomElement implementation */
+
+const char *
+lsm_dom_element_get_attribute (LsmDomElement* self, const char* name)
+{
+ g_return_val_if_fail (LSM_IS_DOM_ELEMENT (self), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return LSM_DOM_ELEMENT_GET_CLASS (self)->get_attribute (self, name);
+}
+
+void
+lsm_dom_element_set_attribute (LsmDomElement* self, const char* name, const char* attribute_value)
+{
+ g_return_if_fail (LSM_IS_DOM_ELEMENT (self));
+ g_return_if_fail (name != NULL);
+
+ LSM_DOM_ELEMENT_GET_CLASS (self)->set_attribute (self, name, attribute_value);
+
+ lsm_dom_node_changed (LSM_DOM_NODE (self));
+}
+
+const char *
+lsm_dom_element_get_tag_name (LsmDomElement *self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_ELEMENT (self), NULL);
+
+ return lsm_dom_node_get_node_name (LSM_DOM_NODE (self));
+}
+
+static void
+lsm_dom_element_init (LsmDomElement *element)
+{
+}
+
+/* LsmDomElement class */
+
+static void
+lsm_dom_element_class_init (LsmDomElementClass *klass)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ node_class->get_node_value = lsm_dom_element_get_node_value;
+ node_class->get_node_type = lsm_dom_element_get_node_type;
+ node_class->write_to_stream = lsm_dom_element_write_to_stream;
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomElement, lsm_dom_element, LSM_TYPE_DOM_NODE)
diff --git a/src/lsmdomelement.h b/src/lsmdomelement.h
new file mode 100644
index 0000000..1ede041
--- /dev/null
+++ b/src/lsmdomelement.h
@@ -0,0 +1,62 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_ELEMENT_H
+#define LSM_DOM_ELEMENT_H
+
+#include <lsmdom.h>
+#include <lsmdomnode.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_ELEMENT (lsm_dom_element_get_type ())
+#define LSM_DOM_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_ELEMENT, LsmDomElement))
+#define LSM_DOM_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_ELEMENT, LsmDomElementClass))
+#define LSM_IS_DOM_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_ELEMENT))
+#define LSM_IS_DOM_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_ELEMENT))
+#define LSM_DOM_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_ELEMENT, LsmDomElementClass))
+
+typedef struct _LsmDomElementClass LsmDomElementClass;
+
+struct _LsmDomElement {
+ LsmDomNode node;
+};
+
+struct _LsmDomElementClass {
+ LsmDomNodeClass parent_class;
+
+ const char* (*get_attribute) (LsmDomElement *self, const char *name);
+ void (*set_attribute) (LsmDomElement *self, const char *name, const char *attribute_value);
+ char * (*get_serialized_attributes) (LsmDomElement *self);
+};
+
+GType lsm_dom_element_get_type (void);
+
+const char * lsm_dom_element_get_tag_name (LsmDomElement *self);
+const char* lsm_dom_element_get_attribute (LsmDomElement* self, const char* name);
+void lsm_dom_element_set_attribute (LsmDomElement* self, const char* name, const char* attribute_value);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/lsmdomenumtypes.c b/src/lsmdomenumtypes.c
new file mode 100644
index 0000000..95c5d42
--- /dev/null
+++ b/src/lsmdomenumtypes.c
@@ -0,0 +1,99 @@
+
+/* Generated data (by glib-mkenums) */
+
+#include "lsmdomenumtypes.h"
+
+/* enumerations from "lsmdebug.h" */
+#include "lsmdebug.h"
+
+GType
+lsm_debug_level_get_type (void)
+{
+ static GType the_type = 0;
+
+ if (the_type == 0)
+ {
+ static const GEnumValue values[] = {
+ { LSM_DEBUG_LEVEL_NONE,
+ "LSM_DEBUG_LEVEL_NONE",
+ "none" },
+ { LSM_DEBUG_LEVEL_WARNING,
+ "LSM_DEBUG_LEVEL_WARNING",
+ "warning" },
+ { LSM_DEBUG_LEVEL_DEBUG,
+ "LSM_DEBUG_LEVEL_DEBUG",
+ "debug" },
+ { LSM_DEBUG_LEVEL_LOG,
+ "LSM_DEBUG_LEVEL_LOG",
+ "log" },
+ { LSM_DEBUG_LEVEL_COUNT,
+ "LSM_DEBUG_LEVEL_COUNT",
+ "count" },
+ { 0, NULL, NULL }
+ };
+ the_type = g_enum_register_static (
+ g_intern_static_string ("LsmDebugLevel"),
+ values);
+ }
+ return the_type;
+}
+
+/* enumerations from "lsmdomnode.h" */
+#include "lsmdomnode.h"
+
+GType
+lsm_dom_node_type_get_type (void)
+{
+ static GType the_type = 0;
+
+ if (the_type == 0)
+ {
+ static const GEnumValue values[] = {
+ { LSM_DOM_NODE_TYPE_ELEMENT_NODE,
+ "LSM_DOM_NODE_TYPE_ELEMENT_NODE",
+ "element-node" },
+ { LSM_DOM_NODE_TYPE_ATTRIBUTE_NODE,
+ "LSM_DOM_NODE_TYPE_ATTRIBUTE_NODE",
+ "attribute-node" },
+ { LSM_DOM_NODE_TYPE_TEXT_NODE,
+ "LSM_DOM_NODE_TYPE_TEXT_NODE",
+ "text-node" },
+ { LSM_DOM_NODE_TYPE_CDATA_SECTION_NODE,
+ "LSM_DOM_NODE_TYPE_CDATA_SECTION_NODE",
+ "cdata-section-node" },
+ { LSM_DOM_NODE_TYPE_ENTITY_REFERENCE_NODE,
+ "LSM_DOM_NODE_TYPE_ENTITY_REFERENCE_NODE",
+ "entity-reference-node" },
+ { LSM_DOM_NODE_TYPE_ENTITY_NODE,
+ "LSM_DOM_NODE_TYPE_ENTITY_NODE",
+ "entity-node" },
+ { LSM_DOM_NODE_TYPE_PROCESSING_INSTRUCTION_NODE,
+ "LSM_DOM_NODE_TYPE_PROCESSING_INSTRUCTION_NODE",
+ "processing-instruction-node" },
+ { LSM_DOM_NODE_TYPE_COMMENT_NODE,
+ "LSM_DOM_NODE_TYPE_COMMENT_NODE",
+ "comment-node" },
+ { LSM_DOM_NODE_TYPE_DOCUMENT_NODE,
+ "LSM_DOM_NODE_TYPE_DOCUMENT_NODE",
+ "document-node" },
+ { LSM_DOM_NODE_TYPE_DOCUMENT_TYPE_NODE,
+ "LSM_DOM_NODE_TYPE_DOCUMENT_TYPE_NODE",
+ "document-type-node" },
+ { LSM_DOM_NODE_TYPE_DOCUMENT_FRAGMENT_NODE,
+ "LSM_DOM_NODE_TYPE_DOCUMENT_FRAGMENT_NODE",
+ "document-fragment-node" },
+ { LSM_DOM_NODE_TYPE_NOTATION_NODE,
+ "LSM_DOM_NODE_TYPE_NOTATION_NODE",
+ "notation-node" },
+ { 0, NULL, NULL }
+ };
+ the_type = g_enum_register_static (
+ g_intern_static_string ("LsmDomNodeType"),
+ values);
+ }
+ return the_type;
+}
+
+
+/* Generated data ends here */
+
diff --git a/src/lsmdomenumtypes.h b/src/lsmdomenumtypes.h
new file mode 100644
index 0000000..1575ad3
--- /dev/null
+++ b/src/lsmdomenumtypes.h
@@ -0,0 +1,26 @@
+
+/* Generated data (by glib-mkenums) */
+
+#ifndef LSM_DOM_ENUM_TYPES_H
+#define LSM_DOM_ENUM_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* Enumerations from "lsmdebug.h" */
+
+#define LSM_TYPE_DEBUG_LEVEL (lsm_debug_level_get_type())
+GType lsm_debug_level_get_type (void) G_GNUC_CONST;
+
+/* Enumerations from "lsmdomnode.h" */
+
+#define LSM_TYPE_DOM_NODE_TYPE (lsm_dom_node_type_get_type())
+GType lsm_dom_node_type_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* LSM_DOM_ENUM_TYPES_H */
+
+/* Generated data ends here */
+
diff --git a/src/lsmdomimplementation.c b/src/lsmdomimplementation.c
new file mode 100644
index 0000000..66b2566
--- /dev/null
+++ b/src/lsmdomimplementation.c
@@ -0,0 +1,73 @@
+/* Lasem
+ *
+ * Copyright  2007-2009 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmdomimplementation.h>
+#include <lsmmathmldocument.h>
+#include <lsmsvgdocument.h>
+#include <lsmdebug.h>
+#include <string.h>
+
+static GHashTable *document_types = NULL;
+
+void
+lsm_dom_implementation_add_create_function (const char *qualified_name,
+ LsmDomDocumentCreateFunction create_function)
+{
+ if (document_types == NULL)
+ document_types = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ g_hash_table_insert (document_types, g_strdup (qualified_name), create_function);
+}
+
+LsmDomDocument *
+lsm_dom_implementation_create_document (const char *namespace_uri,
+ const char *qualified_name)
+{
+ LsmDomDocumentCreateFunction create_function;
+
+ g_return_val_if_fail (qualified_name != NULL, NULL);
+
+ if (document_types == NULL) {
+ lsm_dom_implementation_add_create_function ("math", lsm_mathml_document_new);
+ lsm_dom_implementation_add_create_function ("svg", lsm_svg_document_new);
+ }
+
+ create_function = g_hash_table_lookup (document_types, qualified_name);
+ if (create_function == NULL) {
+ lsm_debug_dom ("[LsmDomImplementation::create_document] Unknow document type (%s)",
+ qualified_name);
+ return NULL;
+ }
+
+ return create_function ();
+}
+
+void
+lsm_dom_implementation_cleanup (void)
+{
+ if (document_types == NULL)
+ return;
+
+ g_hash_table_unref (document_types);
+ document_types = NULL;
+}
diff --git a/src/lsmdomimplementation.h b/src/lsmdomimplementation.h
new file mode 100644
index 0000000..61b6b03
--- /dev/null
+++ b/src/lsmdomimplementation.h
@@ -0,0 +1,43 @@
+/* Lasem
+ *
+ * Copyright  2007-2009 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_IMPLEMENTATION_H
+#define LSM_DOM_IMPLEMENTATION_H
+
+#include <lsmdomtypes.h>
+#include <lsmdomdocument.h>
+
+G_BEGIN_DECLS
+
+typedef LsmDomDocument * (*LsmDomDocumentCreateFunction) (void);
+
+LsmDomDocument * lsm_dom_implementation_create_document (const char *namespace_uri,
+ const char *qualified_name);
+void lsm_dom_implementation_add_document_create_function (const char *qualified_name,
+ LsmDomDocumentCreateFunction create_function);
+
+void lsm_dom_implementation_cleanup (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomnamednodemap.c b/src/lsmdomnamednodemap.c
new file mode 100644
index 0000000..fd7fd85
--- /dev/null
+++ b/src/lsmdomnamednodemap.c
@@ -0,0 +1,81 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmdomnamednodemap.h>
+#include <lsmdomnode.h>
+
+/* LsmDomNamedNodeMap implementation */
+
+LsmDomNode *
+lsm_dom_named_node_map_get_named_item (LsmDomNamedNodeMap *map, const char *name)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NAMED_NODE_MAP (map), NULL);
+
+ return LSM_DOM_NAMED_NODE_MAP_GET_CLASS (map)->get (map, name);
+}
+
+LsmDomNode *
+lsm_dom_named_node_map_set_named_item (LsmDomNamedNodeMap *map, LsmDomNode *node)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NAMED_NODE_MAP (map), NULL);
+
+ return LSM_DOM_NAMED_NODE_MAP_GET_CLASS (map)->set (map, node);
+}
+
+LsmDomNode *
+lsm_dom_named_node_map_remove_named_item (LsmDomNamedNodeMap *map, const char *name)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NAMED_NODE_MAP (map), NULL);
+
+ return LSM_DOM_NAMED_NODE_MAP_GET_CLASS (map)->remove (map, name);
+}
+
+LsmDomNode *
+lsm_dom_named_node_map_get_item (LsmDomNamedNodeMap *map, unsigned int index)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NAMED_NODE_MAP (map), NULL);
+
+ return LSM_DOM_NAMED_NODE_MAP_GET_CLASS (map)->get_item (map, index);
+}
+
+unsigned int
+lsm_dom_named_node_map_get_length (LsmDomNamedNodeMap *map)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NAMED_NODE_MAP (map), 0);
+
+ return LSM_DOM_NAMED_NODE_MAP_GET_CLASS (map)->get_length (map);
+}
+
+static void
+lsm_dom_named_node_map_init (LsmDomNamedNodeMap *map)
+{
+}
+
+/* LsmDomNamedNodeMap class */
+
+static void
+lsm_dom_named_node_map_class_init (LsmDomNamedNodeMapClass *klass)
+{
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomNamedNodeMap, lsm_dom_named_node_map, G_TYPE_OBJECT)
diff --git a/src/lsmdomnamednodemap.h b/src/lsmdomnamednodemap.h
new file mode 100644
index 0000000..2821089
--- /dev/null
+++ b/src/lsmdomnamednodemap.h
@@ -0,0 +1,64 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_NAMED_NODE_MAP_H
+#define LSM_DOM_NAMED_NODE_MAP_H
+
+#include <lsmdomtypes.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_NAMED_NODE_MAP (lsm_dom_named_node_map_get_type ())
+#define LSM_DOM_NAMED_NODE_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMap))
+#define LSM_DOM_NAMED_NODE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMapClass))
+#define LSM_IS_DOM_NAMED_NODE_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NAMED_NODE_MAP))
+#define LSM_IS_DOM_NAMED_NODE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NAMED_NODE_MAP))
+#define LSM_DOM_NAMED_NODE_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMapClass))
+
+typedef struct _LsmDomNamedNodeMapClass LsmDomNamedNodeMapClass;
+
+struct _LsmDomNamedNodeMap {
+ GObject object;
+};
+
+struct _LsmDomNamedNodeMapClass {
+ GObjectClass parent_class;
+
+ LsmDomNode * (*get) (LsmDomNamedNodeMap *map, const char *name);
+ LsmDomNode * (*set) (LsmDomNamedNodeMap *map, LsmDomNode *node);
+ LsmDomNode * (*remove) (LsmDomNamedNodeMap *map, const char *name);
+ LsmDomNode * (*get_item) (LsmDomNamedNodeMap *map, unsigned int index);
+ unsigned int (*get_length) (LsmDomNamedNodeMap *map);
+};
+
+GType lsm_dom_named_node_map_get_type (void);
+
+LsmDomNode * lsm_dom_named_node_map_get_named_item (LsmDomNamedNodeMap *map, const char *name);
+LsmDomNode * lsm_dom_named_node_map_set_named_item (LsmDomNamedNodeMap *map, LsmDomNode *item);
+LsmDomNode * lsm_dom_named_node_map_remove_named_item (LsmDomNamedNodeMap *map, const char *name);
+LsmDomNode * lsm_dom_named_node_map_get_item (LsmDomNamedNodeMap *map, unsigned int index);
+unsigned int lsm_dom_named_node_map_get_length (LsmDomNamedNodeMap *map);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomnode.c b/src/lsmdomnode.c
new file mode 100644
index 0000000..933aa57
--- /dev/null
+++ b/src/lsmdomnode.c
@@ -0,0 +1,672 @@
+/* Lasem
+ *
+ * Copyright  2007-2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomnode
+ * @short_description: Base class for DOM nodes
+ */
+
+#include <lsmdomnode.h>
+#include <lsmdomnodelist.h>
+#include <lsmdomdocument.h>
+#include <lsmdebug.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+
+/* LsmDomNodeChildList */
+
+
+#define LSM_TYPE_DOM_NODE_CHILD_LIST (lsm_dom_node_child_list_get_type ())
+#define LSM_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildList))
+#define LSM_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildListClass))
+#define LSM_IS_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NODE_CHILD_LIST))
+#define LSM_IS_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NODE_CHILD_LIST))
+#define LSM_DOM_NODE_CHILD_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildListClass))
+
+typedef struct _LsmDomNodeChildListClass LsmDomNodeChildListClass;
+
+typedef struct {
+ LsmDomNodeList base;
+
+ LsmDomNode *parent_node;
+} LsmDomNodeChildList;
+
+struct _LsmDomNodeChildListClass {
+ LsmDomNodeListClass parent_class;
+};
+
+GType lsm_dom_node_child_list_get_type (void);
+
+static GObjectClass *child_list_parent_class = NULL;
+
+static void
+lsm_dom_node_child_list_weak_notify_cb (void *user_data, GObject *object)
+{
+ LsmDomNodeChildList *list = user_data;
+
+ list->parent_node = NULL;
+}
+
+static LsmDomNode *
+lsm_dom_node_child_list_get_item (LsmDomNodeList *list, unsigned int index)
+{
+ LsmDomNodeChildList *child_list = LSM_DOM_NODE_CHILD_LIST (list);
+ LsmDomNode *iter;
+ unsigned int i = 0;
+
+ if (child_list->parent_node == NULL)
+ return NULL;
+
+ for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling) {
+ if (i == index)
+ return iter;
+ i++;
+ }
+
+ return NULL;
+}
+
+static unsigned int
+lsm_dom_node_child_list_get_length (LsmDomNodeList *list)
+{
+ LsmDomNodeChildList *child_list = LSM_DOM_NODE_CHILD_LIST (list);
+ LsmDomNode *iter;
+ unsigned int length = 0;
+
+ if (child_list->parent_node == NULL)
+ return 0;
+
+ for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling)
+ length++;
+
+ return length;
+}
+
+LsmDomNodeList *
+lsm_dom_node_child_list_new (LsmDomNode *parent_node)
+{
+ LsmDomNodeChildList *list;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (parent_node), NULL);
+
+ list = g_object_new (LSM_TYPE_DOM_NODE_CHILD_LIST, NULL);
+ list->parent_node = parent_node;
+
+ g_object_weak_ref (G_OBJECT (parent_node), lsm_dom_node_child_list_weak_notify_cb, list);
+
+ return LSM_DOM_NODE_LIST (list);
+}
+
+static void
+lsm_dom_node_child_list_init (LsmDomNodeChildList *list)
+{
+}
+
+static void
+lsm_dom_node_child_list_finalize (GObject *object)
+{
+ LsmDomNodeChildList *list = LSM_DOM_NODE_CHILD_LIST (object);
+
+ if (list->parent_node != NULL) {
+ g_object_weak_unref (G_OBJECT (list->parent_node), lsm_dom_node_child_list_weak_notify_cb, list);
+ list->parent_node = NULL;
+ }
+
+ child_list_parent_class->finalize (object);
+}
+
+static void
+lsm_dom_node_child_list_class_init (LsmDomNodeChildListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ LsmDomNodeListClass *node_list_class = LSM_DOM_NODE_LIST_CLASS (klass);
+
+ child_list_parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = lsm_dom_node_child_list_finalize;
+
+ node_list_class->get_item = lsm_dom_node_child_list_get_item;
+ node_list_class->get_length = lsm_dom_node_child_list_get_length;
+}
+
+G_DEFINE_TYPE (LsmDomNodeChildList, lsm_dom_node_child_list, LSM_TYPE_DOM_NODE_LIST)
+
+static GObjectClass *parent_class = NULL;
+
+/* LsmDomNode implementation */
+
+
+/**
+ * lsm_dom_node_get_node_name:
+ * @self: a #LsmDomNode
+ * Return value: the node name.
+ *
+ * Gets the node name.
+ */
+
+const char*
+lsm_dom_node_get_node_name (LsmDomNode* self)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ g_return_val_if_fail (node_class != NULL, NULL);
+
+ if (node_class->get_node_name)
+ return node_class->get_node_name (self);
+
+ return NULL;
+}
+
+/**
+ * lsm_dom_node_get_node_value:
+ * @self: a #LsmDomNode
+ * Return value: the node value.
+ *
+ * Gets the node value.
+ */
+
+const char*
+lsm_dom_node_get_node_value (LsmDomNode* self)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ g_return_val_if_fail (node_class != NULL, NULL);
+
+ if (node_class->get_node_value)
+ return node_class->get_node_value (self);
+
+ return NULL;
+}
+
+void
+lsm_dom_node_set_node_value (LsmDomNode* self, const char* new_value)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ g_return_if_fail (node_class != NULL);
+ g_return_if_fail (new_value != NULL);
+
+ if (node_class->set_node_value)
+ node_class->set_node_value (self, new_value);
+}
+
+LsmDomNodeType lsm_dom_node_get_node_type (LsmDomNode* self)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ g_return_val_if_fail (node_class != NULL, 0);
+
+ if (node_class->get_node_type)
+ return node_class->get_node_type (self);
+
+ return 0;
+}
+
+LsmDomNode*
+lsm_dom_node_get_parent_node (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ return self->parent_node;
+}
+
+LsmDomNodeList*
+lsm_dom_node_get_child_nodes (LsmDomNode* self)
+{
+ LsmDomNodeList *list;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ list = g_object_get_data (G_OBJECT (self), "child-nodes");
+
+ if (list == NULL) {
+ list = lsm_dom_node_child_list_new (self);
+ g_object_set_data_full (G_OBJECT (self), "child-nodes", list, g_object_unref);
+ }
+
+ return list;
+}
+
+LsmDomNode*
+lsm_dom_node_get_first_child (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ return self->first_child;
+}
+
+LsmDomNode*
+lsm_dom_node_get_last_child (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ return self->last_child;
+}
+
+LsmDomNode*
+lsm_dom_node_get_previous_sibling (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ return self->previous_sibling;
+}
+
+LsmDomNode*
+lsm_dom_node_get_next_sibling (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ return self->next_sibling;
+}
+
+/*LsmDomNamedNodeMap**/
+/*lsm_dom_node_get_attributes (LsmDomNode* self)*/
+/*{*/
+/* return LSM_DOM_NODE_GET_CLASS (self)->get_attributes (self);*/
+/*}*/
+
+LsmDomDocument*
+lsm_dom_node_get_owner_document (LsmDomNode* self)
+{
+ LsmDomNode *parent;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ for (parent = self;
+ parent != NULL &&
+ !LSM_IS_DOM_DOCUMENT (parent);
+ parent = parent->parent_node);
+
+ return LSM_DOM_DOCUMENT (parent);
+}
+
+/**
+ * lsm_dom_node_insert_before:
+ * @self: a #LsmDomNode
+ * @new_child: (transfer full): node to insert
+ * @ref_child: (transfer none): reference node, i.e., the node before which the new node must be inserted.
+ *
+ * Inserts the node @new_child before the existing child node @ref_child. If
+ * @ref_child is null, insert @new_child at the end of the list of children.
+ * If the @new_child is already in the tree, it is first removed.
+ *
+ * Returns: (transfer none): the inserted node.
+ */
+
+/* TODO:
+ * If @new_child is a #LsmDocumentFragment object, all of its children are inserted,
+ * in the same order, before @ref_child.
+ * Check if new_child is an ancestor of self.
+ */
+
+LsmDomNode*
+lsm_dom_node_insert_before (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* ref_child)
+{
+ LsmDomNodeClass *node_class;
+
+ if (ref_child == NULL)
+ lsm_dom_node_append_child (self, new_child);
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (new_child), NULL);
+
+ if (new_child->parent_node != NULL)
+ lsm_dom_node_remove_child (self, new_child);
+
+ if (!LSM_IS_DOM_NODE (self)) {
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (!LSM_IS_DOM_NODE (ref_child)) {
+ g_critical ("%s: ref_child is not a LsmDomNode", G_STRFUNC);
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (ref_child->parent_node != self) {
+ lsm_debug_dom ("[LsmDomNode::insert_before] Ref child '%s' doesn't belong to '%s'",
+ lsm_dom_node_get_node_name (ref_child),
+ lsm_dom_node_get_node_name (self));
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (!LSM_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
+ lsm_debug_dom ("[LsmDomNode::insert_before] Can't append '%s' to '%s'",
+ lsm_dom_node_get_node_name (new_child),
+ lsm_dom_node_get_node_name (self));
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ new_child->parent_node = self;
+ new_child->next_sibling = ref_child;
+ new_child->previous_sibling = ref_child->previous_sibling;
+
+ if (ref_child->previous_sibling == NULL)
+ self->first_child = new_child;
+ else
+ ref_child->previous_sibling->next_sibling = new_child;
+
+ ref_child->previous_sibling = new_child;
+
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ if (node_class->post_new_child)
+ node_class->post_new_child (self, new_child);
+
+ lsm_dom_node_changed (self);
+
+ return new_child;
+}
+
+/**
+ * lsm_dom_node_replace_child:
+ * @self: a #LsmDomNode
+ * @new_child: (transfer full): a replacement node
+ * @old_child: (transfer none): node to replace
+ *
+ * Replaces the child node @old_child with @new_child in the list of children,
+ * and returns the @old_child node.
+ * If the @new_child is already in the tree, it is first removed.
+ *
+ * Returns: (transfer full): the replaced node.
+ */
+
+/* TODO:
+ * Check if new_child is an ancestor of self.
+ */
+
+LsmDomNode*
+lsm_dom_node_replace_child (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* old_child)
+{
+ LsmDomNode *next_sibling;
+ LsmDomNode *node;
+
+ if (new_child == NULL)
+ return lsm_dom_node_remove_child (self, old_child);
+
+ if (!LSM_IS_DOM_NODE (new_child)) {
+ g_critical ("%s: new_child is not a LsmDomNode", G_STRFUNC);
+ if (LSM_IS_DOM_NODE (old_child))
+ g_object_unref (old_child);
+ return NULL;
+ }
+
+ if (new_child->parent_node != NULL)
+ lsm_dom_node_remove_child (self, new_child);
+
+ if (old_child == NULL) {
+ lsm_debug_dom ("[LsmDomNode::replace_child] old_child == NULL)");
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (!LSM_IS_DOM_NODE (old_child)) {
+ g_critical ("%s: old_child is not a LsmDomNode", G_STRFUNC);
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (!LSM_IS_DOM_NODE (self)) {
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
+ g_object_unref (new_child);
+ g_object_unref (old_child);
+ return NULL;
+ }
+
+ if (old_child->parent_node != self) {
+ g_object_unref (new_child);
+ g_object_unref (old_child);
+ return NULL;
+ }
+
+ next_sibling = old_child->next_sibling;
+
+ node = lsm_dom_node_remove_child (self, old_child);
+ if (node != old_child) {
+ g_object_unref (new_child);
+ g_object_unref (old_child);
+ return NULL;
+ }
+
+ if (next_sibling == NULL)
+ lsm_dom_node_append_child (self, new_child);
+ else
+ lsm_dom_node_insert_before (self, new_child, next_sibling);
+
+ return old_child;
+}
+
+/**
+ * lsm_dom_node_remove_child:
+ * @self: a #LsmDomNode
+ * @old_child: (transfer none): node to remove.
+ *
+ * Removes the child node indicated by @old_child from the list of children, and returns it.
+ *
+ * Returns: (transfer full): the removed node.
+ */
+
+LsmDomNode*
+lsm_dom_node_remove_child (LsmDomNode* self, LsmDomNode* old_child)
+{
+ LsmDomNode *node;
+ LsmDomNodeClass *node_class;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
+
+ if (old_child == NULL)
+ return NULL;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (old_child), NULL);
+
+ for (node = self->first_child;
+ node != NULL && node != old_child;
+ node = node->next_sibling);
+
+ if (node == NULL)
+ return NULL;
+
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ if (node_class->pre_remove_child)
+ node_class->pre_remove_child (self, old_child);
+
+ if (self->first_child == old_child)
+ self->first_child = old_child->next_sibling;
+ if (self->last_child == old_child)
+ self->last_child = old_child->previous_sibling;
+
+ if (old_child->next_sibling != NULL)
+ old_child->next_sibling->previous_sibling = old_child->previous_sibling;
+ if (old_child->previous_sibling != NULL)
+ old_child->previous_sibling->next_sibling = old_child->next_sibling;
+
+ old_child->parent_node = NULL;
+ old_child->next_sibling = NULL;
+ old_child->previous_sibling = NULL;
+
+ lsm_dom_node_changed (self);
+
+ return old_child;
+}
+
+/**
+ * lsm_dom_node_append_child:
+ * @self: a #LsmDomNode
+ * @new_child: (transfer full): node to append
+ *
+ * Adds the node @new_child to the end of the list of children of this node.
+ * If the @new_child is already in the tree, it is first removed.
+ *
+ * Returns: (transfer none): the added node.
+ */
+
+LsmDomNode *
+lsm_dom_node_append_child (LsmDomNode* self, LsmDomNode* new_child)
+{
+ LsmDomNodeClass *node_class;
+
+ if (new_child == NULL)
+ return NULL;
+
+ g_return_val_if_fail (LSM_IS_DOM_NODE (new_child), NULL);
+
+ if (!LSM_IS_DOM_NODE (self)) {
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (new_child->parent_node != NULL)
+ lsm_dom_node_remove_child (self, new_child);
+
+ if (!LSM_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
+ lsm_debug_dom ("[LsmDomNode::append_child] Can't append '%s' to '%s'",
+ lsm_dom_node_get_node_name (new_child),
+ lsm_dom_node_get_node_name (self));
+ g_object_unref (new_child);
+ return NULL;
+ }
+
+ if (self->first_child == NULL)
+ self->first_child = new_child;
+ if (self->last_child != NULL)
+ self->last_child->next_sibling = new_child;
+
+ new_child->parent_node = self;
+ new_child->next_sibling = NULL;
+ new_child->previous_sibling = self->last_child;
+ self->last_child = new_child;
+
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ if (node_class->post_new_child)
+ node_class->post_new_child (self, new_child);
+
+ lsm_dom_node_changed (self);
+
+ return new_child;
+}
+
+static gboolean
+lsm_dom_node_can_append_child_default (LsmDomNode *self, LsmDomNode* new_child)
+{
+ return FALSE;
+}
+
+void
+lsm_dom_node_changed (LsmDomNode *self)
+{
+ LsmDomNode *parent_node;
+ LsmDomNode *child_node;
+ LsmDomNodeClass *node_class;
+
+ g_return_if_fail (LSM_IS_DOM_NODE (self));
+
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
+
+ if (node_class->changed)
+ node_class->changed (self);
+
+ child_node = self;
+ for (parent_node = self->parent_node;
+ parent_node != NULL;
+ parent_node = parent_node->parent_node) {
+ node_class = LSM_DOM_NODE_GET_CLASS (parent_node);
+ if (node_class->child_changed == NULL ||
+ !node_class->child_changed (parent_node, child_node))
+ break;
+ child_node = parent_node;
+ }
+}
+
+gboolean
+lsm_dom_node_has_child_nodes (LsmDomNode* self)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), FALSE);
+
+ return self->first_child != NULL;
+}
+
+static void
+lsm_dom_node_write_to_stream_default (LsmDomNode *self, GOutputStream *stream, GError **error)
+{
+ LsmDomNode *child;
+
+ for (child = self->first_child; child != NULL; child = child->next_sibling)
+ lsm_dom_node_write_to_stream (child, stream, error);
+}
+
+void
+lsm_dom_node_write_to_stream (LsmDomNode *self, GOutputStream *stream, GError **error)
+{
+ LsmDomNodeClass *node_class;
+
+ g_return_if_fail (LSM_IS_DOM_NODE (self));
+ g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
+
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
+ if (node_class->write_to_stream != NULL)
+ node_class->write_to_stream (self, stream, error);
+}
+
+static void
+lsm_dom_node_init (LsmDomNode *node)
+{
+}
+
+static void
+lsm_dom_node_finalize (GObject *object)
+{
+ LsmDomNode *node = LSM_DOM_NODE (object);
+ LsmDomNode *child, *next_child;
+
+ child = node->first_child;
+ while (child != NULL) {
+ next_child = child->next_sibling;
+ g_object_unref (child);
+ child = next_child;
+ }
+
+ parent_class->finalize (object);
+}
+
+/* LsmDomNode class */
+
+static void
+lsm_dom_node_class_init (LsmDomNodeClass *node_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (node_class);
+
+ parent_class = g_type_class_peek_parent (node_class);
+
+ object_class->finalize = lsm_dom_node_finalize;
+
+ node_class->can_append_child = lsm_dom_node_can_append_child_default;
+ node_class->write_to_stream = lsm_dom_node_write_to_stream_default;
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomNode, lsm_dom_node, G_TYPE_OBJECT)
diff --git a/src/lsmdomnode.h b/src/lsmdomnode.h
new file mode 100644
index 0000000..de1458c
--- /dev/null
+++ b/src/lsmdomnode.h
@@ -0,0 +1,120 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_NODE_H
+#define LSM_DOM_NODE_H
+
+#include <lsmdomtypes.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ LSM_DOM_NODE_TYPE_ELEMENT_NODE = 1,
+ LSM_DOM_NODE_TYPE_ATTRIBUTE_NODE,
+ LSM_DOM_NODE_TYPE_TEXT_NODE,
+ LSM_DOM_NODE_TYPE_CDATA_SECTION_NODE,
+ LSM_DOM_NODE_TYPE_ENTITY_REFERENCE_NODE,
+ LSM_DOM_NODE_TYPE_ENTITY_NODE,
+ LSM_DOM_NODE_TYPE_PROCESSING_INSTRUCTION_NODE,
+ LSM_DOM_NODE_TYPE_COMMENT_NODE,
+ LSM_DOM_NODE_TYPE_DOCUMENT_NODE,
+ LSM_DOM_NODE_TYPE_DOCUMENT_TYPE_NODE,
+ LSM_DOM_NODE_TYPE_DOCUMENT_FRAGMENT_NODE,
+ LSM_DOM_NODE_TYPE_NOTATION_NODE
+} LsmDomNodeType;
+
+#define LSM_TYPE_DOM_NODE (lsm_dom_node_get_type ())
+#define LSM_DOM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NODE, LsmDomNode))
+#define LSM_DOM_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NODE, LsmDomNodeClass))
+#define LSM_IS_DOM_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NODE))
+#define LSM_IS_DOM_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NODE))
+#define LSM_DOM_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NODE, LsmDomNodeClass))
+
+typedef struct _LsmDomNodeClass LsmDomNodeClass;
+
+struct _LsmDomNode {
+ GObject object;
+
+ LsmDomNode *next_sibling;
+ LsmDomNode *previous_sibling;
+ LsmDomNode *parent_node;
+ LsmDomNode *first_child;
+ LsmDomNode *last_child;
+};
+
+struct _LsmDomNodeClass {
+ GObjectClass parent_class;
+
+ /* DOM node virtuals */
+
+ const char* (*get_node_name) (LsmDomNode* self);
+ const char* (*get_node_value) (LsmDomNode* self);
+ void (*set_node_value) (LsmDomNode* self, const char* new_value);
+ LsmDomNodeType (*get_node_type) (LsmDomNode* self);
+
+ /* Validation virtuals */
+
+ gboolean (*can_append_child) (LsmDomNode *self, LsmDomNode *new_child);
+
+ /* Implementation virtuals */
+
+ void (*post_new_child) (LsmDomNode *parent, LsmDomNode *child);
+ void (*pre_remove_child) (LsmDomNode *parent, LsmDomNode *child);
+ void (*changed) (LsmDomNode *self);
+ gboolean (*child_changed) (LsmDomNode *self, LsmDomNode *child);
+
+ void (*write_to_stream) (LsmDomNode *self, GOutputStream *stream, GError **error);
+};
+
+GType lsm_dom_node_get_type (void);
+
+const char * lsm_dom_node_get_node_name (LsmDomNode* self);
+const char * lsm_dom_node_get_node_value (LsmDomNode* self);
+void lsm_dom_node_set_node_value (LsmDomNode* self, const char* new_value);
+LsmDomNodeType lsm_dom_node_get_node_type (LsmDomNode* self);
+LsmDomNode * lsm_dom_node_get_parent_node (LsmDomNode* self);
+LsmDomNodeList * lsm_dom_node_get_child_nodes (LsmDomNode* self);
+LsmDomNode * lsm_dom_node_get_first_child (LsmDomNode* self);
+LsmDomNode * lsm_dom_node_get_last_child (LsmDomNode* self);
+LsmDomNode * lsm_dom_node_get_previous_sibling (LsmDomNode* self);
+LsmDomNode * lsm_dom_node_get_next_sibling (LsmDomNode* self);
+#if 0
+LsmDomNamedNodeMap * lsm_dom_node_get_attributes (LsmDomNode* self);
+#endif
+LsmDomNode * lsm_dom_node_insert_before (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* ref_child);
+LsmDomNode * lsm_dom_node_replace_child (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* old_child);
+LsmDomNode * lsm_dom_node_append_child (LsmDomNode* self, LsmDomNode* new_child);
+LsmDomNode * lsm_dom_node_remove_child (LsmDomNode* self, LsmDomNode* old_child);
+gboolean lsm_dom_node_has_child_nodes (LsmDomNode* self);
+
+void lsm_dom_node_changed (LsmDomNode *self);
+
+LsmDomDocument * lsm_dom_node_get_owner_document (LsmDomNode* self);
+
+void lsm_dom_node_write_to_stream (LsmDomNode *self, GOutputStream *stream,
+ GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomnodelist.c b/src/lsmdomnodelist.c
new file mode 100644
index 0000000..e896c91
--- /dev/null
+++ b/src/lsmdomnodelist.c
@@ -0,0 +1,57 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmdomnodelist.h>
+#include <lsmdomnode.h>
+
+/* LsmDomNodeList implementation */
+
+LsmDomNode *
+lsm_dom_node_list_get_item (LsmDomNodeList *list, unsigned int index)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE_LIST (list), NULL);
+
+ return LSM_DOM_NODE_LIST_GET_CLASS (list)->get_item (list, index);
+}
+
+unsigned int
+lsm_dom_node_list_get_length (LsmDomNodeList *list)
+{
+ g_return_val_if_fail (LSM_IS_DOM_NODE_LIST (list), 0);
+
+ return LSM_DOM_NODE_LIST_GET_CLASS (list)->get_length (list);
+}
+
+static void
+lsm_dom_node_list_init (LsmDomNodeList *list)
+{
+}
+
+/* LsmDomNodeList class */
+
+static void
+lsm_dom_node_list_class_init (LsmDomNodeListClass *klass)
+{
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmDomNodeList, lsm_dom_node_list, G_TYPE_OBJECT)
diff --git a/src/lsmdomnodelist.h b/src/lsmdomnodelist.h
new file mode 100644
index 0000000..df52bed
--- /dev/null
+++ b/src/lsmdomnodelist.h
@@ -0,0 +1,58 @@
+/* Lasem
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_NODE_LIST_H
+#define LSM_DOM_NODE_LIST_H
+
+#include <lsmdomtypes.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_NODE_LIST (lsm_dom_node_list_get_type ())
+#define LSM_DOM_NODE_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NODE_LIST, LsmDomNodeList))
+#define LSM_DOM_NODE_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NODE_LIST, LsmDomNodeListClass))
+#define LSM_IS_DOM_NODE_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NODE_LIST))
+#define LSM_IS_DOM_NODE_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NODE_LIST))
+#define LSM_DOM_NODE_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NODE_LIST, LsmDomNodeListClass))
+
+typedef struct _LsmDomNodeListClass LsmDomNodeListClass;
+
+struct _LsmDomNodeList {
+ GObject object;
+};
+
+struct _LsmDomNodeListClass {
+ GObjectClass parent_class;
+
+ LsmDomNode * (*get_item) (LsmDomNodeList *list, unsigned int index);
+ unsigned int (*get_length) (LsmDomNodeList *list);
+};
+
+GType lsm_dom_node_list_get_type (void);
+
+LsmDomNode * lsm_dom_node_list_get_item (LsmDomNodeList *list, unsigned int index);
+unsigned int lsm_dom_node_list_get_length (LsmDomNodeList *list);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomparser.c b/src/lsmdomparser.c
new file mode 100644
index 0000000..8f42734
--- /dev/null
+++ b/src/lsmdomparser.c
@@ -0,0 +1,423 @@
+/* Lasem
+ *
+ * Copyright  2007-2009 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmdebug.h>
+#include <lsmdomimplementation.h>
+#include <lsmdomnode.h>
+#include <lsmmathmlpresentationtoken.h>
+#include <lsmmathmlentitydictionary.h>
+#include <lsmsvgtextelement.h>
+#include <lsmstr.h>
+#include <libxml/parser.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <../itex2mml/itex2MML.h>
+
+typedef enum {
+ STATE
+} LsmDomSaxParserStateEnum;
+
+typedef struct {
+ LsmDomSaxParserStateEnum state;
+
+ LsmDomDocument *document;
+ LsmDomNode *current_node;
+
+ gboolean is_error;
+
+ int error_depth;
+
+ GHashTable *entities;
+} LsmDomSaxParserState;
+
+void
+_free_entity (void *data)
+{
+ xmlEntity *entity = data;
+
+ xmlFree ((xmlChar *) entity->name);
+ xmlFree ((xmlChar *) entity->ExternalID);
+ xmlFree ((xmlChar *) entity->SystemID);
+ xmlFree (entity->content);
+ xmlFree (entity->orig);
+ g_free (entity);
+}
+
+static void
+lsm_dom_parser_start_document (void *user_data)
+{
+ LsmDomSaxParserState *state = user_data;
+
+ state->state = STATE;
+ state->document = NULL;
+ state->is_error = FALSE;
+ state->error_depth = 0;
+ state->entities = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, _free_entity);
+}
+
+static void
+lsm_dom_parser_end_document (void *user_data)
+{
+ LsmDomSaxParserState *state = user_data;
+
+ g_hash_table_unref (state->entities);
+}
+
+static void
+lsm_dom_parser_start_element(void *user_data,
+ const xmlChar *name,
+ const xmlChar **attrs)
+{
+ LsmDomSaxParserState *state = user_data;
+ LsmDomNode *node;
+ int i;
+
+ if (state->is_error) {
+ state->error_depth++;
+ return;
+ }
+
+ if (state->document == NULL) {
+ state->document = lsm_dom_implementation_create_document (NULL, (char *) name);
+ state->current_node = LSM_DOM_NODE (state->document);
+
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (state->document));
+ }
+
+ node = LSM_DOM_NODE (lsm_dom_document_create_element (LSM_DOM_DOCUMENT (state->document), (char *) name));
+
+ if (LSM_IS_DOM_NODE (node) && lsm_dom_node_append_child (state->current_node, node) != NULL) {
+ if (attrs != NULL)
+ for (i = 0; attrs[i] != NULL && attrs[i+1] != NULL; i += 2)
+ lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (node),
+ (char *) attrs[i],
+ (char *) attrs[i+1]);
+
+ state->current_node = node;
+ state->is_error = FALSE;
+ state->error_depth = 0;
+ } else {
+ state->is_error = TRUE;
+ state->error_depth = 1;
+ }
+}
+
+static void
+lsm_dom_parser_end_element (void *user_data,
+ const xmlChar *name)
+{
+ LsmDomSaxParserState *state = user_data;
+
+ if (state->is_error) {
+ state->error_depth--;
+ if (state->error_depth > 0) {
+ return;
+ }
+
+ state->is_error = FALSE;
+ return;
+ }
+
+ state->current_node = lsm_dom_node_get_parent_node (state->current_node);
+}
+
+static void
+lsm_dom_parser_characters (void *user_data, const xmlChar *ch, int len)
+{
+ LsmDomSaxParserState *state = user_data;
+
+ if (!state->is_error) {
+ LsmDomNode *node;
+ char *text;
+
+ text = g_strndup ((char *) ch, len);
+ node = LSM_DOM_NODE (lsm_dom_document_create_text_node (LSM_DOM_DOCUMENT (state->document), text));
+
+ lsm_dom_node_append_child (state->current_node, node);
+
+ g_free (text);
+ }
+}
+
+static xmlEntityPtr
+lsm_dom_parser_get_entity (void *user_data, const xmlChar *name)
+{
+ LsmDomSaxParserState *state = user_data;
+ xmlEntity *entity;
+ const char *utf8;
+
+ entity = g_hash_table_lookup (state->entities, name);
+ if (entity != NULL)
+ return entity;
+
+ utf8 = lsm_mathml_entity_get_utf8 ((char *) name);
+ if (utf8 != NULL) {
+ entity = xmlNewEntity (NULL, name, XML_INTERNAL_GENERAL_ENTITY, NULL, NULL, (xmlChar *) utf8);
+
+ g_hash_table_insert (state->entities, (char *) name, entity);
+
+ return entity;
+ }
+
+ return xmlGetPredefinedEntity(name);
+}
+
+void
+lsm_dom_parser_declare_entity (void * user_data, const xmlChar * name, int type,
+ const xmlChar * publicId, const xmlChar * systemId,
+ xmlChar * content)
+{
+ LsmDomSaxParserState *state = user_data;
+
+ if (content != NULL) {
+ xmlEntity *entity;
+
+ entity = xmlNewEntity (NULL, name, type, publicId, systemId, content);
+
+ g_hash_table_insert (state->entities, (char *) name, entity);
+ }
+}
+
+#if 1
+static void
+lsm_dom_parser_warning (void *user_data, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_WARNING, msg, args);
+ va_end(args);
+}
+
+static void
+lsm_dom_parser_error (void *user_data, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_CRITICAL, msg, args);
+ va_end(args);
+}
+
+static void
+lsm_dom_parser_fatal_error (void *user_data, const char *msg, ...)
+{
+ va_list args;
+
+ va_start(args, msg);
+ g_logv("XML", G_LOG_LEVEL_ERROR, msg, args);
+ va_end(args);
+}
+#endif
+
+static xmlSAXHandler sax_handler = {
+#if 1
+ .warning = lsm_dom_parser_warning,
+ .error = lsm_dom_parser_error,
+ .fatalError = lsm_dom_parser_fatal_error,
+#endif
+ .startDocument = lsm_dom_parser_start_document,
+ .endDocument = lsm_dom_parser_end_document,
+ .startElement = lsm_dom_parser_start_element,
+ .endElement = lsm_dom_parser_end_element,
+ .characters = lsm_dom_parser_characters,
+ .getEntity = lsm_dom_parser_get_entity,
+ .entityDecl = lsm_dom_parser_declare_entity
+};
+
+static GQuark
+lsm_dom_document_error_quark (void)
+{
+ static GQuark q = 0;
+
+ if (q == 0) {
+ q = g_quark_from_static_string ("lsm-dom-error-quark");
+ }
+
+ return q;
+}
+
+#define LSM_DOM_DOCUMENT_ERROR lsm_dom_document_error_quark ()
+
+typedef enum {
+ LSM_DOM_DOCUMENT_ERROR_INVALID_XML
+} LsmDomDocumentError;
+
+LsmDomDocument *
+lsm_dom_document_new_from_memory (const void *buffer, int size, GError **error)
+{
+ static LsmDomSaxParserState state;
+
+ g_return_val_if_fail (buffer != NULL, NULL);
+
+ state.document = NULL;
+
+ if (size < 0)
+ size = strlen (buffer);
+
+ if (xmlSAXUserParseMemory (&sax_handler, &state, buffer, size) < 0) {
+ if (state.document != NULL)
+ g_object_unref (state.document);
+ state.document = NULL;
+
+ lsm_debug_dom ("[LsmDomParser::from_memory] Invalid document");
+
+ g_set_error (error,
+ LSM_DOM_DOCUMENT_ERROR,
+ LSM_DOM_DOCUMENT_ERROR_INVALID_XML,
+ "Invalid document.");
+ }
+
+ return state.document;
+}
+
+static LsmDomDocument *
+lsm_dom_document_new_from_file (GFile *file, GError **error)
+{
+ LsmDomDocument *document;
+ gsize size = 0;
+ char *contents = NULL;
+
+ if (!g_file_load_contents (file, NULL, &contents, &size, NULL, error))
+ return NULL;
+
+ document = lsm_dom_document_new_from_memory (contents, size, error);
+
+ g_free (contents);
+
+ return document;
+}
+
+LsmDomDocument *
+lsm_dom_document_new_from_path (const char *path, GError **error)
+{
+ LsmDomDocument *document;
+ GFile *file;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ file = g_file_new_for_path (path);
+
+ document = lsm_dom_document_new_from_file (file, error);
+
+ g_object_unref (file);
+
+ if (document != NULL)
+ lsm_dom_document_set_path (document, path);
+
+ return document;
+}
+
+LsmDomDocument *
+lsm_dom_document_new_from_url (const char *url, GError **error)
+{
+ LsmDomDocument *document;
+ GFile *file;
+
+ g_return_val_if_fail (url != NULL, NULL);
+
+ file = g_file_new_for_uri (url);
+
+ document = lsm_dom_document_new_from_file (file, error);
+
+ g_object_unref (file);
+
+ if (document != NULL)
+ lsm_dom_document_set_url (document, url);
+
+ return document;
+}
+
+void
+lsm_dom_document_save_to_stream (LsmDomDocument *document, GOutputStream *stream, GError **error)
+{
+ g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));
+ g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
+
+ lsm_dom_node_write_to_stream (LSM_DOM_NODE (document), stream, error);
+}
+
+void
+lsm_dom_document_save_to_memory (LsmDomDocument *document, void **buffer, int *size, GError **error)
+{
+ GOutputStream *stream;
+
+ if (buffer != NULL)
+ *buffer = NULL;
+ if (size != NULL)
+ *size = 0;
+
+ g_return_if_fail (document != NULL);
+ g_return_if_fail (buffer != NULL);
+
+ stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+ if (stream == NULL) {
+ *buffer = NULL;
+ if (size != NULL)
+ *size = 0;
+ return;
+ }
+
+ lsm_dom_document_save_to_stream (document, G_OUTPUT_STREAM (stream), error);
+ g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, error);
+
+ if (size != NULL)
+ *size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (stream));
+ *buffer = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (stream));
+
+ g_object_unref (stream);
+}
+
+void
+lsm_dom_document_save_to_path (LsmDomDocument *document, const char *path, GError **error)
+{
+ GFile *file;
+ GFileOutputStream *stream;
+
+ g_return_if_fail (path != NULL);
+
+ file = g_file_new_for_path (path);
+ stream = g_file_create (file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, error);
+ if (stream != NULL) {
+ lsm_dom_document_save_to_stream (document, G_OUTPUT_STREAM (stream), error);
+ g_object_unref (stream);
+ }
+ g_object_unref (file);
+}
+
+void
+lsm_dom_document_save_to_url (LsmDomDocument *document, const char *path, GError **error)
+{
+ GFile *file;
+ GFileOutputStream *stream;
+
+ g_return_if_fail (path != NULL);
+
+ file = g_file_new_for_uri (path);
+ stream = g_file_create (file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, error);
+ if (stream != NULL) {
+ lsm_dom_document_save_to_stream (document, G_OUTPUT_STREAM (stream), error);
+ g_object_unref (stream);
+ }
+ g_object_unref (file);
+}
diff --git a/src/lsmdomparser.h b/src/lsmdomparser.h
new file mode 100644
index 0000000..5ff6b6c
--- /dev/null
+++ b/src/lsmdomparser.h
@@ -0,0 +1,52 @@
+/* Lasem
+ *
+ * Copyright  2007-2009 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_PARSER_H
+#define LSM_DOM_PARSER_H
+
+#include <lsmdomdocument.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+LsmDomDocument * lsm_dom_document_new_from_memory (const void *buffer, int size, GError **error);
+LsmDomDocument * lsm_dom_document_new_from_path (const char *path, GError **error);
+LsmDomDocument * lsm_dom_document_new_from_url (const char *url, GError **error);
+
+void lsm_dom_document_save_to_stream (LsmDomDocument *document,
+ GOutputStream *stream,
+ GError **error);
+void lsm_dom_document_save_to_memory (LsmDomDocument *documennt,
+ void **buffer,
+ int *size,
+ GError **error);
+void lsm_dom_document_save_to_path (LsmDomDocument *documennt,
+ const char *path,
+ GError **error);
+void lsm_dom_document_save_to_url (LsmDomDocument *documennt,
+ const char *path,
+ GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmdomtext.c b/src/lsmdomtext.c
new file mode 100644
index 0000000..dec4dc3
--- /dev/null
+++ b/src/lsmdomtext.c
@@ -0,0 +1,82 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+/**
+ * SECTION:lsmdomtext
+ * @short_description: Base class for DOM text nodes
+ */
+
+#include <lsmdomtext.h>
+
+/* LsmDomNode implementation */
+
+static const char *
+lsm_dom_text_get_node_name (LsmDomNode *node)
+{
+ return "#text";
+}
+
+static const char *
+lsm_dom_text_get_node_value (LsmDomNode *node)
+{
+ return LSM_DOM_CHARACTER_DATA (node)->data;
+}
+
+static LsmDomNodeType
+lsm_dom_text_get_node_type (LsmDomNode *node)
+{
+ return LSM_DOM_NODE_TYPE_TEXT_NODE;
+}
+
+/* LsmDomText implementation */
+
+LsmDomNode *
+lsm_dom_text_new (const char *data)
+{
+ LsmDomNode *node;
+
+ node = g_object_new (LSM_TYPE_DOM_TEXT, NULL);
+
+ lsm_dom_character_data_set_data (LSM_DOM_CHARACTER_DATA (node), data);
+
+ return node;
+}
+
+static void
+lsm_dom_text_init (LsmDomText *text_node)
+{
+}
+
+/* LsmDomText class */
+
+static void
+lsm_dom_text_class_init (LsmDomTextClass *klass)
+{
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+
+ node_class->get_node_name = lsm_dom_text_get_node_name;
+ node_class->get_node_value = lsm_dom_text_get_node_value;
+ node_class->get_node_type = lsm_dom_text_get_node_type;
+}
+
+G_DEFINE_TYPE (LsmDomText, lsm_dom_text, LSM_TYPE_DOM_CHARACTER_DATA)
diff --git a/src/lsmdomtext.h b/src/lsmdomtext.h
new file mode 100644
index 0000000..a793347
--- /dev/null
+++ b/src/lsmdomtext.h
@@ -0,0 +1,55 @@
+/* Lasem
+ *
+ * Copyright  2007-2008 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_TEXT_H
+#define LSM_DOM_TEXT_H
+
+#include <lsmdomcharacterdata.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_DOM_TEXT (lsm_dom_text_get_type ())
+#define LSM_DOM_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_TEXT, LsmDomText))
+#define LSM_DOM_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_TEXT, LsmDomTextClass))
+#define LSM_IS_DOM_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_TEXT))
+#define LSM_IS_DOM_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_TEXT))
+#define LSM_DOM_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_TEXT, LsmDomTextClass))
+
+typedef struct _LsmDomTextClass LsmDomTextClass;
+
+struct _LsmDomText {
+ LsmDomCharacterData character_data;
+};
+
+struct _LsmDomTextClass {
+ LsmDomCharacterDataClass parent_class;
+};
+
+GType lsm_dom_text_get_type (void);
+
+LsmDomNode *lsm_dom_text_new (const char *data);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/lsmdomtypes.h b/src/lsmdomtypes.h
new file mode 100644
index 0000000..1c71b1d
--- /dev/null
+++ b/src/lsmdomtypes.h
@@ -0,0 +1,44 @@
+/* Lasem - SVG and Mathml library
+ *
+ * Copyright  2010 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_DOM_TYPES_H
+#define LSM_DOM_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _LsmDomNode LsmDomNode;
+typedef struct _LsmDomNodeList LsmDomNodeList;
+typedef struct _LsmDomNamedNodeMap LsmDomNamedNodeMap;
+typedef struct _LsmDomElement LsmDomElement;
+typedef struct _LsmDomDocument LsmDomDocument;
+typedef struct _LsmDomDocumentFragment LsmDomDocumentFragment;
+typedef struct _LsmDomCharacterData LsmDomCharacterData;
+typedef struct _LsmDomText LsmDomText;
+
+typedef struct _LsmDomView LsmDomView;
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]