changeset 10415:5b7a74d397cc

[gaim-migrate @ 11665] Ability to save statuses. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 25 Dec 2004 19:54:24 +0000
parents 26eac2362c32
children 73d3a64d5574
files src/status.c src/util.c src/util.h src/xmlnode.c src/xmlnode.h
diffstat 5 files changed, 103 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/src/status.c	Sat Dec 25 18:33:27 2004 +0000
+++ b/src/status.c	Sat Dec 25 19:54:24 2004 +0000
@@ -166,6 +166,7 @@
 
 static GHashTable *buddy_presences = NULL;
 static GList *saved_statuses = NULL;
+gboolean have_read_saved_statuses = FALSE;
 
 #define SCORE_IDLE      5
 #define SCORE_IDLE_TIME 6
@@ -2000,6 +2001,8 @@
 
 	g_return_if_fail(user_dir != NULL);
 
+	have_read_saved_statuses = TRUE;
+
 	filename = g_build_filename(user_dir, "status.xml", NULL);
 
 	if (g_file_test(filename, G_FILE_TEST_EXISTS))
@@ -2018,10 +2021,60 @@
 	g_free(filename);
 }
 
+static xmlnode *
+gaim_status_get_as_xmlnode(GaimStatusSaved *status)
+{
+	xmlnode *node, *child;
+
+	node = xmlnode_new("status");
+	xmlnode_set_attrib(node, "name", status->title);
+
+	child = xmlnode_new("state");
+	xmlnode_insert_data(child, primitive_names[status->type], -1);
+	xmlnode_insert_child(node, child);
+
+	child = xmlnode_new("message");
+	xmlnode_insert_data(child, status->message, -1);
+	xmlnode_insert_child(node, child);
+
+	/* TODO: Add substatuses to the tree */
+
+	return node;
+}
+
+static xmlnode *
+gaim_statuses_get_as_xmlnode()
+{
+	xmlnode *node, *child;
+	GList *cur;
+
+	node = xmlnode_new("statuses");
+	xmlnode_set_attrib(node, "version", "1");
+
+	for (cur = saved_statuses; cur != NULL; cur = cur->next)
+	{
+		child = gaim_status_get_as_xmlnode(cur->data);
+		xmlnode_insert_child(node, child);
+	}
+
+	return node;
+}
+
 void
 gaim_statuses_sync(void)
 {
-	/* TODO: Only attempt to write if we've already read the file. */
+	xmlnode *statuses;
+	char *data;
 
-	//gaim_util_write_xml_file("status.xml", data);
+	if (!have_read_saved_statuses) {
+		gaim_debug_error("status", "Attempted to save statuses before they "
+						 "were read!\n");
+		return;
+	}
+
+	statuses = gaim_statuses_get_as_xmlnode();
+	data = xmlnode_to_formatted_str(statuses, NULL);
+	gaim_util_write_data_to_file("status.xml", data, -1);
+	g_free(data);
+	xmlnode_free(statuses);
 }
--- a/src/util.c	Sat Dec 25 18:33:27 2004 +0000
+++ b/src/util.c	Sat Dec 25 19:54:24 2004 +0000
@@ -1935,12 +1935,12 @@
  * people's settings if there is a problem writing the new values.
  */
 gboolean
-gaim_util_write_xml_file(const char *filename, const char *data)
+gaim_util_write_data_to_file(const char *filename, const char *data, size_t size)
 {
 	const char *user_dir = gaim_user_dir();
 	gchar *filename_temp, *filename_full;
 	FILE *file;
-	size_t datalen, byteswritten;
+	size_t real_size, byteswritten;
 	struct stat st;
 
 	g_return_val_if_fail(user_dir != NULL, FALSE);
@@ -1959,7 +1959,7 @@
 		}
 	}
 
-	filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.xml", user_dir, filename);
+	filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename);
 	filename_temp = g_strdup_printf("%s.save", filename_full);
 
 	/* Remove an old temporary file, if one exists */
@@ -1984,8 +1984,8 @@
 	}
 
 	/* Write to file */
-	datalen = strlen(data);
-	byteswritten = fwrite(data, 1, datalen, file);
+	real_size = (size == -1) ? strlen(data) : size;
+	byteswritten = fwrite(data, 1, real_size, file);
 
 	/* Close file */
 	if (fclose(file) != 0)
@@ -1998,17 +1998,17 @@
 	}
 
 	/* Ensure the file is the correct size */
-	if (byteswritten != datalen)
+	if (byteswritten != real_size)
 	{
 		gaim_debug_error("util", "Error writing to file %s: Wrote %z bytes "
 						 "but should have written %z; is your disk full?\n",
-						 filename_temp, byteswritten, datalen);
+						 filename_temp, byteswritten, real_size);
 		g_free(filename_full);
 		g_free(filename_temp);
 		return FALSE;
 	}
 	/* Use stat to be absolutely sure. */
