[lasem] dom: add serialization functions.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] dom: add serialization functions.
- Date: Wed, 20 Oct 2010 12:10:13 +0000 (UTC)
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]