# HG changeset patch # User Mark Doliner # Date 1104004464 0 # Node ID 5b7a74d397cc8f4082e5b74985f47e35c01b8f1c # Parent 26eac2362c32107b5a47745620af10bbbb0ffb69 [gaim-migrate @ 11665] Ability to save statuses. committer: Tailor Script diff -r 26eac2362c32 -r 5b7a74d397cc src/status.c --- 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); } diff -r 26eac2362c32 -r 5b7a74d397cc src/util.c --- 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", diff -r 26eac2362c32 -r 5b7a74d397cc src/util.h --- 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. diff -r 26eac2362c32 -r 5b7a74d397cc src/xmlnode.c --- 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", node_name, pretty ? newline : ""); + g_string_append_printf(text, "%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("\n\n%s", xml); + g_free(xml); + + return xml_with_declaration; } struct _xmlnode_parser_data { diff -r 26eac2362c32 -r 5b7a74d397cc src/xmlnode.h --- 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