[lasem] dom: add serialization functions.



commit 28407d2754b0d71f2667d4d36eed42da8e386d8d
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Wed Oct 20 14:09:46 2010 +0200

    dom: add serialization functions.

 src/lasemrender.c         |   12 +++++++
 src/lsmattributes.c       |   28 ++++++++++-------
 src/lsmdomcharacterdata.c |   17 ++++++++++-
 src/lsmdomelement.c       |   33 ++++++++++++++++++++
 src/lsmdomelement.h       |    5 ++-
 src/lsmdomnode.c          |   50 +++++++++++-------------------
 src/lsmdomnode.h          |    6 +++-
 src/lsmdomparser.c        |   74 +++++++++++++++++++++++++++++++++++++++++++++
 src/lsmdomparser.h        |   17 ++++++++++-
 src/lsmmathmlelement.c    |    9 +++++
 src/lsmproperties.c       |    8 +++++
 src/lsmsvgelement.c       |   27 ++++++++++++++++
 12 files changed, 238 insertions(+), 48 deletions(-)
---
diff --git a/src/lasemrender.c b/src/lasemrender.c
index ea811ab..e8e8c0d 100644
--- a/src/lasemrender.c
+++ b/src/lasemrender.c
@@ -175,6 +175,18 @@ int main(int argc, char **argv)
 	}
 
 	if (document != NULL) {
+		if (lsm_debug_check ("dom")) {
+			void *buffer;
+			size_t size;
+
+			lsm_dom_document_save_to_memory (document, &buffer, &size, NULL);
+
+			if (buffer != NULL) {
+				g_printf ("%*s\n", (int) size, (char *) buffer);
+				g_free (buffer);
+			}
+		}
+
 		lsm_dom_document_set_resolution (document, option_ppi);
 
 		view = lsm_dom_document_create_view (document);
diff --git a/src/lsmattributes.c b/src/lsmattributes.c
index a2e91d7..013528c 100644
--- a/src/lsmattributes.c
+++ b/src/lsmattributes.c
@@ -224,7 +224,7 @@ lsm_attribute_manager_serialize	(LsmAttributeManager *manager,
 	GHashTableIter iter;
 	char *c_string;
 	gpointer key, value;
-	gboolean is_first = TRUE;
+	gboolean attribute_found = FALSE;
 
 	g_return_val_if_fail (manager != NULL, NULL);
 
@@ -235,20 +235,26 @@ lsm_attribute_manager_serialize	(LsmAttributeManager *manager,
 		attribute_infos = value;
 		attribute = (void *)(instance + attribute_infos->attribute_offset);
 
-		if (is_first) {
-			g_string_append_printf (string, "%s=\"%s\"",
-						attribute_infos->name,
-						attribute->value);
-			is_first = FALSE;
-		} else {
-			g_string_append_printf (string, " %s=\"%s\"",
-						attribute_infos->name,
-						attribute->value);
+		if (attribute->value != NULL) {
+			if (!attribute_found) {
+				g_string_append_printf (string, "%s=\"%s\"",
+							attribute_infos->name,
+							attribute->value);
+				attribute_found = TRUE;
+			} else {
+				g_string_append_printf (string, " %s=\"%s\"",
+							attribute_infos->name,
+							attribute->value);
+			}
 		}
 	}
 
-	c_string = string->str;
+	if (!attribute_found) {
+		g_string_free (string, TRUE);
+		return NULL;
+	}
 
+	c_string = string->str;
 	g_string_free (string, FALSE);
 
 	return c_string;
diff --git a/src/lsmdomcharacterdata.c b/src/lsmdomcharacterdata.c
index 0c81e6a..e988648 100644
--- a/src/lsmdomcharacterdata.c
+++ b/src/lsmdomcharacterdata.c
@@ -1,6 +1,6 @@
 /* lsmdomcharacterdata.c
  *
- * Copyright © 2007-2008  Emmanuel Pacaud
+ * 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
@@ -23,9 +23,21 @@
 
 #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);
+}
+
 /* LsmDomCharacterData implementation */
 
 char*
@@ -71,10 +83,13 @@ 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;
 }
 
 G_DEFINE_ABSTRACT_TYPE (LsmDomCharacterData, lsm_dom_character_data, LSM_TYPE_DOM_NODE)
diff --git a/src/lsmdomelement.c b/src/lsmdomelement.c
index 49f7ed6..deba842 100644
--- a/src/lsmdomelement.c
+++ b/src/lsmdomelement.c
@@ -22,6 +22,9 @@
  */
 
 #include <lsmdomelement.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
 
 /* LsmDomNode implementation */
 
@@ -37,6 +40,33 @@ 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*
@@ -71,8 +101,11 @@ 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
index 7ce2cd8..bba46e1 100644
--- a/src/lsmdomelement.h
+++ b/src/lsmdomelement.h
@@ -45,8 +45,9 @@ struct _LsmDomElement {
 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);
+	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);
diff --git a/src/lsmdomnode.c b/src/lsmdomnode.c
index 8d281f1..6774b2e 100644
--- a/src/lsmdomnode.c
+++ b/src/lsmdomnode.c
@@ -239,7 +239,7 @@ lsm_dom_node_append_child (LsmDomNode* self, LsmDomNode* new_child)
 }
 
 static gboolean