-	if ((stat(filename_temp, &st) == -1) || (st.st_size != datalen))
+	if ((stat(filename_temp, &st) == -1) || (st.st_size != real_size))
 	{
 		gaim_debug_error("util", "Error writing data to file %s: "
 						 "Incomplete file written; is your disk full?\n",
--- a/src/util.h	Sat Dec 25 18:33:27 2004 +0000
+++ b/src/util.h	Sat Dec 25 19:54:24 2004 +0000
@@ -377,18 +377,22 @@
 int gaim_build_dir(const char *path, int mode);
 
 /**
- * Write a null-terminated string of data to a file of the given name
- * in the Gaim user directory ($HOME/.gaim by default).  The data is
- * typically a serialized version of one of Gaim's config files, such
- * as prefs.xml, accounts.xml, etc.  And the string is typically
- * obtained using xmlnode_to_formatted_str.
+ * Write a string of data to a file of the given name in the Gaim
+ * user directory ($HOME/.gaim by default).  The data is typically
+ * a serialized version of one of Gaim's config files, such as
+ * prefs.xml, accounts.xml, etc.  And the string is typically
+ * obtained using xmlnode_to_formatted_str.  However, this function
+ * should work fine for saving binary files as well.
  *
  * @param filename The basename of the file to write in the gaim_user_dir.
  * @param data     A null-terminated string of data to write.
+ * @param size     The size of the data to save.  If data is
+ *                 null-terminated you can pass in -1.
  *
  * @return TRUE if the file was written successfully.  FALSE otherwise.
  */
-gboolean gaim_util_write_xml_file(const char *filename, const char *data);
+gboolean gaim_util_write_data_to_file(const char *filename, const char *data,
+									  size_t size);
 
 /**
  * Creates a temporary file and returns a file pointer to it.
--- a/src/xmlnode.c	Sat Dec 25 18:33:27 2004 +0000
+++ b/src/xmlnode.c	Sat Dec 25 19:54:24 2004 +0000
@@ -85,23 +85,23 @@
 }
 
 void
-xmlnode_insert_data(xmlnode *parent, const char *data, size_t size)
+xmlnode_insert_data(xmlnode *node, const char *data, size_t size)
 {
-	xmlnode *node;
+	xmlnode *child;
 	size_t real_size;
 
-	g_return_if_fail(parent != NULL);
+	g_return_if_fail(node != NULL);
 	g_return_if_fail(data != NULL);
 	g_return_if_fail(size != 0);
 
 	real_size = size == -1 ? strlen(data) : size;
 
-	node = new_node(NULL, XMLNODE_TYPE_DATA);
+	child = new_node(NULL, XMLNODE_TYPE_DATA);
 
-	node->data = g_memdup(data, real_size);
-	node->data_sz = real_size;
+	child->data = g_memdup(data, real_size);
+	child->data_sz = real_size;
 
-	xmlnode_insert_child(parent, node);
+	xmlnode_insert_child(node, child);
 }
 
 void
@@ -243,7 +243,7 @@
 	return g_string_free(str, FALSE);
 }
 
-static char *xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
+static gchar *xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
 {
 	GString *text = g_string_new("");
 	xmlnode *c;
@@ -297,9 +297,9 @@
 
 		if(tab && pretty)
 			text = g_string_append(text, tab);
-		g_string_append_printf(text, "</%s>%s", node_name, pretty ? newline : "");
+		g_string_append_printf(text, "</%s>%s", node_name, formatting ? newline : "");
 	} else {
-		g_string_append_printf(text, "/>%s", pretty ? newline : "");
+		g_string_append_printf(text, "/>%s", formatting ? newline : "");
 	}
 
 	g_free(node_name);
@@ -313,12 +313,19 @@
 	return g_string_free(text, FALSE);
 }
 
-char *xmlnode_to_str(xmlnode *node, int *len) {
+gchar *xmlnode_to_str(xmlnode *node, int *len) {
 	return xmlnode_to_str_helper(node, len, FALSE, 0);
 }
 
-char *xmlnode_to_formatted_str(xmlnode *node, int *len) {
-	return xmlnode_to_str_helper(node, len, TRUE, 0);
+gchar *xmlnode_to_formatted_str(xmlnode *node, int *len) {
+	gchar *xml, *xml_with_declaration;
+
+	xml = xmlnode_to_str_helper(node, len, TRUE, 0);
+	xml_with_declaration =
+		g_strdup_printf("<?xml version='1.0' encoding='UTF-8' ?>\n\n%s", xml);
+	g_free(xml);
+
+	return xml_with_declaration;
 }
 
 struct _xmlnode_parser_data {
--- a/src/xmlnode.h	Sat Dec 25 18:33:27 2004 +0000
+++ b/src/xmlnode.h	Sat Dec 25 19:54:24 2004 +0000
@@ -109,11 +109,12 @@
 /**
  * Inserts data into a node.
  *
- * @param parent The node to insert data into.
+ * @param node   The node to insert data into.
  * @param data   The data to insert.
- * @param size   The size of the data to insert.
+ * @param size   The size of the data to insert.  If data is
+ *               null-terminated you can pass in -1.
  */
-void xmlnode_insert_data(xmlnode *parent, const char *data, size_t size);
+void xmlnode_insert_data(xmlnode *node, const char *data, size_t size);
 
 /**
  * Gets data from a node.
@@ -157,9 +158,10 @@
  * @param node The starting node to output.
  * @param len  Address for the size of the string.
  *
- * @return The node repersented as a string.
+ * @return The node repersented as a string.  You must
+ *         g_free this string when finished using it.
  */
-char *xmlnode_to_str(xmlnode *node, int *len);
+gchar *xmlnode_to_str(xmlnode *node, int *len);
 
 /**
  * Returns the node in a string of human readable xml.
@@ -168,9 +170,10 @@
  * @param len  Address for the size of the string.
  *
  * @return The node as human readable string including
- *          tab and new line characters.
+ *         tab and new line characters.  You must
+ *         g_free this string when finished using it.
  */
-char *xmlnode_to_formatted_str(xmlnode *node, int *len);
+gchar *xmlnode_to_formatted_str(xmlnode *node, int *len);
 
 /**
  * Creates a node from a string of XML.  Calling this on the