diff options
-rw-r--r-- | camel/ChangeLog | 6 | ||||
-rw-r--r-- | camel/Makefile.am | 2 | ||||
-rw-r--r-- | camel/camel-digest-folder.c | 271 | ||||
-rw-r--r-- | camel/camel-digest-summary.c | 90 | ||||
-rw-r--r-- | camel/camel-digest-summary.h | 62 |
5 files changed, 325 insertions, 106 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 1840d4d134..0341cafb34 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,11 @@ 2002-06-20 Jeffrey Stedfast <fejj@ximian.com> + * camel-digest-folder.c: Updated to support searching as well as + making it use CamelDigestSummary. + + * camel-digest-summary.[c,h]: New class to handle the summary for + CamelDigestFolder. + * camel-tcp-stream-ssl.c (set_errno): PR_IO_TIMEOUT_ERROR should map to ETIMEDOUT and not EAGAIN. (stream_connect): Reset the PR_Poll() timeout back to 2 minutes as diff --git a/camel/Makefile.am b/camel/Makefile.am index a58f0e35db..000b66c0b0 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -28,6 +28,7 @@ libcamel_la_SOURCES = \ camel-data-wrapper.c \ camel-digest-folder.c \ camel-digest-store.c \ + camel-digest-summary.c \ camel-disco-diary.c \ camel-disco-folder.c \ camel-disco-store.c \ @@ -126,6 +127,7 @@ libcamelinclude_HEADERS = \ camel-data-wrapper.h \ camel-digest-folder.h \ camel-digest-store.h \ + camel-digest-summary.h \ camel-disco-diary.h \ camel-disco-folder.h \ camel-disco-store.h \ diff --git a/camel/camel-digest-folder.c b/camel/camel-digest-folder.c index 2454b0f637..070e5aed3b 100644 --- a/camel/camel-digest-folder.c +++ b/camel/camel-digest-folder.c @@ -25,11 +25,12 @@ #endif #include "camel-digest-folder.h" +#include "camel-digest-summary.h" #include "camel-exception.h" #include "camel-multipart.h" #include "camel-mime-message.h" -#include "camel-folder-summary.h" +#include "camel-folder-search.h" #define d(x) @@ -37,11 +38,20 @@ struct _CamelDigestFolderPrivate { CamelMimeMessage *message; - GHashTable *info_hash; - GPtrArray *summary; - GPtrArray *uids; + CamelFolderSearch *search; +#ifdef ENABLE_THREADS + GMutex *search_lock; +#endif }; +#ifdef ENABLE_THREADS +#define CAMEL_DIGEST_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelDigestFolder *)f)->priv->l)) +#define CAMEL_DIGEST_FOLDER_UNLOCK(f, l) (g_mutex_unlock(((CamelDigestFolder *)f)->priv->l)) +#else +#define CAMEL_DIGEST_FOLDER_LOCK(f, l) +#define CAMEL_DIGEST_FOLDER_UNLOCK(f, l) +#endif + static CamelFolderClass *parent_class = NULL; static void digest_refresh_info (CamelFolder *folder, CamelException *ex); @@ -49,10 +59,6 @@ static void digest_sync (CamelFolder *folder, gboolean expunge, CamelException * static const char *digest_get_full_name (CamelFolder *folder); static void digest_expunge (CamelFolder *folder, CamelException *ex); -static GPtrArray *digest_get_uids (CamelFolder *folder); -static void digest_free_uids (CamelFolder *folder, GPtrArray *uids); -static CamelMessageInfo *digest_get_message_info (CamelFolder *folder, const char *uid); - /* message manipulation */ static CamelMimeMessage *digest_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex); @@ -62,6 +68,13 @@ static void digest_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, GPtrArray **transferred_uids, gboolean delete_originals, CamelException *ex); +static GPtrArray *digest_search_by_expression (CamelFolder *folder, const char *expression, + CamelException *ex); + +static GPtrArray *digest_search_by_uids (CamelFolder *folder, const char *expression, + GPtrArray *uids, CamelException *ex); + +static void digest_search_free (CamelFolder *folder, GPtrArray *result); static void camel_digest_folder_class_init (CamelDigestFolderClass *camel_digest_folder_class) @@ -78,13 +91,13 @@ camel_digest_folder_class_init (CamelDigestFolderClass *camel_digest_folder_clas camel_folder_class->expunge = digest_expunge; camel_folder_class->get_full_name = digest_get_full_name; - camel_folder_class->get_uids = digest_get_uids; - camel_folder_class->free_uids = digest_free_uids; - camel_folder_class->get_message_info = digest_get_message_info; - camel_folder_class->get_message = digest_get_message; camel_folder_class->append_message = digest_append_message; camel_folder_class->transfer_messages_to = digest_transfer_messages_to; + + camel_folder_class->search_by_expression = digest_search_by_expression; + camel_folder_class->search_by_uids = digest_search_by_uids; + camel_folder_class->search_free = digest_search_free; } static void @@ -93,34 +106,37 @@ camel_digest_folder_init (gpointer object, gpointer klass) CamelDigestFolder *digest_folder = CAMEL_DIGEST_FOLDER (object); CamelFolder *folder = CAMEL_FOLDER (object); - folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY; + folder->folder_flags |= CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | CAMEL_FOLDER_HAS_SEARCH_CAPABILITY; + + folder->summary = camel_digest_summary_new (); - digest_folder->priv = g_new0 (struct _CamelDigestFolderPrivate, 1); - digest_folder->priv->info_hash = g_hash_table_new (g_str_hash, g_str_equal); + digest_folder->priv = g_new (struct _CamelDigestFolderPrivate, 1); + digest_folder->priv->message = NULL; + digest_folder->priv->search = NULL; +#ifdef ENABLE_THREADS + digest_folder->priv->search_lock = g_mutex_new (); +#endif } static void digest_finalize (CamelObject *object) { CamelDigestFolder *digest_folder = CAMEL_DIGEST_FOLDER (object); - GPtrArray *summary; + CamelFolder *folder = CAMEL_FOLDER (object); + + if (folder->summary) { + camel_object_unref (CAMEL_OBJECT (folder->summary)); + folder->summary = NULL; + } camel_object_unref (CAMEL_OBJECT (digest_folder->priv->message)); - g_hash_table_destroy (digest_folder->priv->info_hash); + if (digest_folder->priv->search) + camel_object_unref (CAMEL_OBJECT (digest_folder->priv->search)); - summary = digest_folder->priv->summary; - if (summary) { - int i; - - for (i = 0; i < summary->len; i++) - camel_message_info_free (summary->pdata[i]); - - g_ptr_array_free (summary, TRUE); - } - - if (digest_folder->priv->uids) - g_ptr_array_free (digest_folder->priv->uids, TRUE); +#ifdef ENABLE_THREADS + g_mutex_free (digest_folder->priv->search_lock); +#endif g_free (digest_folder->priv); } @@ -166,6 +182,44 @@ multipart_contains_message_parts (CamelMultipart *multipart) return has_message_parts; } +static void +digest_add_multipart (CamelFolder *folder, CamelMultipart *multipart, const char *preuid) +{ + CamelDataWrapper *wrapper; + CamelMessageInfo *info; + CamelMimePart *part; + int parts, i; + char *uid; + + parts = camel_multipart_get_number (multipart); + for (i = 0; i < parts; i++) { + part = camel_multipart_get_part (multipart, i); + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + + if (CAMEL_IS_MULTIPART (wrapper)) { + uid = g_strdup_printf ("%s%d.", preuid, i); + digest_add_multipart (folder, CAMEL_MULTIPART (wrapper), uid); + g_free (uid); + continue; + } else if (!CAMEL_IS_MIME_MESSAGE (wrapper)) { + continue; + } + + info = camel_folder_summary_info_new_from_message (folder->summary, CAMEL_MIME_MESSAGE (wrapper)); + + uid = g_strdup_printf ("%s%d", preuid, i); + camel_message_info_set_uid (info, uid); + camel_folder_summary_add (folder->summary, info); + } +} + +static void +construct_summary (CamelFolder *folder, CamelMultipart *multipart) +{ + digest_add_multipart (folder, multipart, ""); +} + CamelFolder * camel_digest_folder_new (CamelStore *parent_store, CamelMimeMessage *message) { @@ -191,6 +245,8 @@ camel_digest_folder_new (CamelStore *parent_store, CamelMimeMessage *message) camel_object_ref (CAMEL_OBJECT (message)); digest_folder->priv->message = message; + construct_summary (folder, CAMEL_MULTIPART (wrapper)); + return folder; } @@ -212,83 +268,6 @@ digest_expunge (CamelFolder *folder, CamelException *ex) /* no-op */ } -static void -digest_add_multipart (CamelMultipart *multipart, GPtrArray *summary, - GPtrArray *uids, GHashTable *info_hash, - const char *preuid) -{ - CamelDataWrapper *wrapper; - CamelMessageInfo *info; - CamelMimePart *part; - int parts, i; - char *uid; - - parts = camel_multipart_get_number (multipart); - for (i = 0; i < parts; i++) { - part = camel_multipart_get_part (multipart, i); - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - - if (CAMEL_IS_MULTIPART (wrapper)) { - uid = g_strdup_printf ("%s%d.", preuid, i); - digest_add_multipart (CAMEL_MULTIPART (wrapper), - summary, uids, info_hash, uid); - g_free (uid); - continue; - } else if (!CAMEL_IS_MIME_MESSAGE (wrapper)) { - continue; - } - - info = camel_message_info_new_from_header (CAMEL_MIME_PART (wrapper)->headers); - - uid = g_strdup_printf ("%s%d", preuid, i); - camel_message_info_set_uid (info, g_strdup (uid)); - - g_ptr_array_add (uids, uid); - g_ptr_array_add (summary, info); - g_hash_table_insert (info_hash, uid, info); - } -} - -static GPtrArray * -digest_get_uids (CamelFolder *folder) -{ - CamelDigestFolder *digest_folder = CAMEL_DIGEST_FOLDER (folder); - CamelDataWrapper *wrapper; - GHashTable *info_hash; - GPtrArray *summary; - GPtrArray *uids; - - if (digest_folder->priv->uids) - return digest_folder->priv->uids; - - uids = g_ptr_array_new (); - summary = g_ptr_array_new (); - info_hash = digest_folder->priv->info_hash; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (digest_folder->priv->message)); - digest_add_multipart (CAMEL_MULTIPART (wrapper), summary, uids, info_hash, ""); - - digest_folder->priv->uids = uids; - digest_folder->priv->summary = summary; - - return uids; -} - -static void -digest_free_uids (CamelFolder *folder, GPtrArray *uids) -{ - /* no-op */ -} - -static CamelMessageInfo * -digest_get_message_info (CamelFolder *folder, const char *uid) -{ - CamelDigestFolder *digest = CAMEL_DIGEST_FOLDER (folder); - - return g_hash_table_lookup (digest->priv->info_hash, uid); -} - static const char * digest_get_full_name (CamelFolder *folder) { @@ -346,3 +325,83 @@ digest_get_message (CamelFolder *folder, const char *uid, CamelException *ex) return message; } + + +static GPtrArray * +digest_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) +{ + CamelDigestFolder *df = (CamelDigestFolder *) folder; + CamelFolderSearch *search; + GPtrArray *summary, *matches; + + summary = camel_folder_get_summary (folder); + + CAMEL_DIGEST_FOLDER_LOCK (folder, search_lock); + + if (!df->priv->search) + df->priv->search = camel_folder_search_new (); + + search = df->priv->search; + camel_folder_search_set_folder (search, folder); + camel_folder_search_set_summary (search, summary); + + matches = camel_folder_search_execute_expression (search, expression, ex); + + CAMEL_DIGEST_FOLDER_UNLOCK (folder, search_lock); + + camel_folder_free_summary (folder, summary); + + return matches; +} + +static GPtrArray * +digest_search_by_uids (CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex) +{ + CamelDigestFolder *df = (CamelDigestFolder *) folder; + CamelFolderSearch *search; + GPtrArray *summary, *matches; + int i; + + summary = g_ptr_array_new (); + for (i = 0; i < uids->len; i++) { + CamelMessageInfo *info; + + info = camel_folder_get_message_info (folder, uids->pdata[i]); + if (info) + g_ptr_array_add (summary, info); + } + + if (summary->len == 0) + return summary; + + CAMEL_DIGEST_FOLDER_LOCK (folder, search_lock); + + if (!df->priv->search) + df->priv->search = camel_folder_search_new (); + + search = df->priv->search; + camel_folder_search_set_folder (search, folder); + camel_folder_search_set_summary (search, summary); + + matches = camel_folder_search_execute_expression (search, expression, ex); + + CAMEL_DIGEST_FOLDER_UNLOCK (folder, search_lock); + + for (i = 0; i < summary->len; i++) + camel_folder_free_message_info (folder, summary->pdata[i]); + g_ptr_array_free (summary, TRUE); + + return matches; +} + +static void +digest_search_free (CamelFolder *folder, GPtrArray *result) +{ + CamelDigestFolder *digest_folder = CAMEL_DIGEST_FOLDER (folder); + + CAMEL_DIGEST_FOLDER_LOCK (folder, search_lock); + + camel_folder_search_free_result (digest_folder->priv->search, result); + + CAMEL_DIGEST_FOLDER_UNLOCK (folder, search_lock); +} diff --git a/camel/camel-digest-summary.c b/camel/camel-digest-summary.c new file mode 100644 index 0000000000..f17867e083 --- /dev/null +++ b/camel/camel-digest-summary.c @@ -0,0 +1,90 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast <fejj@ximian.com> + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "camel-digest-summary.h" + +#define CAMEL_DIGEST_SUMMARY_VERSION 0 + +static void camel_digest_summary_class_init (CamelDigestSummaryClass *klass); +static void camel_digest_summary_init (CamelDigestSummary *obj); +static void camel_digest_summary_finalise (CamelObject *obj); + + +static CamelFolderSummaryClass *parent_class = NULL; + + +CamelType +camel_digest_summary_get_type(void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register ( + camel_folder_summary_get_type (), + "CamelDigestSummary", + sizeof (CamelDigestSummary), + sizeof (CamelDigestSummaryClass), + (CamelObjectClassInitFunc) camel_digest_summary_class_init, + NULL, + (CamelObjectInitFunc) camel_digest_summary_init, + (CamelObjectFinalizeFunc) camel_digest_summary_finalise); + } + + return type; +} + +static void +camel_digest_summary_class_init (CamelDigestSummaryClass *klass) +{ + parent_class = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type ())); +} + +static void +camel_digest_summary_init (CamelDigestSummary *summary) +{ + CamelFolderSummary *s = (CamelFolderSummary *) summary; + + /* subclasses need to set the right instance data sizes */ + s->message_info_size = sizeof (CamelMessageInfo); + s->content_info_size = sizeof (CamelMessageContentInfo); + + /* and a unique file version */ + s->version += CAMEL_DIGEST_SUMMARY_VERSION; +} + +static void +camel_digest_summary_finalise (CamelObject *object) +{ + +} + + +CamelFolderSummary * +camel_digest_summary_new (void) +{ + return (CamelFolderSummary *) camel_object_new (camel_digest_summary_get_type ()); +} diff --git a/camel/camel-digest-summary.h b/camel/camel-digest-summary.h new file mode 100644 index 0000000000..16bf5e5c9f --- /dev/null +++ b/camel/camel-digest-summary.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast <fejj@ximian.com> + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef __CAMEL_DIGEST_SUMMARY_H__ +#define __CAMEL_DIGEST_SUMMARY_H__ + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#include <camel/camel-folder-summary.h> +#include <camel/camel-folder.h> +#include <camel/camel-exception.h> + +#define CAMEL_DIGEST_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_digest_summary_get_type (), CamelDigestSummary) +#define CAMEL_DIGEST_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_digest_summary_get_type (), CamelDigestSummaryClass) +#define CAMEL_IS_DIGEST_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_digest_summary_get_type ()) + +typedef struct _CamelDigestSummary CamelDigestSummary; +typedef struct _CamelDigestSummaryClass CamelDigestSummaryClass; + +struct _CamelDigestSummary { + CamelFolderSummary parent_object; + +}; + +struct _CamelDigestSummaryClass { + CamelFolderSummaryClass parent_class; + +}; + + +CamelType camel_digest_summary_get_type (void); + +CamelFolderSummary *camel_digest_summary_new (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CAMEL_DIGEST_SUMMARY_H__ */ |