From 6b00de66025093218127fa74d9a423d58e377025 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Sat, 8 Nov 2003 12:56:44 +0000 Subject: Port node db saving and RDF export to xml writer api. 2003-11-08 Christian Persch * embed/ephy-favicon-cache.c: (ephy_favicon_cache_get_type), (ephy_favicon_cache_finalize): * embed/ephy-history.c: (ephy_history_save): * lib/ephy-file-helpers.c: (ephy_file_switch_temp_file): * lib/ephy-file-helpers.h: * lib/ephy-node-db.c: (ephy_node_db_load_from_file), (ephy_node_db_write_to_xml_valist), (ephy_node_db_write_to_xml_safe): * lib/ephy-node-db.h: * lib/ephy-node.c: (write_parent), (ephy_node_write_to_xml): * lib/ephy-node.h: * lib/ephy-state.c: (ephy_states_save), (ensure_states): * src/bookmarks/ephy-bookmarks-export.c: (write_topics_list), (ephy_bookmarks_export_rdf): * src/bookmarks/ephy-bookmarks.c: (ephy_bookmarks_save): Port node db saving and RDF export to xml writer api. --- ChangeLog | 20 ++++ embed/ephy-favicon-cache.c | 45 ++----- embed/ephy-history.c | 52 ++------ lib/ephy-file-helpers.c | 32 ++--- lib/ephy-file-helpers.h | 4 +- lib/ephy-node-db.c | 141 +++++++++++++++++++++- lib/ephy-node-db.h | 9 ++ lib/ephy-node.c | 148 ++++++++++++----------- lib/ephy-node.h | 7 +- lib/ephy-state.c | 44 ++----- src/bookmarks/ephy-bookmarks-export.c | 220 +++++++++++++++++++++++++--------- src/bookmarks/ephy-bookmarks.c | 59 ++------- 12 files changed, 475 insertions(+), 306 deletions(-) diff --git a/ChangeLog b/ChangeLog index 349e30499..d96cafca0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-11-08 Christian Persch + + * embed/ephy-favicon-cache.c: (ephy_favicon_cache_get_type), + (ephy_favicon_cache_finalize): + * embed/ephy-history.c: (ephy_history_save): + * lib/ephy-file-helpers.c: (ephy_file_switch_temp_file): + * lib/ephy-file-helpers.h: + * lib/ephy-node-db.c: (ephy_node_db_load_from_file), + (ephy_node_db_write_to_xml_valist), + (ephy_node_db_write_to_xml_safe): + * lib/ephy-node-db.h: + * lib/ephy-node.c: (write_parent), (ephy_node_write_to_xml): + * lib/ephy-node.h: + * lib/ephy-state.c: (ephy_states_save), (ensure_states): + * src/bookmarks/ephy-bookmarks-export.c: (write_topics_list), + (ephy_bookmarks_export_rdf): + * src/bookmarks/ephy-bookmarks.c: (ephy_bookmarks_save): + + Port node db saving and RDF export to xml writer api. + 2003-11-07 Christian Persch * src/ephy-favicon-actio.c: (ephy_favicon_action_finalize): diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c index 0ba259132..6c443773f 100644 --- a/embed/ephy-favicon-cache.c +++ b/embed/ephy-favicon-cache.c @@ -19,7 +19,6 @@ * $Id$ */ -#include #include #include #include @@ -85,8 +84,8 @@ ephy_favicon_cache_get_type (void) }; ephy_favicon_cache_type = g_type_register_static (G_TYPE_OBJECT, - "EphyFaviconCache", - &our_info, 0); + "EphyFaviconCache", + &our_info, 0); } return ephy_favicon_cache_type; @@ -199,38 +198,6 @@ remove_obsolete_icons (EphyFaviconCache *eb) } } -static void -ephy_favicon_cache_save (EphyFaviconCache *eb) -{ - xmlDocPtr doc; - xmlNodePtr root; - GPtrArray *children; - int i; - - /* save nodes to xml */ - xmlIndentTreeOutput = TRUE; - doc = xmlNewDoc ("1.0"); - - root = xmlNewDocNode (doc, NULL, "ephy_favicons_cache", NULL); - xmlSetProp (root, "version", EPHY_FAVICON_CACHE_XML_VERSION); - xmlDocSetRootElement (doc, root); - - children = ephy_node_get_children (eb->priv->icons); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; - - kid = g_ptr_array_index (children, i); - - ephy_node_save_to_xml (kid, root); - } - ephy_node_thaw (eb->priv->icons); - - ephy_file_save_xml (eb->priv->xml_file, doc); - - xmlFreeDoc (doc); -} - static void ephy_favicon_cache_init (EphyFaviconCache *cache) { @@ -321,7 +288,13 @@ ephy_favicon_cache_finalize (GObject *object) cleanup_downloads_hash (cache); remove_obsolete_icons (cache); - ephy_favicon_cache_save (cache); + + ephy_node_db_write_to_xml_safe + (cache->priv->db, cache->priv->xml_file, + EPHY_FAVICON_CACHE_XML_ROOT, + EPHY_FAVICON_CACHE_XML_VERSION, + NULL, + cache->priv->icons, 0, NULL); g_free (cache->priv->xml_file); g_free (cache->priv->directory); diff --git a/embed/ephy-history.c b/embed/ephy-history.c index 871212755..8afbead0e 100644 --- a/embed/ephy-history.c +++ b/embed/ephy-history.c @@ -25,6 +25,7 @@ #include "ephy-history.h" #include "ephy-file-helpers.h" #include "ephy-debug.h" +#include "ephy-node-db.h" #include "ephy-node-common.h" #include @@ -36,7 +37,7 @@ #define EPHY_HISTORY_XML_VERSION "1.0" /* how often to save the history, in milliseconds */ -#define HISTORY_SAVE_INTERVAL (60 * 5 * 1000) +#define HISTORY_SAVE_INTERVAL (5 * 60 * 1000) /* if you change this remember to change also the user interface description */ #define HISTORY_PAGE_OBSOLETE_DAYS 10 @@ -176,12 +177,7 @@ remove_obsolete_pages (EphyHistory *eb) static void ephy_history_save (EphyHistory *eb) { - xmlDocPtr doc; - xmlNodePtr root; - GPtrArray *children; - int i; - - LOG ("Saving history") + int ret; /* only save if there are changes */ if (eb->priv->dirty == FALSE) @@ -189,44 +185,22 @@ ephy_history_save (EphyHistory *eb) return; } - /* save nodes to xml */ - xmlIndentTreeOutput = TRUE; - doc = xmlNewDoc ("1.0"); - - root = xmlNewDocNode (doc, NULL, "ephy_history", NULL); - xmlSetProp (root, "version", EPHY_HISTORY_XML_VERSION); - xmlDocSetRootElement (doc, root); - - children = ephy_node_get_children (eb->priv->hosts); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; - - kid = g_ptr_array_index (children, i); - if (kid == eb->priv->pages) continue; - - ephy_node_save_to_xml (kid, root); - } - ephy_node_thaw (eb->priv->hosts); - - children = ephy_node_get_children (eb->priv->pages); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; + LOG ("Saving history db") - kid = g_ptr_array_index (children, i); + ret = ephy_node_db_write_to_xml_safe + (eb->priv->db, eb->priv->xml_file, + EPHY_HISTORY_XML_ROOT, + EPHY_HISTORY_XML_VERSION, + NULL, /* comment */ + eb->priv->hosts, 0, + eb->priv->pages, 0, + NULL); - ephy_node_save_to_xml (kid, root); - } - ephy_node_thaw (eb->priv->pages); - - if (ephy_file_save_xml (eb->priv->xml_file, doc)) + if (ret >=0) { /* save was successful */ eb->priv->dirty = FALSE; } - - xmlFreeDoc(doc); } static void diff --git a/lib/ephy-file-helpers.c b/lib/ephy-file-helpers.c index 0d61f5bfc..1161f6ac7 100644 --- a/lib/ephy-file-helpers.c +++ b/lib/ephy-file-helpers.c @@ -190,41 +190,35 @@ ephy_file_find (const char *path, } gboolean -ephy_file_save_xml (const char *xml_file, xmlDocPtr doc) +ephy_file_switch_temp_file (const char *filename, + const char *filename_temp) { - char *tmp_file; char *old_file; gboolean old_exist; gboolean retval = TRUE; - tmp_file = g_strconcat (xml_file, ".tmp", NULL); - old_file = g_strconcat (xml_file, ".old", NULL); + old_file = g_strconcat (filename, ".old", NULL); - if (xmlSaveFormatFile (tmp_file, doc, 1) <= 0) - { - g_warning ("Failed to write XML data to %s", tmp_file); - goto failed; - } - - old_exist = g_file_test (xml_file, G_FILE_TEST_EXISTS); + old_exist = g_file_test (filename, G_FILE_TEST_EXISTS); if (old_exist) { - if (rename (xml_file, old_file) < 0) + if (rename (filename, old_file) < 0) { - g_warning ("Failed to rename %s to %s", xml_file, old_file); + g_warning ("Failed to rename %s to %s", filename, old_file); retval = FALSE; goto failed; } } - if (rename (tmp_file, xml_file) < 0) + if (rename (filename_temp, filename) < 0) { - g_warning ("Failed to rename %s to %s", tmp_file, xml_file); + g_warning ("Failed to rename %s to %s", filename_temp, filename); - if (rename (old_file, xml_file) < 0) + if (rename (old_file, filename) < 0) { - g_warning ("Failed to restore %s from %s", xml_file, tmp_file); + g_warning ("Failed to restore %s from %s", + filename, filename_temp); } retval = FALSE; goto failed; @@ -238,10 +232,8 @@ ephy_file_save_xml (const char *xml_file, xmlDocPtr doc) } } - failed: +failed: g_free (old_file); - g_free (tmp_file); return retval; } - diff --git a/lib/ephy-file-helpers.h b/lib/ephy-file-helpers.h index 6b2d17cfe..15fa16656 100644 --- a/lib/ephy-file-helpers.h +++ b/lib/ephy-file-helpers.h @@ -43,8 +43,8 @@ GSList *ephy_file_find (const char *path, const char *fname, gint maxdepth); -gboolean ephy_file_save_xml (const char *xml_file, - xmlDocPtr doc); +gboolean ephy_file_switch_temp_file (const char *filename, + const char *filename_temp); G_END_DECLS diff --git a/lib/ephy-node-db.c b/lib/ephy-node-db.c index 58ca3fe91..10276eaba 100644 --- a/lib/ephy-node-db.c +++ b/lib/ephy-node-db.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2002 Jorn Baayen + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,9 +21,14 @@ */ #include "ephy-node-db.h" +#include "ephy-file-helpers.h" #include "ephy-debug.h" #include +#include +#include +#include +#include static void ephy_node_db_class_init (EphyNodeDbClass *klass); static void ephy_node_db_init (EphyNodeDb *node); @@ -323,11 +330,11 @@ ephy_node_db_load_from_file (EphyNodeDb *db, ret = xmlTextReaderRead (reader); while (ret == 1) { - xmlChar *name; + const xmlChar *name; xmlReaderTypes type; gboolean skip = FALSE; - name = xmlTextReaderName (reader); + name = xmlTextReaderConstName (reader); type = xmlTextReaderNodeType (reader); if (xmlStrEqual (name, "node") @@ -354,7 +361,6 @@ ephy_node_db_load_from_file (EphyNodeDb *db, { success = FALSE; xmlFree (version); - xmlFree (name); break; } @@ -362,8 +368,6 @@ ephy_node_db_load_from_file (EphyNodeDb *db, xmlFree (version); } - xmlFree (name); - /* next one, please */ ret = skip ? xmlTextReaderNext (reader) : xmlTextReaderRead (reader); @@ -375,3 +379,130 @@ ephy_node_db_load_from_file (EphyNodeDb *db, return (success && ret == 0); } + +static int +ephy_node_db_write_to_xml_valist (EphyNodeDb *db, + const xmlChar *filename, + const xmlChar *root, + const xmlChar *version, + const xmlChar *comment, + EphyNode *first_node, + va_list argptr) +{ + xmlTextWriterPtr writer; + EphyNode *node; + int ret; + + LOG ("Saving node db to %s", filename) + + START_PROFILER ("Saving node db") + + /* FIXME: do we want to turn compression on ? */ + writer = xmlNewTextWriterFilename (filename, 0); + if (writer == NULL) + { + return -1; + } + + ret = xmlTextWriterStartDocument (writer, "1.0", NULL, NULL); + if (ret < 0) goto out; + + ret = xmlTextWriterStartElement (writer, root); + if (ret < 0) goto out; + + ret = xmlTextWriterWriteAttribute (writer, "version", version); + if (ret < 0) goto out; + + if (comment != NULL) + { + ret = xmlTextWriterWriteComment (writer, comment); + if (ret < 0) goto out; + } + + node = first_node; + while (node != NULL) + { + GPtrArray *children; + guint n_exceptions, i; + GSList *exceptions = NULL; + + n_exceptions = va_arg (argptr, guint); + for (i=0; i < n_exceptions; i++) + { + exceptions = g_slist_prepend (exceptions, + va_arg (argptr, EphyNode *)); + } + + children = ephy_node_get_children (node); + for (i=0; i < children->len; i++) + { + EphyNode *kid; + + kid = g_ptr_array_index (children, i); + + if (g_slist_find (exceptions, kid) == NULL) + { + ret = ephy_node_write_to_xml (kid, writer); + if (ret < 0) break; + } + } + ephy_node_thaw (node); + if (ret < 0) break; + + g_slist_free (exceptions); + + node = va_arg (argptr, EphyNode *); + } + if (ret < 0) goto out; + + ret = xmlTextWriterEndElement (writer); /* root */ + if (ret < 0) goto out; + + ret = xmlTextWriterEndDocument (writer); + if (ret < 0) goto out; + +out: + xmlFreeTextWriter (writer); + + STOP_PROFILER ("Saving node db") + + return ret >= 0 ? 0 : -1; +} + +int +ephy_node_db_write_to_xml_safe (EphyNodeDb *db, + const xmlChar *filename, + const xmlChar *root, + const xmlChar *version, + const xmlChar *comment, + EphyNode *node, ...) +{ + va_list argptr; + int ret = 0; + char *tmp_file; + + tmp_file = g_strconcat (filename, ".tmp", NULL); + + va_start (argptr, node); + + ret = ephy_node_db_write_to_xml_valist + (db, tmp_file, root, version, comment, node, argptr); + + va_end (argptr); + + if (ret < 0) + { + g_warning ("Failed to write XML data to %s", tmp_file); + goto failed; + } + + if (ephy_file_switch_temp_file (filename, tmp_file) == FALSE) + { + ret = -1; + } + +failed: + g_free (tmp_file); + + return ret; +} diff --git a/lib/ephy-node-db.h b/lib/ephy-node-db.h index f5ca81107..f9df6d894 100644 --- a/lib/ephy-node-db.h +++ b/lib/ephy-node-db.h @@ -1,5 +1,7 @@ /* * Copyright (C) 2002 Jorn Baayen + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,6 +63,13 @@ gboolean ephy_node_db_load_from_file (EphyNodeDb *db, const xmlChar *xml_root, const xmlChar *xml_version); +int ephy_node_db_write_to_xml_safe (EphyNodeDb *db, + const xmlChar *filename, + const xmlChar *root, + const xmlChar *version, + const xmlChar *comment, + EphyNode *node, ...); + const char *ephy_node_db_get_name (EphyNodeDb *db); EphyNode *ephy_node_db_get_node_from_id (EphyNodeDb *db, diff --git a/lib/ephy-node.c b/lib/ephy-node.c index 51bd0aa5c..35cbe6936 100644 --- a/lib/ephy-node.c +++ b/lib/ephy-node.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2002 Jorn Baayen + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +21,7 @@ */ #ifdef HAVE_CONFIG_H -#include +#include "config.h" #endif #include @@ -761,122 +763,134 @@ ephy_node_get_property_node (EphyNode *node, return retval; } -static void -save_parent (gulong id, - EphyNodeParent *node_info, - xmlNodePtr xml_node) +typedef struct { - xmlNodePtr parent_xml_node; - char *xml; + xmlTextWriterPtr writer; + int ret; +} ForEachData; - parent_xml_node = xmlNewChild (xml_node, NULL, "parent", NULL); +static void +write_parent (gulong id, + EphyNodeParent *node_info, + ForEachData* data) +{ + xmlTextWriterPtr writer = data->writer; - g_static_rw_lock_reader_lock (node_info->node->lock); + /* there already was an error, do nothing. this works around + * the fact that g_hash_table_foreach cannot be cancelled. + */ + if (data->ret < 0) return; - xml = g_strdup_printf ("%ld", node_info->node->id); - xmlSetProp (parent_xml_node, "id", xml); - g_free (xml); + data->ret = xmlTextWriterStartElement (writer, "parent"); + if (data->ret < 0) return; + g_static_rw_lock_reader_lock (node_info->node->lock); + data->ret = xmlTextWriterWriteFormatAttribute + (writer, "id", "%ld", node_info->node->id); g_static_rw_lock_reader_unlock (node_info->node->lock); + if (data->ret < 0) return; + + data->ret = xmlTextWriterEndElement (writer); /* parent */ + if (data->ret < 0) return; } -void -ephy_node_save_to_xml (EphyNode *node, - xmlNodePtr parent_xml_node) +int +ephy_node_write_to_xml(EphyNode *node, + xmlTextWriterPtr writer) { - xmlNodePtr xml_node; - char *xml; - char xml_buf [G_ASCII_DTOSTR_BUF_SIZE]; + xmlChar xml_buf[G_ASCII_DTOSTR_BUF_SIZE]; guint i; + int ret; + ForEachData data; - g_return_if_fail (EPHY_IS_NODE (node)); - g_return_if_fail (parent_xml_node != NULL); + g_return_val_if_fail (EPHY_IS_NODE (node), -1); + g_return_val_if_fail (writer != NULL, -1); g_static_rw_lock_reader_lock (node->lock); - xml_node = xmlNewChild (parent_xml_node, NULL, "node", NULL); + /* start writing the node */ + ret = xmlTextWriterStartElement (writer, "node"); + if (ret < 0) goto out; - xml = g_strdup_printf ("%ld", node->id); - xmlSetProp (xml_node, "id", xml); - g_free (xml); + /* write node id */ + ret = xmlTextWriterWriteFormatAttribute (writer, "id", "%ld", node->id); + if (ret < 0) goto out; - for (i = 0; i < node->properties->len; i++) { + /* write node properties */ + for (i = 0; i < node->properties->len; i++) + { GValue *value; - xmlNodePtr value_xml_node; value = g_ptr_array_index (node->properties, i); - if (value == NULL) - continue; - value_xml_node = xmlNewChild (xml_node, NULL, "property", NULL); + if (value == NULL) continue; - xml = g_strdup_printf ("%d", i); - xmlSetProp (value_xml_node, "id", xml); - g_free (xml); + ret = xmlTextWriterStartElement (writer, "property"); + if (ret < 0) break; - xmlSetProp (value_xml_node, "value_type", g_type_name (G_VALUE_TYPE (value))); + ret = xmlTextWriterWriteFormatAttribute (writer, "id", "%d", i); + if (ret < 0) break; + + ret = xmlTextWriterWriteAttribute + (writer, "value_type", g_type_name (G_VALUE_TYPE (value))); + if (ret < 0) break; switch (G_VALUE_TYPE (value)) { case G_TYPE_STRING: - xml = xmlEncodeEntitiesReentrant (NULL, - g_value_get_string (value)); - xmlNodeSetContent (value_xml_node, xml); - g_free (xml); + ret = xmlTextWriterWriteString + (writer, g_value_get_string (value)); break; case G_TYPE_BOOLEAN: - xml = g_strdup_printf ("%d", g_value_get_boolean (value)); - xmlNodeSetContent (value_xml_node, xml); - g_free (xml); + ret = xmlTextWriterWriteFormatString + (writer, "%d", g_value_get_boolean (value)); break; case G_TYPE_INT: - xml = g_strdup_printf ("%d", g_value_get_int (value)); - xmlNodeSetContent (value_xml_node, xml); - g_free (xml); + ret = xmlTextWriterWriteFormatString + (writer, "%d", g_value_get_int (value)); break; case G_TYPE_LONG: - xml = g_strdup_printf ("%ld", g_value_get_long (value)); - xmlNodeSetContent (value_xml_node, xml); - g_free (xml); + ret = xmlTextWriterWriteFormatString + (writer, "%ld", g_value_get_long (value)); break; case G_TYPE_FLOAT: g_ascii_dtostr (xml_buf, sizeof (xml_buf), g_value_get_float (value)); - xmlNodeSetContent (value_xml_node, xml_buf); + ret = xmlTextWriterWriteString (writer, xml_buf); break; case G_TYPE_DOUBLE: g_ascii_dtostr (xml_buf, sizeof (xml_buf), g_value_get_double (value)); - xmlNodeSetContent (value_xml_node, xml_buf); + ret = xmlTextWriterWriteString (writer, xml_buf); break; - case G_TYPE_POINTER: - { - EphyNode *prop_node; - - prop_node = g_value_get_pointer (value); - - g_assert (prop_node != NULL); - - g_static_rw_lock_reader_lock (prop_node->lock); - - xml = g_strdup_printf ("%ld", prop_node->id); - xmlNodeSetContent (value_xml_node, xml); - g_free (xml); - - g_static_rw_lock_reader_unlock (prop_node->lock); - break; - } default: g_assert_not_reached (); break; } + if (ret < 0) break; + + ret = xmlTextWriterEndElement (writer); /* property */ + if (ret < 0) break; } + if (ret < 0) goto out; + + /* now write parent node ids */ + data.writer = writer; + data.ret = 0; g_hash_table_foreach (node->parents, - (GHFunc) save_parent, - xml_node); + (GHFunc) write_parent, + &data); + ret = data.ret; + if (ret < 0) goto out; + ret = xmlTextWriterEndElement (writer); /* node */ + if (ret < 0) goto out; + +out: g_static_rw_lock_reader_unlock (node->lock); + + return ret >= 0 ? 0 : -1; } static inline void diff --git a/lib/ephy-node.h b/lib/ephy-node.h index 842001665..754c3f53e 100644 --- a/lib/ephy-node.h +++ b/lib/ephy-node.h @@ -1,5 +1,7 @@ /* * Copyright (C) 2002 Jorn Baayen + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +25,7 @@ #define EPHY_NODE_H #include +#include G_BEGIN_DECLS @@ -100,8 +103,8 @@ char *ephy_node_get_property_time (EphyNode *node, guint property_id); /* xml storage */ -void ephy_node_save_to_xml (EphyNode *node, - xmlNodePtr parent_xml_node); +int ephy_node_write_to_xml (EphyNode *node, + xmlTextWriterPtr writer); EphyNode *ephy_node_new_from_xml (EphyNodeDb *db, xmlNodePtr xml_node); diff --git a/lib/ephy-state.c b/lib/ephy-state.c index c797d2211..33edb87a5 100644 --- a/lib/ephy-state.c +++ b/lib/ephy-state.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2001 Matthew Mueller - * (C) 2002 Jorn Baayen - * (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2002 Jorn Baayen + * Copyright (C) 2003 Marco Pesenti Gritti * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ #include #include -#define STATES_FILE "states.xml" +#define EPHY_STATES_XML_FILE "states.xml" #define EPHY_STATES_XML_ROOT "ephy_states" #define EPHY_STATES_XML_VERSION "1.0" @@ -50,39 +50,21 @@ static EphyNodeDb *states_db = NULL; static void ephy_states_save (void) { - xmlDocPtr doc; - xmlNodePtr root; - GPtrArray *children; - int i; char *xml_file; - if (states == NULL) return; - xml_file = g_build_filename (ephy_dot_dir (), - STATES_FILE, + EPHY_STATES_XML_FILE, NULL); - /* save nodes to xml */ - xmlIndentTreeOutput = TRUE; - doc = xmlNewDoc ("1.0"); - - root = xmlNewDocNode (doc, NULL, "ephy_states", NULL); - xmlSetProp (root, "version", EPHY_STATES_XML_VERSION); - xmlDocSetRootElement (doc, root); - - children = ephy_node_get_children (states); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; - - kid = g_ptr_array_index (children, i); - - ephy_node_save_to_xml (kid, root); - } - ephy_node_thaw (states); + ephy_node_db_write_to_xml_safe + (states_db, xml_file, + EPHY_STATES_XML_ROOT, + EPHY_STATES_XML_VERSION, + NULL, /* comment */ + states, 0, + NULL); - ephy_file_save_xml (xml_file, doc); - g_free (xml_file); + g_free (xml_file); } static EphyNode * @@ -120,7 +102,7 @@ ensure_states (void) char *xml_file; xml_file = g_build_filename (ephy_dot_dir (), - STATES_FILE, + EPHY_STATES_XML_FILE, NULL); states_db = ephy_node_db_new (EPHY_NODE_DB_STATES); diff --git a/src/bookmarks/ephy-bookmarks-export.c b/src/bookmarks/ephy-bookmarks-export.c index be9b97ea7..b0ac4bc56 100644 --- a/src/bookmarks/ephy-bookmarks-export.c +++ b/src/bookmarks/ephy-bookmarks-export.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,24 +15,29 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ */ -#include -#include -#include - #include "ephy-bookmarks-export.h" #include "ephy-node-common.h" #include "ephy-file-helpers.h" #include "ephy-debug.h" -static void -add_topics_list (EphyNode *topics, EphyNode *bmk, - xmlNodePtr parent, xmlNsPtr dc_ns) +#include +#include +#include +#include + +static int +write_topics_list (EphyNode *topics, + EphyNode *bmk, + xmlTextWriterPtr writer) { GPtrArray *children; + GList *keywords = NULL, *l; int i; - GList *bmks = NULL, *l; + int ret = 0; children = ephy_node_get_children (topics); for (i = 0; i < children->len; i++) @@ -47,26 +53,27 @@ add_topics_list (EphyNode *topics, EphyNode *bmk, if (priority == EPHY_NODE_NORMAL_PRIORITY && ephy_node_has_child (kid, bmk)) { - bmks = g_list_append (bmks, kid); + keywords = g_list_prepend (keywords, kid); } } ephy_node_thaw (topics); - if (bmks == NULL) return; - - for (l = bmks; l != NULL; l = l->next) + for (l = keywords; l != NULL; l = l->next) { - const char *name; EphyNode *node = l->data; - xmlNodePtr item_node; + const char *name; name = ephy_node_get_property_string (node, EPHY_NODE_KEYWORD_PROP_NAME); - item_node = xmlNewChild (parent, dc_ns, "subject", NULL); - xmlNodeSetContent (item_node, name); + + ret = xmlTextWriterWriteElementNS + (writer, "dc", "subject", NULL, name); + if (ret < 0) break; } - g_list_free (bmks); + g_list_free (keywords); + + return ret >= 0 ? 0 : -1; } void @@ -74,50 +81,128 @@ ephy_bookmarks_export_rdf (EphyBookmarks *bookmarks, const char *filename) { EphyNode *bmks, *topics, *smart_bmks; - xmlDocPtr doc; - xmlNodePtr root, xml_node, channel_node, channel_seq_node; - xmlNsPtr ephy_ns, rdf_ns, dc_ns; + xmlTextWriterPtr writer; + char *tmp_file; GPtrArray *children; char *file_uri; - int i; + int i, ret; + + LOG ("Exporting as RDF to %s", filename) + + START_PROFILER ("Exporting as RDF") + + tmp_file = g_strconcat (filename, ".tmp", NULL); + + /* FIXME: do we want to turn on compression here? */ + writer = xmlNewTextWriterFilename (tmp_file, 0); + if (writer == NULL) return; - LOG ("Exporting to rdf") + ret = xmlTextWriterStartDocument (writer, "1.0", NULL, NULL); + if (ret < 0) goto out; - xmlIndentTreeOutput = TRUE; - doc = xmlNewDoc ("1.0"); + ret = xmlTextWriterStartElementNS + (writer, "rdf", "RDF", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + if (ret < 0) goto out; - root = xmlNewDocNode (doc, NULL, "rdf:RDF", NULL); - xmlDocSetRootElement (doc, root); - rdf_ns = xmlNewNs (root, "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf"); - xmlNewNs (root, "http://purl.org/rss/1.0/", NULL); - dc_ns = xmlNewNs (root, "http://purl.org/dc/elements/1.1/", "dc"); - ephy_ns = xmlNewNs (root, "http://gnome.org/ns/epiphany#", "ephy"); - channel_node = xmlNewChild (root, NULL, "channel", NULL); + ret = xmlTextWriterWriteAttribute (writer, "xmlns", "http://purl.org/rss/1.0/"); + if (ret < 0) goto out; + + ret = xmlTextWriterWriteAttributeNS + (writer, "xmlns", "dc", NULL, "http://purl.org/dc/elements/1.1/"); + if (ret < 0) goto out; + + ret = xmlTextWriterWriteAttributeNS + (writer, "xmlns", "ephy", NULL, "http://gnome.org/ns/epiphany#"); + if (ret < 0) goto out; + + ret = xmlTextWriterStartElement (writer, "channel"); + if (ret < 0) goto out; + + /* FIXME is this UTF-8 ? */ file_uri = gnome_vfs_get_uri_from_local_path (filename); - xmlSetProp (channel_node, "rdf:about", file_uri); + ret = xmlTextWriterWriteAttributeNS (writer, "rdf", "about", NULL, file_uri); g_free (file_uri); + if (ret < 0) goto out; - xml_node = xmlNewChild (channel_node, NULL, "title", NULL); - xmlNodeSetContent (xml_node, "Epiphany bookmarks"); + ret = xmlTextWriterWriteElement (writer, "title", "Epiphany bookmarks"); + if (ret < 0) goto out; - xml_node = xmlNewChild (channel_node, NULL, "link", NULL); - xmlNodeSetContent (xml_node, "http://epiphany.mozdev.org"); + ret = xmlTextWriterWriteElement + (writer, "link", "http://www.gnome.org/projects/epiphany/"); + if (ret < 0) goto out; - xml_node = xmlNewChild (channel_node, NULL, "items", NULL); + ret = xmlTextWriterStartElement (writer, "items"); + if (ret < 0) goto out; - channel_seq_node = xmlNewChild (xml_node, rdf_ns, "Seq", NULL); + ret = xmlTextWriterStartElementNS (writer, "rdf", "Seq", NULL); + if (ret < 0) goto out; bmks = ephy_bookmarks_get_bookmarks (bookmarks); topics = ephy_bookmarks_get_keywords (bookmarks); smart_bmks = ephy_bookmarks_get_smart_bookmarks (bookmarks); children = ephy_node_get_children (bmks); - for (i = 0; i < children->len; i++) + for (i=0; i < children->len; i++) + { + EphyNode *kid; + const char *url; + char *link = NULL; + gboolean smart_url; + + kid = g_ptr_array_index (children, i); + + smart_url = ephy_node_has_child (smart_bmks, kid); + url = ephy_node_get_property_string + (kid, EPHY_NODE_BMK_PROP_LOCATION); + if (smart_url) + { + GnomeVFSURI *uri; + + uri = gnome_vfs_uri_new (url); + + if (uri) + { + link = g_strconcat (gnome_vfs_uri_get_scheme (uri), + "://", + gnome_vfs_uri_get_host_name (uri), + NULL); + + gnome_vfs_uri_unref (uri); + } + } + + if (link == NULL) + { + link = g_strdup (url); + } + + ret = xmlTextWriterStartElementNS (writer, "rdf", "li", NULL); + if (ret < 0) break; + + ret = xmlTextWriterWriteAttributeNS + (writer, "rdf", "about", NULL, link); + if (ret < 0) break; + + ret = xmlTextWriterEndElement (writer); /* rdf:li */ + if (ret < 0) break; + } + ephy_node_thaw (bmks); + if (ret < 0) goto out; + + ret = xmlTextWriterEndElement (writer); /* rdf:Seq */ + if (ret < 0) goto out; + + ret = xmlTextWriterEndElement (writer); /* items */ + if (ret < 0) goto out; + + ret = xmlTextWriterEndElement (writer); /* channel */ + if (ret < 0) goto out; + + children = ephy_node_get_children (bmks); + for (i=0; i < children->len; i++) { EphyNode *kid; const char *url, *title; - xmlNodePtr item_node; - xmlChar *encoded_link; char *link = NULL; gboolean smart_url; @@ -151,33 +236,54 @@ ephy_bookmarks_export_rdf (EphyBookmarks *bookmarks, link = g_strdup (url); } - encoded_link = xmlEncodeEntitiesReentrant (doc, link); - - item_node = xmlNewChild (channel_seq_node, rdf_ns, "li", NULL); - xmlSetNsProp (item_node, rdf_ns, "about", link); + ret = xmlTextWriterStartElement (writer, "item"); + if (ret < 0) break; - item_node = xmlNewChild (root, NULL, "item", NULL); - xmlSetNsProp (item_node, rdf_ns, "about", link); + ret = xmlTextWriterWriteAttributeNS + (writer, "rdf", "about", NULL, link); + if (ret < 0) break; - xml_node = xmlNewChild (item_node, NULL, "title", title); + ret = xmlTextWriterWriteElement (writer, "title", title); + if (ret < 0) break; - xml_node = xmlNewChild (item_node, NULL, "link", encoded_link); + ret = xmlTextWriterWriteElement (writer, "link", link); + if (ret < 0) break; if (smart_url) { - xmlChar *encoded_url; - encoded_url = xmlEncodeEntitiesReentrant (doc, url); - xml_node = xmlNewChild (item_node, ephy_ns, "smartlink", encoded_url); - xmlFree (encoded_url); + ret = xmlTextWriterWriteElementNS (writer, "ephy", "smartlink", NULL, url); + if (ret < 0) break; } - add_topics_list (topics, kid, item_node, dc_ns); + ret = write_topics_list (topics, kid, writer); + if (ret < 0) break; + + ret = xmlTextWriterEndElement (writer); /* item */ - xmlFree (encoded_link); g_free (link); + + i++; } ephy_node_thaw (bmks); + if (ret < 0) goto out; + + ret = xmlTextWriterEndElement (writer); /* rdf:RDF */ + if (ret < 0) goto out; + + ret = xmlTextWriterEndDocument (writer); + +out: + xmlFreeTextWriter (writer); + + if (ret >= 0) + { + if (ephy_file_switch_temp_file (filename, tmp_file) == FALSE) + { + ret = -1; + } + } + + STOP_PROFILER ("Exporting as RDF") - ephy_file_save_xml (filename, doc); - xmlFreeDoc(doc); + LOG ("Exporting as RDF %s.", ret >= 0 ? "succeeded" : "FAILED") } diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c index 020eab429..2caf08c05 100644 --- a/src/bookmarks/ephy-bookmarks.c +++ b/src/bookmarks/ephy-bookmarks.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002 Marco Pesenti Gritti + * Copyright (C) 2002, 2003 Marco Pesenti Gritti * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ */ #ifdef HAVE_CONFIG_H -#include +#include "config.h" #endif #include "ephy-bookmarks.h" @@ -249,54 +249,19 @@ ephy_bookmarks_class_init (EphyBookmarksClass *klass) static void ephy_bookmarks_save (EphyBookmarks *eb) { - xmlDocPtr doc; - xmlNodePtr root; - xmlNodePtr comment; - GPtrArray *children; - int i; LOG ("Saving bookmarks") - /* save nodes to xml */ - xmlIndentTreeOutput = TRUE; - doc = xmlNewDoc ("1.0"); - - root = xmlNewDocNode (doc, NULL, "ephy_bookmarks", NULL); - xmlSetProp (root, "version", EPHY_BOOKMARKS_XML_VERSION); - xmlDocSetRootElement (doc, root); - - comment = xmlNewDocComment (doc, "Do not rely on this file, it's only for internal use. Use bookmarks.rdf instead."); - xmlAddChild (root, comment); - - children = ephy_node_get_children (eb->priv->keywords); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; - - kid = g_ptr_array_index (children, i); - - if (kid != eb->priv->bookmarks && - kid != eb->priv->favorites && - kid != eb->priv->notcategorized) - { - ephy_node_save_to_xml (kid, root); - } - } - ephy_node_thaw (eb->priv->keywords); - - children = ephy_node_get_children (eb->priv->bookmarks); - for (i = 0; i < children->len; i++) - { - EphyNode *kid; - - kid = g_ptr_array_index (children, i); - - ephy_node_save_to_xml (kid, root); - } - ephy_node_thaw (eb->priv->bookmarks); - - ephy_file_save_xml (eb->priv->xml_file, doc); - xmlFreeDoc(doc); + ephy_node_db_write_to_xml_safe + (eb->priv->db, eb->priv->xml_file, + EPHY_BOOKMARKS_XML_ROOT, + EPHY_BOOKMARKS_XML_VERSION, + "Do not rely on this file, it's only for internal use. Use bookmarks.rdf instead.", + eb->priv->keywords, + 3, eb->priv->bookmarks, eb->priv->favorites, eb->priv->notcategorized, + eb->priv->bookmarks, + 0, + NULL); /* Export bookmarks in rdf */ ephy_bookmarks_export_rdf (eb, eb->priv->rdf_file); -- cgit v1.2.3