From 4e4eb45bf69d539996b298a13bf650c5ebea7f16 Mon Sep 17 00:00:00 2001 From: bertrand Date: Sun, 5 Sep 1999 16:15:12 +0000 Subject: use folder summary instead of opening all messages. 1999-09-05 bertrand * tests/ui-tests/store_listing.c (show_folder_messages): use folder summary instead of opening all messages. * camel/providers/MH/camel-mh-folder.c (_create_summary): basic and highly non-efficient summary implementation. Should be seen as a proof of concept only. subfolder summary still has to be implemented. * camel/providers/maildir/camel-maildir-folder.c (_init_with_store): hasn't summary for the moment. * camel/providers/maildir/camel-maildir-folder.c cosmetic changes. svn path=/trunk/; revision=1178 --- camel/providers/MH/camel-mh-folder.c | 49 +++- camel/providers/maildir/camel-maildir-folder.c | 374 ++++++++++++++----------- 2 files changed, 253 insertions(+), 170 deletions(-) (limited to 'camel/providers') diff --git a/camel/providers/MH/camel-mh-folder.c b/camel/providers/MH/camel-mh-folder.c index 300d8366d3..fa6661c722 100644 --- a/camel/providers/MH/camel-mh-folder.c +++ b/camel/providers/MH/camel-mh-folder.c @@ -37,6 +37,7 @@ #include "camel-stream-fs.h" #include "camel-stream-buffered-fs.h" #include "camel-folder-summary.h" +#include "gmime-utils.h" static CamelFolderClass *parent_class=NULL; @@ -46,7 +47,7 @@ static CamelFolderClass *parent_class=NULL; #define CF_CLASS(so) CAMEL_FOLDER_CLASS (GTK_OBJECT(so)->klass) #define CMHS_CLASS(so) CAMEL_STORE_CLASS (GTK_OBJECT(so)->klass) -static int copy_reg (const char *src_path, const char *dst_path); + static void _set_name(CamelFolder *folder, const gchar *name); static void _init_with_store (CamelFolder *folder, CamelStore *parent_store); static gboolean _exists (CamelFolder *folder); @@ -61,6 +62,9 @@ static void _expunge (CamelFolder *folder); static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, CamelFolder *dest_folder); static void _open (CamelFolder *folder, CamelFolderOpenMode mode); + +/* some utility functions */ +static int copy_reg (const char *src_path, const char *dst_path); static gboolean _is_a_message_file (const gchar *file_name, const gchar *file_path); static void @@ -148,18 +152,51 @@ static void _create_summary (CamelFolder *folder) { CamelMhFolder *mh_folder = CAMEL_MH_FOLDER (folder); + CamelFolderSummary *summary = folder->summary; CamelMessageInfo *message_info; - CamelFolderSummary *subfolder_info; - + CamelFolderInfo *subfolder_info; + CamelStream *message_stream; GList *file_list = mh_folder->file_name_list; gchar *filename; + gchar *message_fullpath; + gchar *directory_path = mh_folder->directory_path; + GArray *header_array; + Rfc822Header *cur_header; + int i; + + summary = folder->summary; while (file_list) { filename = (gchar *)(file_list->data); message_info = g_new0 (CamelMessageInfo, 1); - message_info->subject = NULL; + message_fullpath = g_strdup_printf ("%s/%s", directory_path, filename); + message_stream = camel_stream_buffered_fs_new_with_name (message_fullpath, + CAMEL_STREAM_BUFFERED_FS_READ); + header_array = get_header_array_from_stream (message_stream); + gtk_object_unref (GTK_OBJECT (message_stream)); + + for (i=0; ilen; i++) { + cur_header = (Rfc822Header *)header_array->data + i; + if (!g_strcasecmp (cur_header->name, "subject")) { + message_info->subject = cur_header->value; + g_free (cur_header->name); + } else if (!g_strcasecmp (cur_header->name, "sender")) { + message_info->date = cur_header->value; + g_free (cur_header->name); + } else if (!g_strcasecmp (cur_header->name, "date")) { + message_info->date = cur_header->value; + g_free (cur_header->name); + } else { + g_free (cur_header->name); + g_free (cur_header->value); + } + } + g_array_free (header_array, TRUE); + + message_info->UID = NULL; + summary->message_info_list = g_list_append (summary->message_info_list, message_info); file_list = file_list->next; } } @@ -172,7 +209,8 @@ _open (CamelFolder *folder, CamelFolderOpenMode mode) CamelMhFolder *mh_folder = CAMEL_MH_FOLDER (folder); struct dirent *dir_entry; DIR *dir_handle; - + + if (folder->open_state == FOLDER_OPEN) return; @@ -194,6 +232,7 @@ _open (CamelFolder *folder, CamelFolderOpenMode mode) closedir (dir_handle); + _create_summary (folder); } /** diff --git a/camel/providers/maildir/camel-maildir-folder.c b/camel/providers/maildir/camel-maildir-folder.c index 489fd37009..9b663aa191 100644 --- a/camel/providers/maildir/camel-maildir-folder.c +++ b/camel/providers/maildir/camel-maildir-folder.c @@ -20,6 +20,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + +/* + * AUTHORS : Jukka Zitting + * + */ + + #include #include #include @@ -53,131 +60,76 @@ static CamelFolderClass *parent_class=NULL; #define GETMSG "CamelMaildirFolder::get_message" #define NUMMSGS "CamelMaildirFolder::get_message_count" -static DIR * -_xopendir (const gchar *path) -{ - DIR *handle; - g_assert (path); - - handle = opendir (path); - if (!handle) { - CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - } - - return handle; -} - -static gboolean -_xstat (const gchar *path, struct stat *buf) -{ - gint stat_error; - g_assert (path); - g_assert (buf); - - stat_error = stat (path, buf); - if (stat_error == 0) { - return TRUE; - } else if (errno == ENOENT) { - buf->st_mode = 0; - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: stat (%s, %p);\n", path, buf); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} - -static gboolean -_xmkdir (const gchar *path) -{ - g_assert (path); - if (mkdir (path, S_IRWXU) == -1) { - CAMEL_LOG_WARNING ("ERROR: mkdir (%s, S_IRWXU);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } +static void _init_with_store (CamelFolder *folder, CamelStore *parent_store); +static void _set_name (CamelFolder *folder, const gchar *name); +static gboolean _exists (CamelFolder *folder); +static gboolean _create (CamelFolder *folder); +static gboolean _delete (CamelFolder *folder, gboolean recurse); +static gboolean _delete_messages (CamelFolder *folder); +static CamelMimeMessage *_get_message (CamelFolder *folder, gint number); +static gint _get_message_count (CamelFolder *folder); +static void _expunge (CamelFolder *folder); + +/* fs utility functions */ +static DIR * _xopendir (const gchar *path); +static gboolean _xstat (const gchar *path, struct stat *buf); +static gboolean _xmkdir (const gchar *path); +static gboolean _xlink (const gchar *from, const gchar *to); +static gboolean _xunlink (const gchar *path); +static gboolean _xrmdir (const gchar *path); +/* ** */ - return TRUE; -} - -static gboolean -_xlink (const gchar *from, const gchar *to) +static void +camel_maildir_folder_class_init (CamelMaildirFolderClass *camel_maildir_folder_class) { - g_assert (from); - g_assert (to); + CamelFolderClass *camel_folder_class = + CAMEL_FOLDER_CLASS (camel_maildir_folder_class); - if (link (from, to) == 0) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: link (%s, %s);\n", from, to); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } + parent_class = gtk_type_class (camel_folder_get_type ()); + + /* virtual method definition */ + /* virtual method overload */ + camel_folder_class->init_with_store = _init_with_store; + camel_folder_class->set_name = _set_name; + camel_folder_class->exists = _exists; + camel_folder_class->create = _create; + camel_folder_class->delete = _delete; + camel_folder_class->delete_messages = _delete_messages; + camel_folder_class->expunge = _expunge; + camel_folder_class->get_message = _get_message; + camel_folder_class->get_message_count = _get_message_count; } -static gboolean -_xunlink (const gchar *path) +GtkType +camel_maildir_folder_get_type (void) { - g_assert (path); - - if (unlink (path) == 0) { - return TRUE; - } else if (errno == ENOENT) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: unlink (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; + static GtkType camel_maildir_folder_type = 0; + + if (!camel_maildir_folder_type) { + GtkTypeInfo camel_maildir_folder_info = + { + "CamelMaildirFolder", + sizeof (CamelMaildirFolder), + sizeof (CamelMaildirFolderClass), + (GtkClassInitFunc) camel_maildir_folder_class_init, + (GtkObjectInitFunc) NULL, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + camel_maildir_folder_type = + gtk_type_unique (CAMEL_FOLDER_TYPE, &camel_maildir_folder_info); } + + return camel_maildir_folder_type; } -static gboolean -_xrmdir (const gchar *path) -{ - DIR *dir_handle; - struct dirent *dir_entry; - gchar *file; - struct stat statbuf; - g_assert (path); - dir_handle = opendir (path); - if (!dir_handle && errno == ENOENT) { - return TRUE; - } else if (!dir_handle) { - CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } - while ((dir_entry = readdir (dir_handle))) { - file = g_strconcat (path, G_DIR_SEPARATOR_S, dir_entry->d_name, - NULL); - if (_xstat (file, &statbuf) && S_ISREG (statbuf.st_mode)) - _xunlink (file); - g_free (file); - } - closedir (dir_handle); - if (rmdir (path) == 0) { - return TRUE; - } else if (errno == ENOENT) { - return TRUE; - } else { - CAMEL_LOG_WARNING ("ERROR: rmdir (%s);\n", path); - CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", - errno, strerror(errno)); - return FALSE; - } -} /** * CamelMaildirFolder::init_with_store: initializes the folder object @@ -188,8 +140,8 @@ _xrmdir (const gchar *path) * Perhaps we'll later implement subfolders too... */ static void -camel_maildir_folder_init_with_store (CamelFolder *folder, - CamelStore *parent_store) +_init_with_store (CamelFolder *folder, + CamelStore *parent_store) { CAMEL_LOG_FULL_DEBUG ("Entering CamelMaildirFolder::init_with_store\n"); g_assert(folder); @@ -200,6 +152,7 @@ camel_maildir_folder_init_with_store (CamelFolder *folder, folder->can_hold_messages = TRUE; folder->can_hold_folders = FALSE; + folder->has_summary_capability = FALSE; CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::init_with_store\n"); } @@ -213,7 +166,7 @@ camel_maildir_folder_init_with_store (CamelFolder *folder, * the given name is not checked in this function. */ static void -camel_maildir_folder_set_name (CamelFolder *folder, const gchar *name) +_set_name (CamelFolder *folder, const gchar *name) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); @@ -250,7 +203,7 @@ camel_maildir_folder_set_name (CamelFolder *folder, const gchar *name) * Return value: TRUE if the maildir exists, FALSE otherwise */ static gboolean -camel_maildir_folder_exists (CamelFolder *folder) +_exists (CamelFolder *folder) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); static const gchar *dir[3] = { "new", "cur", "tmp" }; @@ -303,7 +256,7 @@ camel_maildir_folder_exists (CamelFolder *folder) * FALSE otherwise */ static gboolean -camel_maildir_folder_create (CamelFolder *folder) +_create (CamelFolder *folder) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); static const gchar *dir[3] = { "new", "cur", "tmp" }; @@ -354,7 +307,7 @@ camel_maildir_folder_create (CamelFolder *folder) * maildir directory won't be removed, but it might no longer be a valid maildir. */ static gboolean -camel_maildir_folder_delete (CamelFolder *folder, gboolean recurse) +_delete (CamelFolder *folder, gboolean recurse) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); static const gchar *dir[3] = { "new", "cur", "tmp" }; @@ -412,7 +365,7 @@ camel_maildir_folder_delete (CamelFolder *folder, gboolean recurse) * TRUE otherwise. */ static gboolean -camel_maildir_folder_delete_messages (CamelFolder *folder) +_delete_messages (CamelFolder *folder) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER (folder); const gchar *maildir; @@ -469,7 +422,7 @@ camel_maildir_folder_delete_messages (CamelFolder *folder) * Return value: the message, NULL on error */ static CamelMimeMessage * -camel_maildir_folder_get_message (CamelFolder *folder, gint number) +_get_message (CamelFolder *folder, gint number) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(folder); DIR *dir_handle; @@ -540,7 +493,7 @@ camel_maildir_folder_get_message (CamelFolder *folder, gint number) * Return value: number of messages in the maildir, -1 on error */ static gint -camel_maildir_folder_get_message_count (CamelFolder *folder) +_get_message_count (CamelFolder *folder) { CamelMaildirFolder *maildir_folder = CAMEL_MAILDIR_FOLDER(folder); const gchar *maildir; @@ -599,6 +552,9 @@ camel_maildir_folder_get_message_count (CamelFolder *folder) return count; } + + + /** * CamelMaildirFolder::expunge: expunge messages marked as deleted * @folder: the folder object @@ -606,7 +562,7 @@ camel_maildir_folder_get_message_count (CamelFolder *folder) * Physically deletes the messages marked as deleted in the folder. */ static void -camel_maildir_folder_expunge (CamelFolder *folder) +_expunge (CamelFolder *folder) { CamelMimeMessage *message; GList *node; @@ -648,54 +604,142 @@ camel_maildir_folder_expunge (CamelFolder *folder) CAMEL_LOG_FULL_DEBUG ("Leaving CamelMaildirFolder::expunge\n"); } -static void -camel_maildir_folder_class_init ( - CamelMaildirFolderClass *camel_maildir_folder_class) + + + + + + +/* + * fs utility function + * + */ + +static DIR * +_xopendir (const gchar *path) { - CamelFolderClass *camel_folder_class = - CAMEL_FOLDER_CLASS (camel_maildir_folder_class); + DIR *handle; + g_assert (path); - parent_class = gtk_type_class (camel_folder_get_type ()); - - /* virtual method definition */ - /* virtual method overload */ - camel_folder_class-> - init_with_store = camel_maildir_folder_init_with_store; - camel_folder_class->set_name = camel_maildir_folder_set_name; - camel_folder_class->exists = camel_maildir_folder_exists; - camel_folder_class->create = camel_maildir_folder_create; - camel_folder_class->delete = camel_maildir_folder_delete; - camel_folder_class-> - delete_messages = camel_maildir_folder_delete_messages; - camel_folder_class->expunge = camel_maildir_folder_expunge; - camel_folder_class-> - get_message = camel_maildir_folder_get_message; - camel_folder_class-> - get_message_count = camel_maildir_folder_get_message_count; + handle = opendir (path); + if (!handle) { + CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + } + + return handle; } -GtkType -camel_maildir_folder_get_type (void) +static gboolean +_xstat (const gchar *path, struct stat *buf) { - static GtkType camel_maildir_folder_type = 0; - - if (!camel_maildir_folder_type) { - GtkTypeInfo camel_maildir_folder_info = - { - "CamelMaildirFolder", - sizeof (CamelMaildirFolder), - sizeof (CamelMaildirFolderClass), - (GtkClassInitFunc) camel_maildir_folder_class_init, - (GtkObjectInitFunc) NULL, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - camel_maildir_folder_type = - gtk_type_unique (CAMEL_FOLDER_TYPE, - &camel_maildir_folder_info); + gint stat_error; + g_assert (path); + g_assert (buf); + + stat_error = stat (path, buf); + if (stat_error == 0) { + return TRUE; + } else if (errno == ENOENT) { + buf->st_mode = 0; + return TRUE; + } else { + CAMEL_LOG_WARNING ("ERROR: stat (%s, %p);\n", path, buf); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; + } +} + +static gboolean +_xmkdir (const gchar *path) +{ + g_assert (path); + + if (mkdir (path, S_IRWXU) == -1) { + CAMEL_LOG_WARNING ("ERROR: mkdir (%s, S_IRWXU);\n", path); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; + } + + return TRUE; +} + +static gboolean +_xlink (const gchar *from, const gchar *to) +{ + g_assert (from); + g_assert (to); + + if (link (from, to) == 0) { + return TRUE; + } else { + CAMEL_LOG_WARNING ("ERROR: link (%s, %s);\n", from, to); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; + } +} + +static gboolean +_xunlink (const gchar *path) +{ + g_assert (path); + + if (unlink (path) == 0) { + return TRUE; + } else if (errno == ENOENT) { + return TRUE; + } else { + CAMEL_LOG_WARNING ("ERROR: unlink (%s);\n", path); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; } - - return camel_maildir_folder_type; } + +static gboolean +_xrmdir (const gchar *path) +{ + DIR *dir_handle; + struct dirent *dir_entry; + gchar *file; + struct stat statbuf; + g_assert (path); + + dir_handle = opendir (path); + if (!dir_handle && errno == ENOENT) { + return TRUE; + } else if (!dir_handle) { + CAMEL_LOG_WARNING ("ERROR: opendir (%s);\n", path); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; + } + + while ((dir_entry = readdir (dir_handle))) { + file = g_strconcat (path, G_DIR_SEPARATOR_S, dir_entry->d_name, + NULL); + if (_xstat (file, &statbuf) && S_ISREG (statbuf.st_mode)) + _xunlink (file); + g_free (file); + } + + closedir (dir_handle); + + if (rmdir (path) == 0) { + return TRUE; + } else if (errno == ENOENT) { + return TRUE; + } else { + CAMEL_LOG_WARNING ("ERROR: rmdir (%s);\n", path); + CAMEL_LOG_FULL_DEBUG (" Full error text is: (%d) %s\n", + errno, strerror(errno)); + return FALSE; + } +} + +/** *** **/ + -- cgit v1.2.3