-lsm_dom_node_can_append_child (LsmDomNode *self, LsmDomNode* new_child)
+lsm_dom_node_can_append_child_default (LsmDomNode *self, LsmDomNode* new_child)
 {
 	return FALSE;
 }
@@ -278,41 +278,26 @@ lsm_dom_node_has_child_nodes (LsmDomNode* self)
 	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_dump (LsmDomNode *self)
+lsm_dom_node_write_to_stream (LsmDomNode *self, GOutputStream *stream, GError **error)
 {
-	LsmDomNode *node;
-	LsmDomNodeType type;
-	const char *text;
+	LsmDomNodeClass *node_class;
 
 	g_return_if_fail (LSM_IS_DOM_NODE (self));
+	g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
 
-	type = lsm_dom_node_get_node_type (self);
-
-	switch (type) {
-		case LSM_DOM_NODE_TYPE_ELEMENT_NODE:
-			g_printf ("<%s>", lsm_dom_node_get_node_name (self));
-			for (node = self->first_child;
-			     node != NULL;
-			     node = node->next_sibling)
-				lsm_dom_node_dump (node);
-			g_printf ("</%s>", lsm_dom_node_get_node_name (self));
-			break;
-		case LSM_DOM_NODE_TYPE_TEXT_NODE:
-			text = lsm_dom_node_get_node_value (self);
-			g_printf ("%s", text != NULL ? text : "null");
-			break;
-		case LSM_DOM_NODE_TYPE_DOCUMENT_NODE:
-			g_printf ("Mathml Document\n");
-			if (self->first_child != NULL) {
-				lsm_dom_node_dump (self->first_child);
-				g_printf ("\n");
-			}
-			break;
-		default:
-			g_printf ("Not supported\n");
-			break;
-	}
+	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
@@ -347,7 +332,8 @@ lsm_dom_node_class_init (LsmDomNodeClass *node_class)
 
 	object_class->finalize = lsm_dom_node_finalize;
 
-	node_class->can_append_child = lsm_dom_node_can_append_child;
+	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
index b82255d..0812262 100644
--- a/src/lsmdomnode.h
+++ b/src/lsmdomnode.h
@@ -25,6 +25,7 @@
 #define LSM_DOM_NODE_H
 
 #include <lsmdom.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -86,6 +87,8 @@ struct _LsmDomNodeClass {
 	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);
@@ -115,7 +118,8 @@ void 			lsm_dom_node_changed 			(LsmDomNode *self);
 
 LsmDomDocument*		lsm_dom_node_get_owner_document 	(LsmDomNode* self);
 
-void 			lsm_dom_node_dump 			(LsmDomNode *self);
+void			lsm_dom_node_write_to_stream		(LsmDomNode *self, GOutputStream *stream,
+								 GError **error);
 
 G_END_DECLS
 
diff --git a/src/lsmdomparser.c b/src/lsmdomparser.c
index d147bf1..39545a0 100644
--- a/src/lsmdomparser.c
+++ b/src/lsmdomparser.c
@@ -364,3 +364,77 @@ lsm_dom_document_new_from_url (const char *url, GError **error)
 
 	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, size_t *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
index 03827ba..11551bb 100644
--- a/src/lsmdomparser.h
+++ b/src/lsmdomparser.h
@@ -24,6 +24,7 @@
 #define LSM_DOM_PARSER_H
 
 #include <lsmdomdocument.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -31,10 +32,24 @@ typedef enum {
 	LSM_DOM_DOCUMENT_ERROR_INVALID_XML
 } LsmDomDocumentError;
 
-LsmDomDocument * 	lsm_dom_document_new_from_memory 	(const char *buffer, int size, GError **error);
+LsmDomDocument * 	lsm_dom_document_new_from_memory 	(const void *buffer, size_t 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,
+								 size_t *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/lsmmathmlelement.c b/src/lsmmathmlelement.c
index 0b2eb2d..a125a10 100644
--- a/src/lsmmathmlelement.c
+++ b/src/lsmmathmlelement.c
@@ -82,6 +82,14 @@ lsm_mathml_element_get_attribute (LsmDomElement *self, const char *name)
 						    self, name);
 }
 
+static char *
+lsm_mathml_element_get_serialized_attributes (LsmDomElement *self)
+{
+	LsmMathmlElementClass *m_element_class = LSM_MATHML_ELEMENT_GET_CLASS(self);
+
+	return lsm_attribute_manager_serialize (m_element_class->attribute_manager, self);
+}
+
 /* LsmMathmlElement implementation */
 
 static gboolean
@@ -459,6 +467,7 @@ lsm_mathml_element_class_init (LsmMathmlElementClass *m_element_class)
 
 	d_element_class->get_attribute = lsm_mathml_element_get_attribute;
 	d_element_class->set_attribute = lsm_mathml_element_set_attribute;
+	d_element_class->get_serialized_attributes = lsm_mathml_element_get_serialized_attributes;
 
 	m_element_class->update = NULL;
 	m_element_class->update_children = _update_children;
diff --git a/src/lsmproperties.c b/src/lsmproperties.c
index 38da0bf..983b85b 100644
--- a/src/lsmproperties.c
+++ b/src/lsmproperties.c
@@ -256,6 +256,7 @@ lsm_property_manager_serialize (LsmPropertyManager *manager,
 	GSList *iter;
 	GString *string;
 	char *c_string;
+	gboolean attribute_found = FALSE;
 
 	g_return_val_if_fail (property_bag != NULL, NULL);
 	g_return_val_if_fail (manager != NULL, NULL);
@@ -273,9 +274,16 @@ lsm_property_manager_serialize (LsmPropertyManager *manager,
 						property_infos->name,
 						property->value,
 						iter->next != NULL ? " ": "");
+			if (!attribute_found)
+				attribute_found = TRUE;
 		}
 	}
 
+	if (!attribute_found) {
+		g_string_free (string, TRUE);
+		return NULL;
+	}
+
 	c_string = string->str;
 	g_string_free (string, FALSE);
 
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index c010327..17252ab 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -99,6 +99,32 @@ lsm_svg_element_get_attribute (LsmDomElement *self, const char *name)
 	return lsm_svg_property_bag_get_property (&s_element->property_bag, name);
 }
 
+static char *
+lsm_svg_element_get_serialized_attributes (LsmDomElement *self)
+{
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS(self);
+	LsmSvgElement *s_element = LSM_SVG_ELEMENT (self);
+	char *properties;
+	char *attributes;
+	char *result;
+
+	properties = lsm_svg_property_bag_serialize (&s_element->property_bag);
+	attributes = lsm_attribute_manager_serialize (s_element_class->attribute_manager, self);
+
+	if (attributes == NULL)
+		return properties;
+
+	if (properties == NULL)
+		return attributes;
+
+	result = g_strconcat (attributes, " ", properties, NULL);
+
+	g_free (properties);
+	g_free (attributes);
+
+	return result;
+}
+
 /* LsmSvgElement implementation */
 
 LsmSvgElementCategory
@@ -326,6 +352,7 @@ lsm_svg_element_class_init (LsmSvgElementClass *s_element_class)
 
 	d_element_class->get_attribute = lsm_svg_element_get_attribute;
 	d_element_class->set_attribute = lsm_svg_element_set_attribute;
+	d_element_class->get_serialized_attributes = lsm_svg_element_get_serialized_attributes;
 
 	s_element_class->category = 0;
 



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