diff options
Diffstat (limited to 'camel')
62 files changed, 2266 insertions, 1456 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 0ca4b09edc..6fe3ebbbb9 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,7 @@ +2004-11-12 Not Zed <NotZed@Ximian.com> + + ** Merge in notzed-messageinfo-branch, fix some minor conflicts. + 2004-11-11 Jeffrey Stedfast <fejj@novell.com> * providers/imap4/camel-imap4-store.c (imap4_reconnect): Free the @@ -140,6 +144,83 @@ (camel_imap4_store_summary_get_folder_info): Fixed the logic a bit. +2004-11-11 Not Zed <NotZed@Ximian.com> + + * providers/imap4/*: Update for folder-summary api changes. + + * providers/imap4/camel-imap4-store.c (imap4_build_folder_info): + clean up the logic for getting counts from the folder, we have + code to do this already. Also always run it against the selected + folder, does'nt need to have FAST bit unset. + + * camel-folder-summary.c (camel_folder_summary_info_new): removed. + + * camel-string-utils.c (camel_pstring_strdup, camel_pstring_free): + pooled string allocators. Oh so much easier than the poolv thing, + and these refcount too. + + * camel-folder-summary.h: put message_id back into the summary. + +2004-11-08 Not Zed <NotZed@Ximian.com> + + * camel-folder.c (camel_folder_get_deleted_message_count): use + getv method to get the deleted count. + (get_deleted_message_count): removed. + + * camel-vtrash-folder.c (vtrash_getv): override the unread count + to ignore junked or deleted. + + * camel-folder.c (folder_getv): ignore junked and deleted in the + unread count. + + * camel-vee-folder.c (camel_vee_folder_finalise): changed the + logic slightly not to call internal functions directly. + (vee_delete): implement, remove all our folders when we're + deleted, to give unmatched at least a snowflakes chance in hell of + working. + + * camel-vtrash-folder.c (vtrash_search_by_expression) + (vtrash_search_by_uids, vtrash_folder_changed, vtrash_add_folder) + (vtrash_remove_folder, vtrash_rebuild_folder): implement + vtrash-optimised versions. Much faster. + + * camel-vee-folder.c (camel_vee_folder_set_folders): don't rebuild + the folder. + (camel_vee_folder_add_folder): track folders here, but invoke + virtual method to let subclasses know about it. + (camel_vee_folder_remove_folder): similar. + (vee_search_by_uids): free the folder_uids array with TRUE, + plugging memory leak. + +2004-11-06 Not Zed <NotZed@Ximian.com> + + * camel-vee-folder.c: Removed vname, use Folder->full_name + instead. Make add_folder/remove_folder/set_expression/set_folders + virtual methods. + (vee_add_folder): virtual implementation. + + * camel-vee-summary.c (camel_vee_summary_add): remove folder arg. + +2004-11-05 Not Zed <NotZed@Ximian.com> + + * camel-vee-summary.c (vee_info_set_flags): don't emit changed for + ourselves, let it filter through the changed handler, otherwise we + do it twice. + (vee_info_set_user_tag, vee_info_set_user_flag): same. + + * camel-folder-summary.c (message_info_new_from_header): use the + string pool for allocations. + (message_info_load): same here. + (camel_pstring_strdup): noop for NULL or "" + (camel_pstring_free): same. + (summary_assign_uid): don't always assing the flagged bit, der. + +2004-11-02 Not Zed <NotZed@Ximian.com> + + * camel-folder-summary.c (camel_pstring_strdup) + (camel_pstring_free, message_info_free, message_info_clone): + 'uniquify' the strings. + 2004-10-28 Jeffrey Stedfast <fejj@ximian.com> * providers/imap4/camel-imap4-summary.c (envelope_decode_nstring): diff --git a/camel/Makefile.am b/camel/Makefile.am index 51ec97cfcb..f835bbf741 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -119,6 +119,7 @@ libcamel_la_SOURCES = \ camel-utf8.c \ camel-vee-folder.c \ camel-vee-store.c \ + camel-vee-summary.c \ camel-vtrash-folder.c \ camel.c @@ -224,6 +225,7 @@ libcamelinclude_HEADERS = \ camel-utf8.h \ camel-vee-folder.h \ camel-vee-store.h \ + camel-vee-summary.h \ camel-vtrash-folder.h \ camel.h diff --git a/camel/camel-digest-folder.c b/camel/camel-digest-folder.c index 1e814fdf6a..6de306475e 100644 --- a/camel/camel-digest-folder.c +++ b/camel/camel-digest-folder.c @@ -196,9 +196,7 @@ digest_add_multipart (CamelFolder *folder, CamelMultipart *multipart, const char } 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); + info->uid = g_strdup_printf ("%s%d", preuid, i); camel_folder_summary_add (folder->summary, info); } } diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c index 7e4e653492..af670a6b97 100644 --- a/camel/camel-disco-folder.c +++ b/camel/camel-disco-folder.c @@ -345,9 +345,9 @@ disco_expunge (CamelFolder *folder, CamelException *ex) count = camel_folder_summary_count (folder->summary); for (i = 0; i < count; i++) { info = camel_folder_summary_index (folder->summary, i); - if (info->flags & CAMEL_MESSAGE_DELETED) + if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED) g_ptr_array_add (uids, g_strdup (camel_message_info_uid (info))); - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); } disco_expunge_uids (folder, uids, ex); diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index dfb88b84ed..e8b499d56f 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -575,7 +575,7 @@ do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDr if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) camel_folder_set_message_user_tag (p->source, p->uid, "colour", argv[0]->value.string); else - camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string); + camel_message_info_set_user_tag(p->info, "colour", argv[0]->value.string); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set colour to %s", argv[0]->value.string); } @@ -595,7 +595,7 @@ do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) camel_folder_set_message_user_tag (p->source, p->uid, "score", value); else - camel_tag_set (&p->info->user_tags, "score", value); + camel_message_info_set_user_tag(p->info, "score", value); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set score to %d", argv[0]->value.number); g_free (value); } @@ -615,7 +615,7 @@ set_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDri if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) camel_folder_set_message_flags (p->source, p->uid, flags, ~0); else - p->info->flags |= flags | CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Set %s flag", argv[0]->value.string); } @@ -634,7 +634,7 @@ unset_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterD if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) camel_folder_set_message_flags (p->source, p->uid, flags, 0); else - p->info->flags = (p->info->flags & ~flags) | CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_message_info_set_flags(p->info, flags | CAMEL_MESSAGE_FOLDER_FLAGGED, 0); camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Unset %s flag", argv[0]->value.string); } @@ -1150,8 +1150,8 @@ camel_filter_driver_filter_mbox (CamelFilterDriver *driver, const char *mbox, co goto fail; } - info = camel_message_info_new_from_header(((CamelMimePart *)msg)->headers); - info->size = camel_mime_parser_tell(mp) - last; + info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers); + ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - last; last = camel_mime_parser_tell(mp); status = camel_filter_driver_filter_message (driver, msg, info, NULL, NULL, source_url, original_source_url ? original_source_url : source_url, ex); @@ -1365,10 +1365,10 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage } h = CAMEL_MIME_PART (message)->headers; - info = camel_message_info_new_from_header (h); + info = camel_message_info_new_from_header (NULL, h); freeinfo = TRUE; } else { - if (info->flags & CAMEL_MESSAGE_DELETED) + if (camel_message_info_flags(info) & CAMEL_MESSAGE_DELETED) return 0; uid = camel_message_info_uid (info); @@ -1443,7 +1443,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage if (p->source && p->uid && camel_folder_has_summary_capability (p->source)) camel_folder_set_message_flags(p->source, p->uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0); else - info->flags |= CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_message_info_set_flags(info, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FOLDER_FLAGGED, ~0); } /* Logic: if !Moved and there exists a default folder... */ diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c index 2d057efc36..24578e4ec0 100644 --- a/camel/camel-filter-search.c +++ b/camel/camel-filter-search.c @@ -365,7 +365,7 @@ user_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessage /* performs an OR of all words */ for (i = 0; i < argc && !truth; i++) { if (argv[i]->type == ESEXP_RES_STRING - && camel_flag_get (&fms->info->user_flags, argv[i]->value.string)) { + && camel_message_info_user_flag(fms->info, argv[i]->value.string)) { truth = TRUE; break; } @@ -386,7 +386,7 @@ system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessa e_sexp_fatal_error(f, _("Invalid arguments to (system-flag)")); r = e_sexp_result_new (f, ESEXP_RES_BOOL); - r->value.bool = camel_system_flag_get (fms->info->flags, argv[0]->value.string); + r->value.bool = camel_system_flag_get (camel_message_info_flags(fms->info), argv[0]->value.string); return r; } @@ -400,7 +400,7 @@ user_tag (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS if (argc != 1 || argv[0]->type != ESEXP_RES_STRING) e_sexp_fatal_error(f, _("Invalid arguments to (user-tag)")); - tag = camel_tag_get (&fms->info->user_tags, argv[0]->value.string); + tag = camel_message_info_user_tag(fms->info, argv[0]->value.string); r = e_sexp_result_new (f, ESEXP_RES_STRING); r->value.string = g_strdup (tag ? tag : ""); @@ -491,7 +491,7 @@ get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageS ESExpResult *r; r = e_sexp_result_new(f, ESEXP_RES_INT); - r->value.number = fms->info->size / 1024; + r->value.number = camel_message_info_size(fms->info) / 1024; return r; } diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c index b7578ba887..ff5dee6c82 100644 --- a/camel/camel-folder-search.c +++ b/camel/camel-folder-search.c @@ -861,7 +861,7 @@ check_header(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolder header = camel_message_info_subject(search->current); } else if (!strcasecmp(headername, "date")) { /* FIXME: not a very useful form of the date */ - sprintf(strbuf, "%d", (int)search->current->date_sent); + sprintf(strbuf, "%d", (int)camel_message_info_date_sent(search->current)); header = strbuf; } else if (!strcasecmp(headername, "from")) { header = camel_message_info_from(search->current); @@ -1247,7 +1247,7 @@ search_user_flag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo /* performs an OR of all words */ for (i=0;i<argc && !truth;i++) { if (argv[i]->type == ESEXP_RES_STRING - && camel_flag_get(&search->current->user_flags, argv[i]->value.string)) { + && camel_message_info_user_flag(search->current, argv[i]->value.string)) { truth = TRUE; break; } @@ -1273,7 +1273,7 @@ search_system_flag (struct _ESExp *f, int argc, struct _ESExpResult **argv, Came gboolean truth = FALSE; if (argc == 1) - truth = camel_system_flag_get (search->current->flags, argv[0]->value.string); + truth = camel_system_flag_get (camel_message_info_flags(search->current), argv[0]->value.string); r = e_sexp_result_new(f, ESEXP_RES_BOOL); r->value.bool = truth; @@ -1294,7 +1294,7 @@ search_user_tag(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFol r(printf("executing user-tag\n")); if (argc == 1) - value = camel_tag_get (&search->current->user_tags, argv[0]->value.string); + value = camel_message_info_user_tag(search->current, argv[0]->value.string); r = e_sexp_result_new(f, ESEXP_RES_STRING); r->value.string = g_strdup (value ? value : ""); @@ -1313,7 +1313,7 @@ search_get_sent_date(struct _ESExp *f, int argc, struct _ESExpResult **argv, Cam if (s->current) { r = e_sexp_result_new(f, ESEXP_RES_INT); - r->value.number = s->current->date_sent; + r->value.number = camel_message_info_date_sent(s->current); } else { r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR); r->value.ptrarray = g_ptr_array_new (); @@ -1333,7 +1333,7 @@ search_get_received_date(struct _ESExp *f, int argc, struct _ESExpResult **argv, if (s->current) { r = e_sexp_result_new(f, ESEXP_RES_INT); - r->value.number = s->current->date_received; + r->value.number = camel_message_info_date_received(s->current); } else { r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR); r->value.ptrarray = g_ptr_array_new (); @@ -1364,7 +1364,7 @@ search_get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFo /* are we inside a match-all? */ if (s->current) { r = e_sexp_result_new (f, ESEXP_RES_INT); - r->value.number = s->current->size / 1024; + r->value.number = camel_message_info_size(s->current) / 1024; } else { r = e_sexp_result_new (f, ESEXP_RES_ARRAY_PTR); r->value.ptrarray = g_ptr_array_new (); diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index fdffcff8fe..57bf2712dd 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -37,6 +37,9 @@ #include "camel-folder-summary.h" +/* for change events, perhaps we should just do them ourselves */ +#include "camel-folder.h" + #include <camel/camel-file-utils.h> #include <camel/camel-mime-filter.h> #include <camel/camel-mime-filter-index.h> @@ -90,14 +93,14 @@ static int my_list_size(struct _node **list); static int summary_header_load(CamelFolderSummary *, FILE *); static int summary_header_save(CamelFolderSummary *, FILE *); -static CamelMessageInfo * message_info_new(CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *); static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *); static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg); static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *); static int message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *); static void message_info_free(CamelFolderSummary *, CamelMessageInfo *); -static CamelMessageContentInfo * content_info_new(CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageContentInfo * content_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *); static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *); static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummary *s, CamelMimePart *mp); static CamelMessageContentInfo * content_info_load(CamelFolderSummary *, FILE *); @@ -116,31 +119,6 @@ static void camel_folder_summary_finalize (CamelObject *obj); static CamelObjectClass *camel_folder_summary_parent; static void -camel_folder_summary_class_init (CamelFolderSummaryClass *klass) -{ - camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ()); - - klass->summary_header_load = summary_header_load; - klass->summary_header_save = summary_header_save; - - klass->message_info_new = message_info_new; - klass->message_info_new_from_parser = message_info_new_from_parser; - klass->message_info_new_from_message = message_info_new_from_message; - klass->message_info_load = message_info_load; - klass->message_info_save = message_info_save; - klass->message_info_free = message_info_free; - - klass->content_info_new = content_info_new; - klass->content_info_new_from_parser = content_info_new_from_parser; - klass->content_info_new_from_message = content_info_new_from_message; - klass->content_info_load = content_info_load; - klass->content_info_save = content_info_save; - klass->content_info_free = content_info_free; - - klass->next_uid_string = next_uid_string; -} - -static void camel_folder_summary_init (CamelFolderSummary *s) { struct _CamelFolderSummaryPrivate *p; @@ -149,7 +127,7 @@ camel_folder_summary_init (CamelFolderSummary *s) p->filter_charset = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); - s->message_info_size = sizeof(CamelMessageInfo); + s->message_info_size = sizeof(CamelMessageInfoBase); s->content_info_size = sizeof(CamelMessageContentInfo); s->message_info_chunks = NULL; @@ -249,17 +227,21 @@ camel_folder_summary_get_type (void) /** * camel_folder_summary_new: + * @folder: Parent folder. It will hold a ref to us, not the other way around. * * Create a new CamelFolderSummary object. * * Return value: A new CamelFolderSummary widget. **/ CamelFolderSummary * -camel_folder_summary_new (void) +camel_folder_summary_new (struct _CamelFolder *folder) { - CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ())); return new; -} + CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ())); + new->folder = folder; + + return new; +} /** * camel_folder_summary_set_filename: @@ -340,7 +322,6 @@ camel_folder_summary_count(CamelFolderSummary *s) * * Return value: The summary item, or NULL if the index @i is out * of range. - * It must be freed using camel_folder_summary_info_free(). **/ CamelMessageInfo * camel_folder_summary_index(CamelFolderSummary *s, int i) @@ -406,8 +387,9 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array) { int i; + /* FIXME: do the locking around the whole lot to make it faster */ for (i=0;i<array->len;i++) - camel_folder_summary_info_free(s, array->pdata[i]); + camel_message_info_free(array->pdata[i]); g_ptr_array_free(array, TRUE); } @@ -424,7 +406,6 @@ camel_folder_summary_array_free(CamelFolderSummary *s, GPtrArray *array) * * Return value: The summary item, or NULL if the uid @uid * is not available. - * It must be freed using camel_folder_summary_info_free(). **/ CamelMessageInfo * camel_folder_summary_uid(CamelFolderSummary *s, const char *uid) @@ -560,10 +541,11 @@ camel_folder_summary_load(CamelFolderSummary *s) if (mi == NULL) goto error; + /* FIXME: this should be done differently, how i don't know */ if (s->build_content) { - mi->content = perform_content_info_load(s, in); - if (mi->content == NULL) { - camel_folder_summary_info_free(s, mi); + ((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in); + if (((CamelMessageInfoBase *)mi)->content == NULL) { + camel_message_info_free(mi); goto error; } } @@ -631,6 +613,8 @@ camel_folder_summary_save(CamelFolderSummary *s) CamelMessageInfo *mi; char *path; + g_assert(s->message_info_size >= sizeof(CamelMessageInfoBase)); + if (s->summary_path == NULL || (s->flags & CAMEL_SUMMARY_DIRTY) == 0) return 0; @@ -665,7 +649,7 @@ camel_folder_summary_save(CamelFolderSummary *s) goto exception; if (s->build_content) { - if (perform_content_info_save (s, out, mi->content) == -1) + if (perform_content_info_save (s, out, ((CamelMessageInfoBase *)mi)->content) == -1) goto exception; } } @@ -740,8 +724,8 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info) uid = camel_message_info_uid(info); if (uid == NULL || uid[0] == 0) { - camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s)); - uid = camel_message_info_uid(info); + g_free(info->uid); + uid = info->uid = camel_folder_summary_next_uid_string(s); } CAMEL_SUMMARY_LOCK(s, summary_lock); @@ -751,13 +735,14 @@ summary_assign_uid(CamelFolderSummary *s, CamelMessageInfo *info) if (mi == info) return 0; d(printf ("Trying to insert message with clashing uid (%s). new uid re-assigned", camel_message_info_uid(info))); - camel_message_info_set_uid(info, camel_folder_summary_next_uid_string(s)); - uid = camel_message_info_uid(info); - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; + g_free(info->uid); + uid = info->uid = camel_folder_summary_next_uid_string(s); + camel_message_info_set_flags(info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED); CAMEL_SUMMARY_LOCK(s, summary_lock); } CAMEL_SUMMARY_UNLOCK(s, summary_lock); + return 1; } @@ -866,12 +851,11 @@ CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *s, C * * Create a new info record from a header. * - * Return value: Guess? This info record MUST be freed using - * camel_folder_summary_info_free(), camel_message_info_free() will not work. + * Return value: Guess? Free using camel_message_info_free(). **/ CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { - return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new(s, h); + return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s))) -> message_info_new_from_header(s, h); } /** @@ -892,8 +876,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary * * Once complete, the parser will be positioned at the end of * the message. * - * Return value: Guess? This info record MUST be freed using - * camel_folder_summary_info_free(), camel_message_info_free() will not work. + * Return value: Guess? **/ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp) { @@ -928,7 +911,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary * } /* always scan the content info, even if we dont save it */ - info->content = summary_build_content_info(s, info, mp); + ((CamelMessageInfoBase *)info)->content = summary_build_content_info(s, info, mp); if (name) { camel_index_write_name(p->index, name); @@ -938,7 +921,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary * CAMEL_SUMMARY_UNLOCK(s, filter_lock); - info->size = camel_mime_parser_tell(mp) - start; + ((CamelMessageInfoBase *)info)->size = camel_mime_parser_tell(mp) - start; } return info; } @@ -982,7 +965,7 @@ CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary } } - info->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg); + ((CamelMessageInfoBase *)info)->content = summary_build_content_info_message(s, info, (CamelMimePart *)msg); if (name) { camel_index_write_name(p->index, name); @@ -1017,58 +1000,6 @@ camel_folder_summary_content_info_free(CamelFolderSummary *s, CamelMessageConten } /** - * camel_folder_summary_info_free: - * @s: - * @mi: - * - * Unref and potentially free the message info @mi, and all associated memory. - **/ -void camel_folder_summary_info_free(CamelFolderSummary *s, CamelMessageInfo *mi) -{ - CamelMessageContentInfo *ci; - - g_assert(mi); - g_assert(s); - - CAMEL_SUMMARY_LOCK(s, ref_lock); - - g_assert(mi->refcount >= 1); - - mi->refcount--; - if (mi->refcount > 0) { - CAMEL_SUMMARY_UNLOCK(s, ref_lock); - return; - } - - CAMEL_SUMMARY_UNLOCK(s, ref_lock); - - ci = mi->content; - - ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_free(s, mi); - if (s->build_content && ci) { - camel_folder_summary_content_info_free(s, ci); - } -} - -/** - * camel_folder_summary_info_ref: - * @s: - * @mi: - * - * Add an extra reference to @mi. - **/ -void camel_folder_summary_info_ref(CamelFolderSummary *s, CamelMessageInfo *mi) -{ - g_assert(mi); - g_assert(s); - - CAMEL_SUMMARY_LOCK(s, ref_lock); - g_assert(mi->refcount >= 1); - mi->refcount++; - CAMEL_SUMMARY_UNLOCK(s, ref_lock); -} - -/** * camel_folder_summary_touch: * @s: * @@ -1100,7 +1031,7 @@ camel_folder_summary_clear(CamelFolderSummary *s) } for (i=0;i<s->messages->len;i++) - camel_folder_summary_info_free(s, s->messages->pdata[i]); + camel_message_info_free(s->messages->pdata[i]); g_ptr_array_set_size(s->messages, 0); g_hash_table_destroy(s->messages_uid); @@ -1124,7 +1055,7 @@ void camel_folder_summary_remove(CamelFolderSummary *s, CamelMessageInfo *info) s->flags |= CAMEL_SUMMARY_DIRTY; CAMEL_SUMMARY_UNLOCK(s, summary_lock); - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } /** @@ -1147,7 +1078,7 @@ void camel_folder_summary_remove_uid(CamelFolderSummary *s, const char *uid) CAMEL_SUMMARY_UNLOCK(s, ref_lock); CAMEL_SUMMARY_UNLOCK(s, summary_lock); camel_folder_summary_remove(s, oldinfo); - camel_folder_summary_info_free(s, oldinfo); + camel_message_info_free(oldinfo); } else { CAMEL_SUMMARY_UNLOCK(s, ref_lock); CAMEL_SUMMARY_UNLOCK(s, summary_lock); @@ -1172,7 +1103,7 @@ void camel_folder_summary_remove_index(CamelFolderSummary *s, int index) s->flags |= CAMEL_SUMMARY_DIRTY; CAMEL_SUMMARY_UNLOCK(s, summary_lock); - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } else { CAMEL_SUMMARY_UNLOCK(s, summary_lock); } @@ -1213,7 +1144,7 @@ void camel_folder_summary_remove_range(CamelFolderSummary *s, int start, int end CAMEL_SUMMARY_UNLOCK(s, summary_lock); for (i=start;i<end;i++) - camel_folder_summary_info_free(s, infos[i-start]); + camel_message_info_free(infos[i-start]); g_free(infos); } else { CAMEL_SUMMARY_UNLOCK(s, summary_lock); @@ -1459,18 +1390,20 @@ summary_header_save(CamelFolderSummary *s, FILE *out) count = camel_folder_summary_count(s); for (i=0; i<count; i++) { CamelMessageInfo *info = camel_folder_summary_index(s, i); + guint32 flags; if (info == NULL) continue; - if ((info->flags & CAMEL_MESSAGE_SEEN) == 0) + flags = camel_message_info_flags(info); + if ((flags & CAMEL_MESSAGE_SEEN) == 0) unread++; - if ((info->flags & CAMEL_MESSAGE_DELETED) != 0) + if ((flags & CAMEL_MESSAGE_DELETED) != 0) deleted++; - if ((info->flags & CAMEL_MESSAGE_JUNK) != 0) + if ((flags & CAMEL_MESSAGE_JUNK) != 0) junk++; - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } camel_file_util_encode_fixed_int32(out, count); @@ -1491,7 +1424,7 @@ static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *s, Ca case CAMEL_MIME_PARSER_STATE_HEADER: case CAMEL_MIME_PARSER_STATE_MESSAGE: case CAMEL_MIME_PARSER_STATE_MULTIPART: - mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, camel_mime_parser_headers_raw(mp)); + mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, camel_mime_parser_headers_raw(mp)); break; default: g_error("Invalid parser state"); @@ -1508,7 +1441,7 @@ static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary case CAMEL_MIME_PARSER_STATE_HEADER: case CAMEL_MIME_PARSER_STATE_MESSAGE: case CAMEL_MIME_PARSER_STATE_MULTIPART: - ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, camel_mime_parser_headers_raw(mp)); + ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, camel_mime_parser_headers_raw(mp)); if (ci) { ci->type = camel_mime_parser_content_type(mp); camel_content_type_ref(ci->type); @@ -1525,7 +1458,7 @@ static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, C { CamelMessageInfo *mi; - mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new(s, ((CamelMimePart *)msg)->headers); + mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_new_from_header(s, ((CamelMimePart *)msg)->headers); return mi; } @@ -1534,7 +1467,7 @@ static CamelMessageContentInfo * content_info_new_from_message(CamelFolderSummar { CamelMessageContentInfo *ci; - ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new(s, mp->headers); + ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_new_from_header(s, mp->headers); return ci; } @@ -1574,37 +1507,6 @@ summary_format_string (struct _camel_header_raw *h, const char *name, const char } /** - * camel_folder_summary_info_new: - * @s: - * - * Allocate a new camel message info, suitable for adding - * to this summary. - * - * Return value: - **/ -CamelMessageInfo * -camel_folder_summary_info_new(CamelFolderSummary *s) -{ - CamelMessageInfo *mi; - - CAMEL_SUMMARY_LOCK(s, alloc_lock); - if (s->message_info_chunks == NULL) - s->message_info_chunks = e_memchunk_new(32, s->message_info_size); - mi = e_memchunk_alloc(s->message_info_chunks); - CAMEL_SUMMARY_UNLOCK(s, alloc_lock); - - memset(mi, 0, s->message_info_size); -#ifdef DOEPOOLV - mi->strings = e_poolv_new (s->message_info_strings); -#endif -#ifdef DOESTRV - mi->strings = e_strv_new(s->message_info_strings); -#endif - mi->refcount = 1; - return mi; -} - -/** * camel_folder_summary_content_info_new: * @s: * @@ -1629,9 +1531,9 @@ camel_folder_summary_content_info_new(CamelFolderSummary *s) } static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) +message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { - CamelMessageInfo *mi; + CamelMessageInfoBase *mi; const char *received; guchar digest[16]; struct _camel_header_references *refs, *irt, *scan; @@ -1641,12 +1543,12 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) CamelContentType *ct = NULL; const char *content, *charset = NULL; - mi = camel_folder_summary_info_new(s); + mi = (CamelMessageInfoBase *)camel_message_info_new(s); if ((content = camel_header_raw_find(&h, "Content-Type", NULL)) && (ct = camel_content_type_decode(content)) && (charset = camel_content_type_param(ct, "charset")) - && (strcasecmp(charset, "us-ascii") == 0)) + && (g_ascii_strcasecmp(charset, "us-ascii") == 0)) charset = NULL; charset = charset ? e_iconv_charset_name (charset) : NULL; @@ -1660,25 +1562,17 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) if (ct) camel_content_type_unref(ct); -#ifdef DOEPOOLV - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE); -#elif defined (DOESTRV) - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist); -#else - mi->subject = subject; - mi->from = from; - mi->to = to; - mi->cc = cc; - mi->mlist = mlist; -#endif + mi->subject = camel_pstring_strdup(subject); + mi->from = camel_pstring_strdup(from); + mi->to = camel_pstring_strdup(to); + mi->cc = camel_pstring_strdup(cc); + mi->mlist = camel_pstring_strdup(mlist); + + g_free(subject); + g_free(from); + g_free(to); + g_free(cc); + g_free(mlist); mi->user_flags = NULL; mi->user_tags = NULL; @@ -1727,19 +1621,18 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) camel_header_references_list_clear(&refs); } - return mi; + return (CamelMessageInfo *)mi; } - static CamelMessageInfo * message_info_load(CamelFolderSummary *s, FILE *in) { - CamelMessageInfo *mi; + CamelMessageInfoBase *mi; guint count; int i; char *subject, *from, *to, *cc, *mlist, *uid;; - mi = camel_folder_summary_info_new(s); + mi = (CamelMessageInfoBase *)camel_message_info_new(s); io(printf("Loading message info\n")); @@ -1754,28 +1647,18 @@ message_info_load(CamelFolderSummary *s, FILE *in) camel_file_util_decode_string(in, &cc); camel_file_util_decode_string(in, &mlist); -#ifdef DOEPOOLV - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_UID, uid, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_FROM, from, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_TO, to, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_CC, cc, TRUE); - e_poolv_set(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist, TRUE); -#elif defined (DOESTRV) - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_UID, uid); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_SUBJECT, subject); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_FROM, from); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_TO, to); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_CC, cc); - e_strv_set_ref_free(mi->strings, CAMEL_MESSAGE_INFO_MLIST, mlist); -#else mi->uid = uid; - mi->subject = subject; - mi->from = from; - mi->to = to; - mi->cc = cc; - mi->mlist = mlist; -#endif + mi->subject = camel_pstring_strdup(subject); + mi->from = camel_pstring_strdup(from); + mi->to = camel_pstring_strdup(to); + mi->cc = camel_pstring_strdup(cc); + mi->mlist = camel_pstring_strdup(mlist); + + g_free(subject); + g_free(from); + g_free(to); + g_free(cc); + g_free(mlist); mi->content = NULL; @@ -1819,21 +1702,22 @@ message_info_load(CamelFolderSummary *s, FILE *in) } if (!ferror(in)) - return mi; + return (CamelMessageInfo *)mi; error: - camel_folder_summary_info_free(s, mi); + camel_message_info_free((CamelMessageInfo *)mi); return NULL; } static int -message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) +message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *info) { guint32 count; CamelFlag *flag; CamelTag *tag; int i; + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; io(printf("Saving message info\n")); @@ -1882,28 +1766,27 @@ message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi) } static void -message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi) +message_info_free(CamelFolderSummary *s, CamelMessageInfo *info) { -#ifdef DOEPOOLV - e_poolv_destroy(mi->strings); -#elif defined (DOESTRV) - e_strv_destroy(mi->strings); -#else + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; + g_free(mi->uid); - g_free(mi->subject); - g_free(mi->from); - g_free(mi->to); - g_free(mi->cc); - g_free(mi->mlist); -#endif + camel_pstring_free(mi->subject); + camel_pstring_free(mi->from); + camel_pstring_free(mi->to); + camel_pstring_free(mi->cc); + camel_pstring_free(mi->mlist); g_free(mi->references); camel_flag_list_free(&mi->user_flags); camel_tag_list_free(&mi->user_tags); - e_memchunk_free(s->message_info_chunks, mi); + if (s) + e_memchunk_free(s->message_info_chunks, mi); + else + g_free(mi); } static CamelMessageContentInfo * -content_info_new (CamelFolderSummary *s, struct _camel_header_raw *h) +content_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { CamelMessageContentInfo *ci; const char *charset; @@ -2056,7 +1939,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam || camel_content_type_is(ct, "application", "pkcs7-signature") #endif ) - msginfo->flags |= CAMEL_MESSAGE_SECURE; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE); if (p->index && camel_content_type_is(ct, "text", "*")) { char *encoding; @@ -2140,10 +2023,10 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam /* update attachments flag as we go */ ct = camel_mime_parser_content_type(mp); if (camel_content_type_is(ct, "multipart", "mixed")) - msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS); if (camel_content_type_is(ct, "multipart", "signed") || camel_content_type_is(ct, "multipart", "encrypted")) - msginfo->flags |= CAMEL_MESSAGE_SECURE; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE); while (camel_mime_parser_step(mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) { camel_mime_parser_unstep(mp); @@ -2157,7 +2040,7 @@ summary_build_content_info(CamelFolderSummary *s, CamelMessageInfo *msginfo, Cam case CAMEL_MIME_PARSER_STATE_MESSAGE: d(printf("Summarising message\n")); /* update attachments flag as we go */ - msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS); part = summary_build_content_info(s, msginfo, mp); if (part) { @@ -2203,17 +2086,17 @@ summary_build_content_info_message(CamelFolderSummary *s, CamelMessageInfo *msgi ct = ((CamelDataWrapper *)containee)->mime_type; if (camel_content_type_is(ct, "multipart", "*")) { if (camel_content_type_is(ct, "multipart", "mixed")) - msginfo->flags |= CAMEL_MESSAGE_ATTACHMENTS; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS); if (camel_content_type_is(ct, "multipart", "signed") || camel_content_type_is(ct, "multipart", "encrypted")) - msginfo->flags |= CAMEL_MESSAGE_SECURE; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE); } else if (camel_content_type_is(ct, "application", "pgp-signature") #ifdef ENABLE_SMIME || camel_content_type_is(ct, "application", "x-pkcs7-signature") || camel_content_type_is(ct, "application", "pkcs7-signature") #endif ) { - msginfo->flags |= CAMEL_MESSAGE_SECURE; + camel_message_info_set_flags(msginfo, CAMEL_MESSAGE_SECURE, CAMEL_MESSAGE_SECURE); } /* using the object types is more accurate than using the mime/types */ @@ -2607,19 +2490,23 @@ camel_system_flag_get (guint32 flags, const char *name) * * Returns a new CamelMessageInfo structure. **/ -CamelMessageInfo * -camel_message_info_new (void) +void * +camel_message_info_new (CamelFolderSummary *s) { CamelMessageInfo *info; - - info = g_malloc0(sizeof(*info)); -#ifdef DOEPOOLV - info->strings = e_poolv_new(CAMEL_MESSAGE_INFO_LAST); -#endif -#ifdef DOESTRV - info->strings = e_strv_new (CAMEL_MESSAGE_INFO_LAST); -#endif + + if (s) { + CAMEL_SUMMARY_LOCK(s, alloc_lock); + if (s->message_info_chunks == NULL) + s->message_info_chunks = e_memchunk_new(32, s->message_info_size); + info = e_memchunk_alloc0(s->message_info_chunks); + CAMEL_SUMMARY_UNLOCK(s, alloc_lock); + } else { + info = g_malloc0(sizeof(CamelMessageInfoBase)); + } + info->refcount = 1; + info->summary = s; return info; } @@ -2629,14 +2516,22 @@ camel_message_info_new (void) * @info: * * Reference an info. - * - * NOTE: This interface is not MT-SAFE, like the others. **/ -void camel_message_info_ref(CamelMessageInfo *info) +void camel_message_info_ref(void *o) { - GLOBAL_INFO_LOCK(info); - info->refcount++; - GLOBAL_INFO_UNLOCK(info); + CamelMessageInfo *mi = o; + + if (mi->summary) { + CAMEL_SUMMARY_LOCK(mi->summary, ref_lock); + g_assert(mi->refcount >= 1); + mi->refcount++; + CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock); + } else { + GLOBAL_INFO_LOCK(info); + g_assert(mi->refcount >= 1); + mi->refcount++; + GLOBAL_INFO_UNLOCK(info); + } } /** @@ -2646,108 +2541,89 @@ void camel_message_info_ref(CamelMessageInfo *info) * Returns a new CamelMessageInfo structure populated by the header. **/ CamelMessageInfo * -camel_message_info_new_from_header (struct _camel_header_raw *header) +camel_message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *header) { - CamelMessageInfo *info; - char *subject, *from, *to, *cc, *mlist; - CamelContentType *ct = NULL; - const char *content, *date, *charset = NULL; - - if ((content = camel_header_raw_find(&header, "Content-Type", NULL)) - && (ct = camel_content_type_decode(content)) - && (charset = camel_content_type_param(ct, "charset")) - && (strcasecmp(charset, "us-ascii") == 0)) - charset = NULL; - - charset = charset ? e_iconv_charset_name (charset) : NULL; - - subject = summary_format_string(header, "subject", charset); - from = summary_format_address(header, "from", charset); - to = summary_format_address(header, "to", charset); - cc = summary_format_address(header, "cc", charset); - date = camel_header_raw_find(&header, "date", NULL); - mlist = camel_header_raw_check_mailing_list(&header); - - if (ct) - camel_content_type_unref(ct); - - info = camel_message_info_new(); - - camel_message_info_set_subject(info, subject); - camel_message_info_set_from(info, from); - camel_message_info_set_to(info, to); - camel_message_info_set_cc(info, cc); - camel_message_info_set_mlist(info, mlist); - - if (date) - info->date_sent = camel_header_decode_date (date, NULL); - else - info->date_sent = time (NULL); - - date = camel_header_raw_find (&header, "received", NULL); - if (date && (date = strrchr (date, ';'))) - date++; - - if (date) - info->date_received = camel_header_decode_date (date, NULL); + if (s) + return ((CamelFolderSummaryClass *)((CamelObject *)s)->klass)->message_info_new_from_header(s, header); else - info->date_received = time (NULL); - - return info; + return message_info_new_from_header(NULL, header); } /** - * camel_message_info_dup_to: - * @from: source message info - * @to: destination message info + * camel_message_info_free: + * @mi: the message info + * + * Unref's and potentially frees a CamelMessageInfo and its contents. * - * Duplicates the contents of one CamelMessageInfo structure into another. - * (The destination is assumed to be empty: its contents are not freed.) - * The slightly odd interface is to allow this to be used to initialize - * "subclasses" of CamelMessageInfo. **/ void -camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to) +camel_message_info_free(void *o) +{ + CamelMessageInfo *mi = o; + + g_return_if_fail(mi != NULL); + + if (mi->summary) { + CAMEL_SUMMARY_LOCK(mi->summary, ref_lock); + + g_assert(mi->refcount >= 1); + mi->refcount--; + if (mi->refcount > 0) { + CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock); + return; + } + + CAMEL_SUMMARY_UNLOCK(mi->summary, ref_lock); + + /* FIXME: this is kinda busted, should really be handled by message info free */ + if (mi->summary->build_content + && ((CamelMessageInfoBase *)mi)->content) { + camel_folder_summary_content_info_free(mi->summary, ((CamelMessageInfoBase *)mi)->content); + } + + ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(mi->summary)))->message_info_free(mi->summary, mi); + } else { + GLOBAL_INFO_LOCK(info); + mi->refcount--; + if (mi->refcount > 0) { + GLOBAL_INFO_UNLOCK(info); + return; + } + GLOBAL_INFO_UNLOCK(info); + + message_info_free(NULL, mi); + } +} + +static CamelMessageInfo * +message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi) { + CamelMessageInfoBase *to, *from = (CamelMessageInfoBase *)mi; CamelFlag *flag; CamelTag *tag; - /* Copy numbers */ + to = (CamelMessageInfoBase *)camel_message_info_new(s); + to->flags = from->flags; to->size = from->size; to->date_sent = from->date_sent; to->date_received = from->date_received; to->refcount = 1; - /* Copy strings */ -#ifdef DOEPOOLV - to->strings = e_poolv_cpy (to->strings, from->strings); -#elif defined (DOESTRV) - /* to->strings = e_strv_new(CAMEL_MESSAGE_INFO_LAST); */ - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_SUBJECT, camel_message_info_subject(from)); - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_FROM, camel_message_info_from(from)); - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_TO, camel_message_info_to(from)); - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_CC, camel_message_info_cc(from)); - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_uid(from)); - e_strv_set(to->strings, CAMEL_MESSAGE_INFO_UID, camel_message_info_mlist(from)); -#else - to->subject = g_strdup(from->subject); - to->from = g_strdup(from->from); - to->to = g_strdup(from->to); - to->cc = g_strdup(from->cc); - to->uid = g_strdup(from->uid); - to->mlist = g_strdup(from->mlist); -#endif - memcpy(&to->message_id, &from->message_id, sizeof(from->message_id)); + /* NB: We don't clone the uid */ + + to->subject = camel_pstring_strdup(from->subject); + to->from = camel_pstring_strdup(from->from); + to->to = camel_pstring_strdup(from->to); + to->cc = camel_pstring_strdup(from->cc); + to->mlist = camel_pstring_strdup(from->mlist); + memcpy(&to->message_id, &from->message_id, sizeof(to->message_id)); - /* Copy structures */ if (from->references) { int len = sizeof(*from->references) + ((from->references->size-1) * sizeof(from->references->references[0])); to->references = g_malloc(len); memcpy(to->references, from->references, len); - } else { - to->references = NULL; } flag = from->user_flags; @@ -2762,83 +2638,226 @@ camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to) tag = tag->next; } - /* No, this is impossible without knowing the class of summary we came from */ - /* FIXME some day */ - to->content = NULL; + if (from->content) { + /* FIXME: copy content-infos */ + } + + return (CamelMessageInfo *)to; } -/** - * camel_message_info_free: - * @mi: the message info - * - * Unref's and potentially frees a CamelMessageInfo and its contents. - * - * Can only be used to free CamelMessageInfo's created with - * camel_message_info_dup_to. - * - * NOTE: This interface is not MT-SAFE, like the others. - * - **/ -void -camel_message_info_free(CamelMessageInfo *mi) +void * +camel_message_info_clone(const void *o) { - g_return_if_fail(mi != NULL); + const CamelMessageInfo *mi = o; - GLOBAL_INFO_LOCK(info); - mi->refcount--; - if (mi->refcount > 0) { - GLOBAL_INFO_UNLOCK(info); - return; + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->message_info_clone(mi->summary, mi); + else + return message_info_clone(NULL, mi); +} + +static const void * +info_ptr(const CamelMessageInfo *mi, int id) +{ + switch (id) { + case CAMEL_MESSAGE_INFO_SUBJECT: + return ((const CamelMessageInfoBase *)mi)->subject; + case CAMEL_MESSAGE_INFO_FROM: + return ((const CamelMessageInfoBase *)mi)->from; + case CAMEL_MESSAGE_INFO_TO: + return ((const CamelMessageInfoBase *)mi)->to; + case CAMEL_MESSAGE_INFO_CC: + return ((const CamelMessageInfoBase *)mi)->cc; + case CAMEL_MESSAGE_INFO_MLIST: + return ((const CamelMessageInfoBase *)mi)->mlist; + case CAMEL_MESSAGE_INFO_MESSAGE_ID: + return &((const CamelMessageInfoBase *)mi)->message_id; + case CAMEL_MESSAGE_INFO_REFERENCES: + return ((const CamelMessageInfoBase *)mi)->references; + case CAMEL_MESSAGE_INFO_USER_FLAGS: + return ((const CamelMessageInfoBase *)mi)->user_flags; + case CAMEL_MESSAGE_INFO_USER_TAGS: + return ((const CamelMessageInfoBase *)mi)->user_tags; + default: + abort(); } - GLOBAL_INFO_UNLOCK(info); +} -#ifdef DOEPOOLV - e_poolv_destroy(mi->strings); -#elif defined (DOESTRV) - e_strv_destroy(mi->strings); -#else - g_free(mi->uid); - g_free(mi->subject); - g_free(mi->from); - g_free(mi->to); - g_free(mi->cc); - g_free(mi->mlist); -#endif - g_free(mi->references); - camel_flag_list_free(&mi->user_flags); - camel_tag_list_free(&mi->user_tags); - /* FIXME: content info? */ - g_free(mi); +static guint32 +info_uint32(const CamelMessageInfo *mi, int id) +{ + switch (id) { + case CAMEL_MESSAGE_INFO_FLAGS: + return ((const CamelMessageInfoBase *)mi)->flags; + case CAMEL_MESSAGE_INFO_SIZE: + return ((const CamelMessageInfoBase *)mi)->size; + default: + abort(); + } } -#if defined (DOEPOOLV) || defined (DOESTRV) -const char * -camel_message_info_string (const CamelMessageInfo *mi, int type) +static time_t +info_time(const CamelMessageInfo *mi, int id) { - g_assert (mi != NULL); - - if (mi->strings == NULL) - return ""; -#ifdef DOEPOOLV - return e_poolv_get (mi->strings, type); -#else - return e_strv_get (mi->strings, type); -#endif + switch (id) { + case CAMEL_MESSAGE_INFO_DATE_SENT: + return ((const CamelMessageInfoBase *)mi)->date_sent; + case CAMEL_MESSAGE_INFO_DATE_RECEIVED: + return ((const CamelMessageInfoBase *)mi)->date_received; + default: + abort(); + } } -void -camel_message_info_set_string (CamelMessageInfo *mi, int type, char *str) +static gboolean +info_user_flag(const CamelMessageInfo *mi, const char *id) { - g_assert (mi != NULL); - g_assert (mi->strings != NULL); -#ifdef DOEPOOLV - e_poolv_set (mi->strings, type, str, TRUE); -#else - mi->strings = e_strv_set_ref_free (mi->strings, type, str); -#endif + return camel_flag_get(&((CamelMessageInfoBase *)mi)->user_flags, id); } -#endif +static const char * +info_user_tag(const CamelMessageInfo *mi, const char *id) +{ + return camel_tag_get(&((CamelMessageInfoBase *)mi)->user_tags, id); +} + +const void * +camel_message_info_ptr(const CamelMessageInfo *mi, int id) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_ptr(mi, id); + else + return info_ptr(mi, id); +} + +guint32 camel_message_info_uint32(const CamelMessageInfo *mi, int id) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_uint32(mi, id); + else + return info_uint32(mi, id); +} + +time_t camel_message_info_time(const CamelMessageInfo *mi, int id) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_time(mi, id); + else + return info_time(mi, id); +} + +gboolean camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_flag(mi, id); + else + return info_user_flag(mi, id); +} + +const char *camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_user_tag(mi, id); + else + return info_user_tag(mi, id); +} + +static gboolean +info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set) +{ + guint32 old; + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; + + /* TODO: locking? */ + + old = mi->flags; + mi->flags = (old & ~flags) | (set & flags); + if (old != mi->flags) { + mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; + if (mi->summary) + camel_folder_summary_touch(mi->summary); + } + + if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) + return FALSE; + + if (mi->summary && mi->summary->folder && mi->uid) { + CamelFolderChangeInfo *changes = camel_folder_change_info_new(); + + camel_folder_change_info_change_uid(changes, camel_message_info_uid(info)); + camel_object_trigger_event(mi->summary->folder, "folder_changed", changes); + camel_folder_change_info_free(changes); + } + + return TRUE; +} + +gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_flags(mi, flags, set); + else + return info_set_flags(mi, flags, set); +} + +static gboolean +info_set_user_flag(CamelMessageInfo *info, const char *name, gboolean value) +{ + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; + int res; + + res = camel_flag_set(&mi->user_flags, name, value); + + /* TODO: check this item is still in the summary first */ + if (mi->summary && res && mi->summary->folder && mi->uid) { + CamelFolderChangeInfo *changes = camel_folder_change_info_new(); + + mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_folder_summary_touch(mi->summary); + camel_folder_change_info_change_uid(changes, camel_message_info_uid(info)); + camel_object_trigger_event(mi->summary->folder, "folder_changed", changes); + camel_folder_change_info_free(changes); + } + + return res; +} + +gboolean camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_flag(mi, id, state); + else + return info_set_user_flag(mi, id, state); +} + +static gboolean +info_set_user_tag(CamelMessageInfo *info, const char *name, const char *value) +{ + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info; + int res; + + res = camel_tag_set(&mi->user_tags, name, value); + + if (mi->summary && res && mi->summary->folder && mi->uid) { + CamelFolderChangeInfo *changes = camel_folder_change_info_new(); + + mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_folder_summary_touch(mi->summary); + camel_folder_change_info_change_uid(changes, camel_message_info_uid(info)); + camel_object_trigger_event(mi->summary->folder, "folder_changed", changes); + camel_folder_change_info_free(changes); + } + + return res; +} + +gboolean camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val) +{ + if (mi->summary) + return ((CamelFolderSummaryClass *)((CamelObject *)mi->summary)->klass)->info_set_user_tag(mi, id, val); + else + return info_set_user_tag(mi, id, val); +} void camel_content_info_dump (CamelMessageContentInfo *ci, int depth) @@ -2883,6 +2902,50 @@ camel_message_info_dump (CamelMessageInfo *mi) printf("mailing list: %s\n", camel_message_info_mlist(mi)); printf("From: %s\n", camel_message_info_from(mi)); printf("UID: %s\n", camel_message_info_uid(mi)); - printf("Flags: %04x\n", mi->flags & 0xffff); - camel_content_info_dump(mi->content, 0); + printf("Flags: %04x\n", camel_message_info_flags(mi)); + /*camel_content_info_dump(mi->content, 0);*/ +} + + +static void +camel_folder_summary_class_init (CamelFolderSummaryClass *klass) +{ + camel_folder_summary_parent = camel_type_get_global_classfuncs (camel_object_get_type ()); + + klass->summary_header_load = summary_header_load; + klass->summary_header_save = summary_header_save; + + klass->message_info_new_from_header = message_info_new_from_header; + klass->message_info_new_from_parser = message_info_new_from_parser; + klass->message_info_new_from_message = message_info_new_from_message; + klass->message_info_load = message_info_load; + klass->message_info_save = message_info_save; + klass->message_info_free = message_info_free; + klass->message_info_clone = message_info_clone; + + klass->content_info_new_from_header = content_info_new_from_header; + klass->content_info_new_from_parser = content_info_new_from_parser; + klass->content_info_new_from_message = content_info_new_from_message; + klass->content_info_load = content_info_load; + klass->content_info_save = content_info_save; + klass->content_info_free = content_info_free; + + klass->next_uid_string = next_uid_string; + + klass->info_ptr = info_ptr; + klass->info_uint32 = info_uint32; + klass->info_time = info_time; + klass->info_user_flag = info_user_flag; + klass->info_user_tag = info_user_tag; + +#if 0 + klass->info_set_string = info_set_string; + klass->info_set_uint32 = info_set_uint32; + klass->info_set_time = info_set_time; + klass->info_set_ptr = info_set_ptr; +#endif + klass->info_set_user_flag = info_set_user_flag; + klass->info_set_user_tag = info_set_user_tag; + + klass->info_set_flags = info_set_flags; } diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index de56a6e8e0..5f0b0d15ec 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -33,6 +33,8 @@ extern "C" { #include <camel/camel-object.h> #include <camel/camel-index.h> +struct _CamelFolder; + #define CAMEL_FOLDER_SUMMARY_TYPE camel_folder_summary_get_type () #define CAMEL_FOLDER_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary) #define CAMEL_FOLDER_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass) @@ -41,6 +43,9 @@ extern "C" { /*typedef struct _CamelFolderSummary CamelFolderSummary;*/ typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass; +typedef struct _CamelMessageInfo CamelMessageInfo; +typedef struct _CamelMessageInfoBase CamelMessageInfoBase; + /* A tree of message content info structures describe the content structure of the message (if it has any) */ struct _CamelMessageContentInfo { @@ -113,47 +118,58 @@ typedef struct _CamelSummaryReferences { CamelSummaryMessageID references[1]; } CamelSummaryReferences; -/* #define DOESTRV */ -#define DOEPOOLV - -#if defined (DOEPOOLV) || defined (DOESTRV) - -/* string array indices */ +/* accessor id's */ enum { - CAMEL_MESSAGE_INFO_UID, CAMEL_MESSAGE_INFO_SUBJECT, CAMEL_MESSAGE_INFO_FROM, CAMEL_MESSAGE_INFO_TO, CAMEL_MESSAGE_INFO_CC, CAMEL_MESSAGE_INFO_MLIST, - CAMEL_MESSAGE_INFO_LAST, + + CAMEL_MESSAGE_INFO_FLAGS, + CAMEL_MESSAGE_INFO_SIZE, + + CAMEL_MESSAGE_INFO_DATE_SENT, + CAMEL_MESSAGE_INFO_DATE_RECEIVED, + + CAMEL_MESSAGE_INFO_MESSAGE_ID, + CAMEL_MESSAGE_INFO_REFERENCES, + CAMEL_MESSAGE_INFO_USER_FLAGS, + CAMEL_MESSAGE_INFO_USER_TAGS, + + CAMEL_MESSAGE_INFO_LAST }; -#endif -/* information about a given object */ +/* information about a given message, use accessors */ struct _CamelMessageInfo { - /* public fields */ -#ifdef DOEPOOLV - struct _EPoolv *strings; -#elif defined (DOESTRV) - struct _EStrv *strings; /* all strings packed into a single compact array */ -#else - char *subject; - char *from; - char *to; - char *cc; - char *mlist; + CamelFolderSummary *summary; + + guint32 refcount; /* ??? */ + char *uid; +}; +/* For classes wishing to do the provided i/o, or for anonymous users, + * they must subclass or use this messageinfo structure */ +/* Otherwise they can do their own thing entirely */ +struct _CamelMessageInfoBase { + CamelFolderSummary *summary; + + guint32 refcount; /* ??? */ char *uid; -#endif /* DOEPOOLV */ + + const char *subject; + const char *from; + const char *to; + const char *cc; + const char *mlist; + guint32 flags; guint32 size; - guint32 refcount; time_t date_sent; time_t date_received; - CamelSummaryMessageID message_id;/* for this message */ + CamelSummaryMessageID message_id; CamelSummaryReferences *references;/* from parent to root */ struct _CamelFlag *user_flags; @@ -163,6 +179,16 @@ struct _CamelMessageInfo { CamelMessageContentInfo *content; }; +/* probably do this as well, removing CamelFolderChangeInfo and interfaces +typedef struct _CamelChangeInfo CamelChangeInfo; +struct _CamelChangeInfo { + GPtrArray *added; + GPtrArray *removed; + GPtrArray *changed; + GPtrArray *recent; +}; +*/ + enum _CamelFolderSummaryFlags { CAMEL_SUMMARY_DIRTY = 1<<0, }; @@ -186,9 +212,6 @@ struct _CamelFolderSummary { guint32 message_info_size; guint32 content_info_size; -#if defined (DOEPOOLV) || defined (DOESTRV) - guint32 message_info_strings; -#endif /* memory allocators (setup automatically) */ struct _EMemChunk *message_info_chunks; struct _EMemChunk *content_info_chunks; @@ -198,6 +221,8 @@ struct _CamelFolderSummary { GPtrArray *messages; /* CamelMessageInfo's */ GHashTable *messages_uid; /* CamelMessageInfo's by uid */ + + struct _CamelFolder *folder; /* parent folder, for events */ }; struct _CamelFolderSummaryClass { @@ -208,15 +233,17 @@ struct _CamelFolderSummaryClass { int (*summary_header_save)(CamelFolderSummary *, FILE *); /* create/save/load an individual message info */ - CamelMessageInfo * (*message_info_new)(CamelFolderSummary *, struct _camel_header_raw *); + CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *); CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *); CamelMessageInfo * (*message_info_new_from_message)(CamelFolderSummary *, CamelMimeMessage *); CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *); int (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *); + void (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *); + CamelMessageInfo * (*message_info_clone)(CamelFolderSummary *, const CamelMessageInfo *); /* save/load individual content info's */ - CamelMessageContentInfo * (*content_info_new)(CamelFolderSummary *, struct _camel_header_raw *); + CamelMessageContentInfo * (*content_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *); CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *); CamelMessageContentInfo * (*content_info_new_from_message)(CamelFolderSummary *, CamelMimePart *); CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *); @@ -225,10 +252,29 @@ struct _CamelFolderSummaryClass { /* get the next uid */ char *(*next_uid_string)(CamelFolderSummary *); + + /* virtual accessors on messageinfo's */ + const void *(*info_ptr)(const CamelMessageInfo *mi, int id); + guint32 (*info_uint32)(const CamelMessageInfo *mi, int id); + time_t (*info_time)(const CamelMessageInfo *mi, int id); + + gboolean (*info_user_flag)(const CamelMessageInfo *mi, const char *id); + const char *(*info_user_tag)(const CamelMessageInfo *mi, const char *id); + + /* set accessors for the modifyable bits */ +#if 0 + void (*info_set_ptr)(CamelMessageInfo *mi, int id, const void *val); + void (*info_set_uint32)(CamelMessageInfo *mi, int id, guint32 val); + void (*info_set_time)(CamelMessageInfo *mi, int id, time_t val); + void (*info_set_references)(CamelMessageInfo *mi, CamelSummaryReferences *); +#endif + gboolean (*info_set_user_flag)(CamelMessageInfo *mi, const char *id, gboolean state); + gboolean (*info_set_user_tag)(CamelMessageInfo *mi, const char *id, const char *val); + gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set); }; CamelType camel_folder_summary_get_type (void); -CamelFolderSummary *camel_folder_summary_new (void); +CamelFolderSummary *camel_folder_summary_new (struct _CamelFolder *folder); void camel_folder_summary_set_filename(CamelFolderSummary *, const char *); void camel_folder_summary_set_index(CamelFolderSummary *, CamelIndex *); @@ -257,14 +303,10 @@ CamelMessageInfo *camel_folder_summary_add_from_parser(CamelFolderSummary *, Cam CamelMessageInfo *camel_folder_summary_add_from_message(CamelFolderSummary *, CamelMimeMessage *); /* Just build raw summary items */ -CamelMessageInfo *camel_folder_summary_info_new(CamelFolderSummary *s); CamelMessageInfo *camel_folder_summary_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *); CamelMessageInfo *camel_folder_summary_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *); CamelMessageInfo *camel_folder_summary_info_new_from_message(CamelFolderSummary *, CamelMimeMessage *); -void camel_folder_summary_info_ref(CamelFolderSummary *, CamelMessageInfo *); -void camel_folder_summary_info_free(CamelFolderSummary *, CamelMessageInfo *); - CamelMessageContentInfo *camel_folder_summary_content_info_new(CamelFolderSummary *s); void camel_folder_summary_content_info_free(CamelFolderSummary *s, CamelMessageContentInfo *ci); @@ -309,53 +351,46 @@ gboolean camel_tag_list_copy(CamelTag **to, CamelTag **from); int camel_tag_list_size(CamelTag **list); void camel_tag_list_free(CamelTag **list); -/* message info utils for working with pseudo-messageinfo structures - NOTE: These cannot be added to a real summary object, but suffice for all - other external interfaces that use message info's */ -CamelMessageInfo *camel_message_info_new(void); -void camel_message_info_ref(CamelMessageInfo *info); -CamelMessageInfo *camel_message_info_new_from_header(struct _camel_header_raw *header); -void camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to); -void camel_message_info_free(CamelMessageInfo *mi); +/* Summary may be null */ +/* Use anonymous pointers to avoid tons of cast crap */ +void *camel_message_info_new(CamelFolderSummary *); +void camel_message_info_ref(void *); +CamelMessageInfo *camel_message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *header); +void camel_message_info_free(void *); +void *camel_message_info_clone(const void *); /* accessors */ -#if defined (DOEPOOLV) || defined (DOESTRV) -const char *camel_message_info_string(const CamelMessageInfo *mi, int type); -#define camel_message_info_subject(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_SUBJECT) -#define camel_message_info_from(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_FROM) -#define camel_message_info_to(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_TO) -#define camel_message_info_cc(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_CC) -#define camel_message_info_uid(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_UID) -#define camel_message_info_mlist(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MESSAGE_INFO_MLIST) - -void camel_message_info_set_string(CamelMessageInfo *mi, int type, char *str); -#define camel_message_info_set_subject(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_SUBJECT, s) -#define camel_message_info_set_from(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_FROM, s) -#define camel_message_info_set_to(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_TO, s) -#define camel_message_info_set_cc(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_CC, s) -#define camel_message_info_set_uid(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_UID, s) -#define camel_message_info_set_mlist(x, s) camel_message_info_set_string(x, CAMEL_MESSAGE_INFO_MLIST, s) - -#else - -#define camel_message_info_subject(x) (((CamelMessageInfo *)(x))->subject?((CamelMessageInfo *)(x))->subject:"") -#define camel_message_info_from(x) (((CamelMessageInfo *)(x))->from?((CamelMessageInfo *)(x))->from:"") -#define camel_message_info_to(x) (((CamelMessageInfo *)(x))->to?((CamelMessageInfo *)(x))->to:"") -#define camel_message_info_cc(x) (((CamelMessageInfo *)(x))->cc?((CamelMessageInfo *)(x))->cc:"") -#define camel_message_info_uid(x) (((CamelMessageInfo *)(x))->uid?((CamelMessageInfo *)(x))->uid:"") -#define camel_message_info_mlist(x) (((CamelMessageInfo *)(x))->mlist?((CamelMessageInfo *)(x))->mlist:"") - -#define camel_message_info_set_subject(x, s) (g_free(((CamelMessageInfo *)(x))->subject),((CamelMessageInfo *)(x))->subject = (s)) -#define camel_message_info_set_from(x, s) (g_free(((CamelMessageInfo *)(x))->from),((CamelMessageInfo *)(x))->from = (s)) -#define camel_message_info_set_to(x, s) (g_free(((CamelMessageInfo *)(x))->to),((CamelMessageInfo *)(x))->to = (s)) -#define camel_message_info_set_cc(x, s) (g_free(((CamelMessageInfo *)(x))->cc),((CamelMessageInfo *)(x))->cc = (s)) -#define camel_message_info_set_uid(x, s) (g_free(((CamelMessageInfo *)(x))->uid),((CamelMessageInfo *)(x))->uid = (s)) -#define camel_message_info_set_mlist(x, s) (g_free(((CamelMessageInfo *)(x))->mlist),((CamelMessageInfo *)(x))->mlist = (s)) -#endif +const void *camel_message_info_ptr(const CamelMessageInfo *mi, int id); +guint32 camel_message_info_uint32(const CamelMessageInfo *mi, int id); +time_t camel_message_info_time(const CamelMessageInfo *mi, int id); +#define camel_message_info_uid(mi) ((const char *)((const CamelMessageInfo *)mi)->uid) -/* debugging functions */ +#define camel_message_info_subject(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SUBJECT)) +#define camel_message_info_from(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FROM)) +#define camel_message_info_to(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_TO)) +#define camel_message_info_cc(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CC)) +#define camel_message_info_mlist(mi) ((const char *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MLIST)) + +#define camel_message_info_flags(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_FLAGS) +#define camel_message_info_size(mi) camel_message_info_uint32((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_SIZE) + +#define camel_message_info_date_sent(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_SENT) +#define camel_message_info_date_received(mi) camel_message_info_time((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_DATE_RECEIVED) +#define camel_message_info_message_id(mi) ((const CamelSummaryMessageID *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_MESSAGE_ID)) +#define camel_message_info_references(mi) ((const CamelSummaryReferences *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_REFERENCES)) +#define camel_message_info_user_flags(mi) ((const CamelFlag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_FLAGS)) +#define camel_message_info_user_tags(mi) ((const CamelTag *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_USER_TAGS)) + +gboolean camel_message_info_user_flag(const CamelMessageInfo *mi, const char *id); +const char *camel_message_info_user_tag(const CamelMessageInfo *mi, const char *id); + +gboolean camel_message_info_set_flags(CamelMessageInfo *mi, guint32 mask, guint32 set); +gboolean camel_message_info_set_user_flag(CamelMessageInfo *mi, const char *id, gboolean state); +gboolean camel_message_info_set_user_tag(CamelMessageInfo *mi, const char *id, const char *val); + +/* debugging functions */ void camel_content_info_dump (CamelMessageContentInfo *ci, int depth); void camel_message_info_dump (CamelMessageInfo *mi); diff --git a/camel/camel-folder-thread.c b/camel/camel-folder-thread.c index a110cdb28e..234b3f1f62 100644 --- a/camel/camel-folder-thread.c +++ b/camel/camel-folder-thread.c @@ -333,7 +333,7 @@ dump_tree_rec(struct _tree_info *info, CamelFolderThreadNode *c, int depth) g_hash_table_insert(info->visited, c, c); } if (c->message) { - printf("%s %p Subject: %s <%.8s>\n", p, c, camel_message_info_subject(c->message), c->message->message_id.id.hash); + printf("%s %p Subject: %s <%.8s>\n", p, c, camel_message_info_subject(c->message), camel_message_info_message_id(c->message)->id.hash); count += 1; } else { printf("%s %p <empty>\n", p, c); @@ -446,9 +446,11 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary) no_id_table = g_hash_table_new(NULL, NULL); for (i=0;i<summary->len;i++) { CamelMessageInfo *mi = summary->pdata[i]; + const CamelSummaryMessageID *mid = camel_message_info_message_id(mi); + const CamelSummaryReferences *references = camel_message_info_references(mi); - if (mi->message_id.id.id) { - c = g_hash_table_lookup(id_table, &mi->message_id); + if (mid->id.id) { + c = g_hash_table_lookup(id_table, mid); /* check for duplicate messages */ if (c && c->order) { /* if duplicate, just make out it is a no-id message, but try and insert it @@ -457,9 +459,9 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary) c = e_memchunk_alloc0(thread->node_chunks); g_hash_table_insert(no_id_table, (void *)mi, c); } else if (!c) { - d(printf("doing : %08x%08x (%s)\n", mi->message_id.id.part.hi, mi->message_id.id.part.lo, camel_message_info_subject(mi))); + d(printf("doing : %08x%08x (%s)\n", mid->id.part.hi, mid->id.part.lo, camel_message_info_subject(mi))); c = e_memchunk_alloc0(thread->node_chunks); - g_hash_table_insert(id_table, (void *)&mi->message_id, c); + g_hash_table_insert(id_table, (void *)mid, c); } } else { d(printf("doing : (no message id)\n")); @@ -470,20 +472,20 @@ thread_summary(CamelFolderThread *thread, GPtrArray *summary) c->message = mi; c->order = i+1; child = c; - if (mi->references) { + if (references) { int j; d(printf("references:\n")); - for (j=0;j<mi->references->size;j++) { + for (j=0;j<references->size;j++) { /* should never be empty, but just incase */ - if (mi->references->references[j].id.id == 0) + if (references->references[j].id.id == 0) continue; - c = g_hash_table_lookup(id_table, &mi->references->references[j]); + c = g_hash_table_lookup(id_table, &references->references[j]); if (c == NULL) { d(printf("not found\n")); c = e_memchunk_alloc0(thread->node_chunks); - g_hash_table_insert(id_table, &mi->references->references[j], c); + g_hash_table_insert(id_table, (void *)&references->references[j], c); } if (c!=child) container_parent_child(c, child); diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 30e5ab6b77..81884dfb52 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -71,8 +71,6 @@ static const char *get_message_user_tag(CamelFolder *folder, const char *uid, co static void set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); static int get_message_count(CamelFolder *folder); -static int get_unread_message_count(CamelFolder *folder); -static int get_deleted_message_count(CamelFolder *folder); static void expunge (CamelFolder *folder, CamelException *ex); @@ -130,8 +128,6 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_parent_store = get_parent_store; camel_folder_class->expunge = expunge; camel_folder_class->get_message_count = get_message_count; - camel_folder_class->get_unread_message_count = get_unread_message_count; - camel_folder_class->get_deleted_message_count = get_deleted_message_count; camel_folder_class->append_message = append_message; camel_folder_class->get_permanent_flags = get_permanent_flags; camel_folder_class->get_message_flags = get_message_flags; @@ -356,15 +352,17 @@ folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) count = camel_folder_summary_count(folder->summary); for (j=0; j<count; j++) { if ((info = camel_folder_summary_index(folder->summary, j))) { - if (!(info->flags & CAMEL_MESSAGE_SEEN)) + guint32 flags = camel_message_info_flags(info); + + if ((flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0) unread++; - if (info->flags & CAMEL_MESSAGE_DELETED) + if (flags & CAMEL_MESSAGE_DELETED) deleted++; - if (info->flags & CAMEL_MESSAGE_JUNK) + if (flags & CAMEL_MESSAGE_JUNK) junked++; - if ((info->flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0) + if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0) visible++; - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); } } } @@ -397,7 +395,7 @@ folder_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) for (j=0; j<count; j++) { if ((info = camel_folder_summary_index(folder->summary, j))) { array->pdata[i] = g_strdup(camel_message_info_uid(info)); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); } } *arg->ca_ptr = array; @@ -565,66 +563,24 @@ camel_folder_get_message_count (CamelFolder *folder) return ret; } -static int -get_unread_message_count(CamelFolder *folder) -{ - int i, count, unread=0; - - g_return_val_if_fail(folder->summary != NULL, -1); - - count = camel_folder_summary_count(folder->summary); - for (i=0; i<count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(folder->summary, i); - - if (info) { - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - unread++; - camel_folder_summary_info_free(folder->summary, info); - } - } - - return unread; -} - /** * camel_folder_unread_get_message_count: * @folder: A CamelFolder object * + * DEPRECATED, use camel_object_get instead. + * * Return value: the number of unread messages in the folder, or -1 if unknown. **/ int camel_folder_get_unread_message_count (CamelFolder *folder) { - int ret; + int count = -1; g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1); - ret = CF_CLASS (folder)->get_unread_message_count (folder); - - return ret; -} - + camel_object_get(folder, NULL, CAMEL_FOLDER_UNREAD, &count, 0); -static int -get_deleted_message_count (CamelFolder *folder) -{ - int i, count, deleted = 0; - CamelMessageInfo *info; - - g_return_val_if_fail (folder->summary != NULL, -1); - - count = camel_folder_summary_count (folder->summary); - for (i = 0; i < count; i++) { - if (!(info = camel_folder_summary_index (folder->summary, i))) - continue; - - if ((info->flags & CAMEL_MESSAGE_DELETED)) - deleted++; - - camel_folder_summary_info_free (folder->summary, info); - } - - return deleted; + return count; } /** @@ -636,11 +592,14 @@ get_deleted_message_count (CamelFolder *folder) int camel_folder_get_deleted_message_count (CamelFolder *folder) { + int count = -1; + g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1); - - return CF_CLASS (folder)->get_deleted_message_count (folder); -} + camel_object_get(folder, NULL, CAMEL_FOLDER_DELETED, &count, 0); + + return count; +} static void append_message (CamelFolder *folder, CamelMimeMessage *message, @@ -720,8 +679,8 @@ get_message_flags(CamelFolder *folder, const char *uid) if (info == NULL) return 0; - flags = info->flags; - camel_folder_summary_info_free(folder->summary, info); + flags = camel_message_info_flags(info); + camel_message_info_free(info); return flags; } @@ -731,6 +690,8 @@ get_message_flags(CamelFolder *folder, const char *uid) * @folder: a CamelFolder * @uid: the UID of a message in @folder * + * Deprecated: Use camel_folder_get_message_info instead. + * * Return value: the CamelMessageFlags that are set on the indicated * message. **/ @@ -750,8 +711,7 @@ static gboolean set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) { CamelMessageInfo *info; - CamelFolderChangeInfo *changes; - guint32 old; + int res; g_return_val_if_fail(folder->summary != NULL, FALSE); @@ -759,25 +719,10 @@ set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 s if (info == NULL) return FALSE; - old = info->flags; - info->flags = (old & ~flags) | (set & flags); - if (old != info->flags) { - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(folder->summary); - } - - camel_folder_summary_info_free(folder->summary, info); - - /* app or vfolders don't need to be notified of system flag changes */ - if ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (info->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) - return FALSE; + res = camel_message_info_set_flags(info, flags, set); + camel_message_info_free(info); - changes = camel_folder_change_info_new(); - camel_folder_change_info_change_uid(changes, uid); - camel_object_trigger_event(folder, "folder_changed", changes); - camel_folder_change_info_free(changes); - - return TRUE; + return res; } /** @@ -794,6 +739,9 @@ set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 s * E.g. to set the deleted flag and clear the draft flag, use * set_message_flags(folder, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_DRAFT, CAMEL_MESSAGE_DELETED); * + * DEPRECATED: Use camel_message_info_set_flags on the message info directly + * (when it works) + * * Return Value: TRUE if the flags were changed, false otherwise. **/ gboolean @@ -821,8 +769,8 @@ get_message_user_flag(CamelFolder *folder, const char *uid, const char *name) if (info == NULL) return FALSE; - ret = camel_flag_get(&info->user_flags, name); - camel_folder_summary_info_free(folder->summary, info); + ret = camel_message_info_user_flag(info, name); + camel_message_info_free(info); return ret; } @@ -833,7 +781,9 @@ get_message_user_flag(CamelFolder *folder, const char *uid, const char *name) * @uid: the UID of a message in @folder * @name: the name of a user flag * - * Return value: whether or not the given user flag is set on the message. + * DEPRECATED: Use camel_message_info_get_user_flag on the message info directly + * + * * Return value: whether or not the given user flag is set on the message. **/ gboolean camel_folder_get_message_user_flag (CamelFolder *folder, const char *uid, @@ -859,16 +809,8 @@ set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gb if (info == NULL) return; - if (camel_flag_set(&info->user_flags, name, value)) { - CamelFolderChangeInfo *changes = camel_folder_change_info_new(); - - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(folder->summary); - camel_folder_change_info_change_uid(changes, uid); - camel_object_trigger_event (folder, "folder_changed", changes); - camel_folder_change_info_free(changes); - } - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_set_user_flag(info, name, value); + camel_message_info_free(info); } /** @@ -878,6 +820,8 @@ set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gb * @name: the name of the user flag to set * @value: the value to set it to * + * DEPRECATED: Use camel_message_info_set_user_flag on the message info directly (when it works) + * * Sets the user flag specified by @name to the value specified by @value * on the indicated message. (This may or may not persist after the * folder or store is closed. See camel_folder_get_permanent_flags().) @@ -903,10 +847,8 @@ get_message_user_tag(CamelFolder *folder, const char *uid, const char *name) if (info == NULL) return NULL; - /* FIXME: Need to duplicate tag string */ - - ret = camel_tag_get(&info->user_tags, name); - camel_folder_summary_info_free(folder->summary, info); + ret = camel_message_info_user_tag(info, name); + camel_message_info_free(info); return ret; } @@ -917,6 +859,8 @@ get_message_user_tag(CamelFolder *folder, const char *uid, const char *name) * @uid: the UID of a message in @folder * @name: the name of a user tag * + * DEPRECATED: Use camel_message_info_get_user_tag on the messageinfo directly. + * * Return value: Returns the value of the user tag. **/ const char * @@ -943,16 +887,8 @@ set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, con if (info == NULL) return; - if (camel_tag_set(&info->user_tags, name, value)) { - CamelFolderChangeInfo *changes = camel_folder_change_info_new(); - - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED; - camel_folder_summary_touch(folder->summary); - camel_folder_change_info_change_uid(changes, uid); - camel_object_trigger_event (folder, "folder_changed", changes); - camel_folder_change_info_free(changes); - } - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_set_user_tag(info, name, value); + camel_message_info_free(info); } /** @@ -962,6 +898,8 @@ set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, con * @name: the name of the user tag to set * @value: the value to set it to * + * DEPRECATED: Use camel_message_info_set_user_tag on the messageinfo directly (when it works). + * * Sets the user tag specified by @name to the value specified by @value * on the indicated message. (This may or may not persist after the * folder or store is closed. See camel_folder_get_permanent_flags().) @@ -1011,7 +949,7 @@ free_message_info (CamelFolder *folder, CamelMessageInfo *info) { g_return_if_fail(folder->summary != NULL); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); } /** @@ -1035,7 +973,7 @@ ref_message_info (CamelFolder *folder, CamelMessageInfo *info) { g_return_if_fail(folder->summary != NULL); - camel_folder_summary_info_ref(folder->summary, info); + camel_message_info_ref(info); } /** @@ -1043,6 +981,8 @@ ref_message_info (CamelFolder *folder, CamelMessageInfo *info) * @folder: * @info: * + * DEPRECATED: Use camel_message_info_ref directly. + * * Ref a CamelMessageInfo, previously obtained with get_message_info(). **/ void @@ -1126,7 +1066,7 @@ get_uids(CamelFolder *folder) if (info) { array->pdata[j++] = g_strdup (camel_message_info_uid (info)); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); } } @@ -1376,15 +1316,13 @@ transfer_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, /* if its deleted we poke the flags, so we need to copy the messageinfo */ if ((source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY) && (minfo = camel_folder_get_message_info(source, uid))) { - info = camel_message_info_new(); - camel_message_info_dup_to(minfo, info); + info = camel_message_info_clone(minfo); camel_folder_free_message_info(source, minfo); } else - info = camel_message_info_new_from_header (((CamelMimePart *)msg)->headers); + info = camel_message_info_new_from_header(NULL, ((CamelMimePart *)msg)->headers); /* we don't want to retain the deleted flag */ - if (info && info->flags & CAMEL_MESSAGE_DELETED) - info->flags = info->flags & ~CAMEL_MESSAGE_DELETED; + camel_message_info_set_flags(info, CAMEL_MESSAGE_DELETED, 0); camel_folder_append_message (dest, msg, info, transferred_uid, ex); camel_object_unref (msg); diff --git a/camel/camel-folder.h b/camel/camel-folder.h index 78f8885dc6..850a746a08 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -130,8 +130,6 @@ typedef struct { CamelException *ex); int (*get_message_count) (CamelFolder *folder); - int (*get_unread_message_count) (CamelFolder *folder); - int (*get_deleted_message_count) (CamelFolder *folder); void (*append_message) (CamelFolder *folder, CamelMimeMessage *message, diff --git a/camel/camel-string-utils.c b/camel/camel-string-utils.c index 6949a9aa53..c169c8a65a 100644 --- a/camel/camel-string-utils.c +++ b/camel/camel-string-utils.c @@ -26,10 +26,10 @@ #endif #include <string.h> +#include <pthread.h> #include "camel-string-utils.h" - int camel_strcase_equal (gconstpointer a, gconstpointer b) { @@ -141,3 +141,81 @@ char camel_toupper(char c) return c; } +/* working stuff for pstrings */ +static pthread_mutex_t pstring_lock = PTHREAD_MUTEX_INITIALIZER; +static GHashTable *pstring_table = NULL; + +/** + * camel_pstring_strdup: + * @s: String to copy. + * + * Create a new pooled string entry for the string @s. A pooled + * string is a table where common strings are uniquified to the same + * pointer value. They are also refcounted, so freed when no longer + * in use. In a thread-safe manner. + * + * The NULL and empty strings are special cased to constant values. + * + * Return value: A pointer to an equivalent string of @s. Use + * camel_pstring_free() when it is no longer needed. + **/ +const char *camel_pstring_strdup(const char *s) +{ + char *p; + void *pcount; + int count; + + if (s == NULL) + return NULL; + if (s[0] == 0) + return ""; + + pthread_mutex_lock(&pstring_lock); + if (pstring_table == NULL) + pstring_table = g_hash_table_new(g_str_hash, g_str_equal); + + if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) { + count = GPOINTER_TO_INT(pcount)+1; + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count)); + } else { + p = g_strdup(s); + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(1)); + } + pthread_mutex_unlock(&pstring_lock); + + return p; +} + +/** + * camel_pstring_free: + * @s: String to free. + * + * De-ref a pooled string. If no more refs exist to this string, it will be deallocated. + * + * NULL and the empty string are special cased. + **/ +void camel_pstring_free(const char *s) +{ + char *p; + void *pcount; + int count; + + if (pstring_table == NULL) + return; + if (s == NULL || s[0] == 0) + return; + + pthread_mutex_lock(&pstring_lock); + if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) { + count = GPOINTER_TO_INT(pcount)-1; + if (count == 0) { + g_hash_table_remove(pstring_table, p); + g_free(p); + } else { + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count)); + } + } else { + g_warning("Trying to free string not allocated from the pool '%s'", s); + } + pthread_mutex_unlock(&pstring_lock); +} diff --git a/camel/camel-string-utils.h b/camel/camel-string-utils.h index c6557551d2..30745db7ba 100644 --- a/camel/camel-string-utils.h +++ b/camel/camel-string-utils.h @@ -42,6 +42,9 @@ const char *camel_strdown (char *str); char camel_tolower(char c); char camel_toupper(char c); +const char *camel_pstring_strdup(const char *s); +void camel_pstring_free(const char *s); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/camel-types.h b/camel/camel-types.h index 8345bbf206..5a69a6eee8 100644 --- a/camel/camel-types.h +++ b/camel/camel-types.h @@ -41,7 +41,6 @@ typedef struct _CamelFolderSummary CamelFolderSummary; typedef struct _CamelInternetAddress CamelInternetAddress; typedef struct _CamelMedium CamelMedium; typedef struct _CamelMessageContentInfo CamelMessageContentInfo; -typedef struct _CamelMessageInfo CamelMessageInfo; typedef struct _CamelMimeFilter CamelMimeFilter; typedef struct _CamelMimeFilterBasic CamelMimeFilterBasic; typedef struct _CamelMimeFilterBestenc CamelMimeFilterBestenc; diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index 34211a48aa..7f8473e571 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -30,9 +30,9 @@ #include "camel-exception.h" #include "camel-vee-folder.h" #include "camel-store.h" -#include "camel-folder-summary.h" #include "camel-mime-message.h" #include "camel-folder-search.h" +#include "camel-vee-summary.h" #include "camel-session.h" #include "camel-vee-store.h" /* for open flags */ @@ -51,6 +51,7 @@ #define _PRIVATE(o) (((CamelVeeFolder *)(o))->priv) +#if 0 static void vee_refresh_info(CamelFolder *folder, CamelException *ex); static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex); @@ -66,21 +67,19 @@ static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, Camel static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); static GPtrArray *vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex); -static gboolean vee_set_message_flags (CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -static void vee_set_message_user_flag (CamelFolder *folder, const char *uid, const char *name, gboolean value); -static void vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); static void vee_rename(CamelFolder *folder, const char *new); +#endif static void camel_vee_folder_class_init (CamelVeeFolderClass *klass); static void camel_vee_folder_init (CamelVeeFolder *obj); static void camel_vee_folder_finalise (CamelObject *obj); -static int vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex); -static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun); +static int vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex); +static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source); static void folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf); static void subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf); -static void subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf); +static void folder_renamed(CamelFolder *f, const char *old, CamelVeeFolder *vf); static void folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], int keep, CamelVeeFolder *vf); @@ -104,120 +103,21 @@ camel_vee_folder_get_type (void) return type; } -static void -camel_vee_folder_class_init (CamelVeeFolderClass *klass) -{ - CamelFolderClass *folder_class = (CamelFolderClass *) klass; - - camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); - - folder_class->refresh_info = vee_refresh_info; - folder_class->sync = vee_sync; - folder_class->expunge = vee_expunge; - - folder_class->get_message = vee_get_message; - folder_class->append_message = vee_append_message; - folder_class->transfer_messages_to = vee_transfer_messages_to; - - folder_class->search_by_expression = vee_search_by_expression; - folder_class->search_by_uids = vee_search_by_uids; - - folder_class->set_message_flags = vee_set_message_flags; - folder_class->set_message_user_flag = vee_set_message_user_flag; - folder_class->set_message_user_tag = vee_set_message_user_tag; - - folder_class->rename = vee_rename; - - folder_class->freeze = vee_freeze; - folder_class->thaw = vee_thaw; -} - -static void -camel_vee_folder_init (CamelVeeFolder *obj) -{ - struct _CamelVeeFolderPrivate *p; - CamelFolder *folder = (CamelFolder *)obj; - - p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); - - folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | - CAMEL_FOLDER_HAS_SEARCH_CAPABILITY); - - /* FIXME: what to do about user flags if the subfolder doesn't support them? */ - folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | - CAMEL_MESSAGE_DELETED | - CAMEL_MESSAGE_DRAFT | - CAMEL_MESSAGE_FLAGGED | - CAMEL_MESSAGE_SEEN; - - obj->changes = camel_folder_change_info_new(); - obj->search = camel_folder_search_new(); - - p->summary_lock = g_mutex_new(); - p->subfolder_lock = g_mutex_new(); - p->changed_lock = g_mutex_new(); -} - -static void -camel_vee_folder_finalise (CamelObject *obj) -{ - CamelVeeFolder *vf = (CamelVeeFolder *)obj; - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - GList *node; - CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; - - /* FIXME: check leaks */ - node = p->folders; - while (node) { - CamelFolder *f = node->data; - - if (vf != folder_unmatched) { - camel_object_unhook_event((CamelObject *)f, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf); - camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf); - camel_object_unhook_event((CamelObject *)f, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf); - /* this updates the vfolder */ - if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) - vee_folder_remove_folder(vf, f, FALSE); - } - camel_object_unref((CamelObject *)f); - - node = g_list_next(node); - } - - g_free(vf->expression); - g_free(vf->vname); - - g_list_free(p->folders); - g_list_free(p->folders_changed); - - camel_folder_change_info_free(vf->changes); - camel_object_unref((CamelObject *)vf->search); - - g_mutex_free(p->summary_lock); - g_mutex_free(p->subfolder_lock); - g_mutex_free(p->changed_lock); - - g_free(p); -} - void camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags) { CamelFolder *folder = (CamelFolder *)vf; - char *tmp; + const char *tmp; vf->flags = flags; - vf->vname = g_strdup(name); - tmp = strrchr(vf->vname, '/'); + tmp = strrchr(name, '/'); if (tmp) tmp++; else - tmp = vf->vname; - camel_folder_construct(folder, parent_store, vf->vname, tmp); + tmp = name; + camel_folder_construct(folder, parent_store, name, tmp); - /* should CamelVeeMessageInfo be subclassable ..? */ - folder->summary = camel_folder_summary_new(); - folder->summary->message_info_size = sizeof(CamelVeeMessageInfo); + folder->summary = camel_vee_summary_new(folder); if (CAMEL_IS_VEE_STORE(parent_store)) vf->parent_vee_store = (CamelVeeStore *)parent_store; @@ -262,38 +162,7 @@ camel_vee_folder_new(CamelStore *parent_store, const char *name, guint32 flags) void camel_vee_folder_set_expression(CamelVeeFolder *vf, const char *query) { - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - GList *node; - - CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); - - /* no change, do nothing */ - if ((vf->expression && query && strcmp(vf->expression, query) == 0) - || (vf->expression == NULL && query == NULL)) { - CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); - return; - } - - g_free(vf->expression); - if (query) - vf->expression = g_strdup(query); - - node = p->folders; - while (node) { - CamelFolder *f = node->data; - - if (vee_folder_build_folder(vf, f, NULL) == -1) - break; - - node = node->next; - } - - CAMEL_VEE_FOLDER_LOCK(vf, changed_lock); - g_list_free(p->folders_changed); - p->folders_changed = NULL; - CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock); - - CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); + ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->set_expression(vf, query); } /** @@ -350,9 +219,9 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub) camel_object_hook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc)folder_changed, vf); camel_object_hook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc)subfolder_deleted, vf); - camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)subfolder_renamed, vf); + camel_object_hook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc)folder_renamed, vf); - vee_folder_build_folder(vf, sub, NULL); + ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->add_folder(vf, sub); } /** @@ -366,7 +235,6 @@ void camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) { struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - int killun = FALSE; int i; CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; @@ -383,7 +251,7 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf); camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf); - camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) subfolder_renamed, vf); + camel_object_unhook_event((CamelObject *)sub, "renamed", (CamelObjectEventHookFunc) folder_renamed, vf); p->folders = g_list_remove(p->folders, sub); @@ -402,7 +270,6 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */ if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) { while (g_list_find(up->folders, sub)) { - killun = TRUE; up->folders = g_list_remove(up->folders, sub); camel_object_unref((CamelObject *)sub); @@ -423,18 +290,29 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) camel_folder_thaw(sub); CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock); } - if (g_list_find(up->folders, sub) == NULL) { - killun = TRUE; - } } CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock); } - vee_folder_remove_folder(vf, sub, killun); + ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->remove_folder(vf, sub); camel_object_unref((CamelObject *)sub); } +/** + * camel_vee_folder_rebuild_folder: + * @vf: Virtual Folder object + * @sub: source CamelFolder to add to @vf + * @ex: Exception. + * + * Rebuild the folder @sub, if it should be. + **/ +int +camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex) +{ + return ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->rebuild_folder(vf, sub, ex); +} + static void remove_folders(CamelFolder *folder, CamelFolder *foldercopy, CamelVeeFolder *vf) { @@ -456,7 +334,6 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders) GHashTable *remove = g_hash_table_new(NULL, NULL); GList *l; CamelFolder *folder; - int changed; /* setup a table of all folders we have currently */ CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); @@ -474,15 +351,6 @@ camel_vee_folder_set_folders(CamelVeeFolder *vf, GList *folders) if ((folder = g_hash_table_lookup(remove, l->data))) { g_hash_table_remove(remove, folder); camel_object_unref((CamelObject *)folder); - - /* if this was a changed folder, re-update it while we're here */ - CAMEL_VEE_FOLDER_LOCK(vf, changed_lock); - changed = g_list_find(p->folders_changed, folder) != NULL; - if (changed) - p->folders_changed = g_list_remove(p->folders_changed, folder); - CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock); - if (changed) - vee_folder_build_folder(vf, folder, NULL); } else { camel_vee_folder_add_folder(vf, l->data); } @@ -541,21 +409,25 @@ camel_vee_folder_hash_folder(CamelFolder *folder, char buffer[8]) CamelFolder * camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid) { + CamelFolder *folder; + + folder = vinfo->real->summary->folder; + /* locking? yes? no? although the vfolderinfo is valid when obtained the folder in it might not necessarily be so ...? */ - if (CAMEL_IS_VEE_FOLDER(vinfo->folder)) { - CamelFolder *folder; + if (CAMEL_IS_VEE_FOLDER(folder)) { + CamelFolder *res; const CamelVeeMessageInfo *vfinfo; - vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(vinfo->folder, camel_message_info_uid(vinfo)+8); - folder = camel_vee_folder_get_location((CamelVeeFolder *)vinfo->folder, vfinfo, realuid); - camel_folder_free_message_info(vinfo->folder, (CamelMessageInfo *)vfinfo); - return folder; + vfinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(folder, camel_message_info_uid(vinfo)+8); + res = camel_vee_folder_get_location((CamelVeeFolder *)folder, vfinfo, realuid); + camel_folder_free_message_info(folder, (CamelMessageInfo *)vfinfo); + return res; } else { if (realuid) *realuid = g_strdup(camel_message_info_uid(vinfo)+8); - return vinfo->folder; + return folder; } } @@ -574,7 +446,7 @@ static void vee_refresh_info(CamelFolder *folder, CamelException *ex) while (node) { CamelFolder *f = node->data; - if (vee_folder_build_folder(vf, f, ex) == -1) + if (camel_vee_folder_rebuild_folder(vf, f, ex) == -1) break; node = node->next; @@ -607,7 +479,7 @@ vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) /* auto update vfolders shouldn't need a rebuild */ if ((vf->flags & CAMEL_STORE_VEE_FOLDER_AUTO) == 0 - && vee_folder_build_folder(vf, f, ex) == -1) + && camel_vee_folder_rebuild_folder(vf, f, ex) == -1) break; node = node->next; @@ -639,8 +511,8 @@ vee_get_message(CamelFolder *folder, const char *uid, CamelException *ex) mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); if (mi) { - msg = camel_folder_get_message(mi->folder, camel_message_info_uid(mi)+8, ex); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); + msg = camel_folder_get_message(mi->real->summary->folder, camel_message_info_uid(mi)+8, ex); + camel_message_info_free((CamelMessageInfo *)mi); } else { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("No such message %s in %s"), uid, @@ -760,53 +632,11 @@ vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); g_hash_table_destroy(searched); - g_ptr_array_free(folder_uids, 0); + g_ptr_array_free(folder_uids, TRUE); return result; } -static gboolean -vee_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - CamelVeeMessageInfo *mi; - int res = FALSE; - - mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); - if (mi) { - res = camel_folder_set_message_flags(mi->folder, camel_message_info_uid(mi) + 8, flags, set); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); - res = res || ((CamelFolderClass *)camel_vee_folder_parent)->set_message_flags(folder, uid, flags, set); - } - - return res; -} - -static void -vee_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - CamelVeeMessageInfo *mi; - - mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); - if (mi) { - camel_folder_set_message_user_flag(mi->folder, camel_message_info_uid(mi) + 8, name, value); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); - ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_flag(folder, uid, name, value); - } -} - -static void -vee_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) -{ - CamelVeeMessageInfo *mi; - - mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); - if (mi) { - camel_folder_set_message_user_tag(mi->folder, camel_message_info_uid(mi) + 8, name, value); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); - ((CamelFolderClass *)camel_vee_folder_parent)->set_message_user_tag(folder, uid, name, value); - } -} - static void vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, CamelException *ex) { @@ -821,57 +651,36 @@ vee_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *des static void vee_rename(CamelFolder *folder, const char *new) { - CamelVeeFolder *vf = (CamelVeeFolder *)folder; - - g_free(vf->vname); - vf->vname = g_strdup(new); + /*CamelVeeFolder *vf = (CamelVeeFolder *)folder;*/ ((CamelFolderClass *)camel_vee_folder_parent)->rename(folder, new); } -/* ********************************************************************** * - utility functions */ - -/* must be called with summary_lock held */ -static CamelVeeMessageInfo * -vee_folder_add_info(CamelVeeFolder *vf, CamelFolder *f, CamelMessageInfo *info, const char hash[8]) +static void vee_delete(CamelFolder *folder) { - CamelVeeMessageInfo *mi; - char *vuid; - const char *uid; - CamelFolder *folder = (CamelFolder *)vf; - CamelMessageInfo *dinfo; + struct _CamelVeeFolderPrivate *p = _PRIVATE(folder); - uid = camel_message_info_uid(info); - vuid = alloca(strlen(uid)+9); - memcpy(vuid, hash, 8); - strcpy(vuid+8, uid); - dinfo = camel_folder_summary_uid(folder->summary, vuid); - if (dinfo) { - d(printf("w:clash, we already have '%s' in summary\n", vuid)); - camel_folder_summary_info_free(folder->summary, dinfo); - return NULL; - } + /* NB: this is never called on UNMTACHED */ - d(printf("adding vuid %s to %s\n", vuid, vf->vname)); - - mi = (CamelVeeMessageInfo *)camel_folder_summary_info_new(folder->summary); - camel_message_info_dup_to(info, (CamelMessageInfo *)mi); -#ifdef DOEPOOLV - mi->info.strings = e_poolv_set(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid, FALSE); -#elif defined (DOESTRV) - mi->info.strings = e_strv_set_ref(mi->info.strings, CAMEL_MESSAGE_INFO_UID, vuid); - mi->info.strings = e_strv_pack(mi->info.strings); -#else - g_free(mi->info.uid); - mi->info.uid = g_strdup(vuid); -#endif - mi->folder = f; - camel_folder_summary_add(folder->summary, (CamelMessageInfo *)mi); + CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock); + while (p->folders) { + CamelFolder *f = p->folders->data; - return mi; + camel_object_ref(f); + CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock); + + camel_vee_folder_remove_folder((CamelVeeFolder *)folder, f); + camel_object_unref(f); + CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock); + } + CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock); + + ((CamelFolderClass *)camel_vee_folder_parent)->delete(folder); } +/* ********************************************************************** * + utility functions */ + /* must be called with summary_lock held */ static CamelVeeMessageInfo * vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const char hash[8]) @@ -881,14 +690,14 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const info = camel_folder_get_message_info(f, inuid); if (info) { - mi = vee_folder_add_info(vf, f, info, hash); + mi = camel_vee_summary_add((CamelVeeSummary *)((CamelFolder *)vf)->summary, info, hash); camel_folder_free_message_info(f, info); } return mi; } static void -vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) +vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source) { int i, count, n, still = FALSE, start, last; char *oldkey; @@ -899,10 +708,15 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) void *oldval; CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL; - + CamelFolderSummary *ssummary = source->summary; + int killun = FALSE; + if (vf == folder_unmatched) return; + if ((source->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED)) + killun = TRUE; + CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); if (folder_unmatched != NULL) { @@ -925,7 +739,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i); if (mi) { - if (mi->folder == source) { + if (mi->real->summary == ssummary) { camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi)); if (last == -1) { last = start = i; @@ -937,7 +751,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) start = last = i; } } - camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } } if (last != -1) @@ -951,7 +765,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) for (i=0;i<count;i++) { CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i); if (mi) { - if (mi->folder == source) { + if (mi->real->summary == ssummary) { const char *uid = camel_message_info_uid(mi); camel_folder_change_info_remove_uid(vf->changes, uid); @@ -986,7 +800,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) } } } - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } } @@ -1046,7 +860,7 @@ unmatched_check_uid(char *uidin, void *value, struct _update_data *u) if (mi) { camel_folder_summary_remove(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi); camel_folder_change_info_remove_uid(u->folder_unmatched->changes, uid); - camel_folder_summary_info_free(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } } } @@ -1075,7 +889,7 @@ folder_added_uid(char *uidin, void *value, struct _update_data *u) /* build query contents for a single folder */ static int -vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex) +vee_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex) { GPtrArray *match, *all; GHashTable *allhash, *matchhash; @@ -1086,6 +900,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL; CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL; + CamelFolderSummary *ssummary = source->summary; if (vf == folder_unmatched) return 0; @@ -1130,7 +945,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i); if (mi) { - if (mi->folder == source) { + if (mi->real->summary == ssummary) { char *uid = (char *)camel_message_info_uid(mi), *oldkey; void *oldval; @@ -1160,7 +975,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException g_hash_table_remove(matchhash, uid+8); } } - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } } if (last != -1) @@ -1176,7 +991,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i); if (mi) { - if (mi->folder == source) { + if (mi->real->summary == ssummary) { char *uid = (char *)camel_message_info_uid(mi); if (g_hash_table_lookup(allhash, uid+8) == NULL) { @@ -1188,7 +1003,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException g_hash_table_remove(allhash, uid+8); } } - camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } } @@ -1295,7 +1110,7 @@ folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8], if (vinfo) { camel_folder_change_info_remove_uid(vf->changes, vuid); camel_folder_summary_remove(folder->summary, (CamelMessageInfo *)vinfo); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo); + camel_message_info_free((CamelMessageInfo *)vinfo); } if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) { @@ -1350,45 +1165,23 @@ folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], info = camel_folder_get_message_info(sub, uid); if (info) { if (vinfo) { - int changed = FALSE; - - if (vinfo->info.flags != info->flags){ - vinfo->info.flags = info->flags; - changed = TRUE; - } - - changed |= camel_flag_list_copy(&vinfo->info.user_flags, &info->user_flags); - changed |= camel_tag_list_copy(&vinfo->info.user_tags, &info->user_tags); - if (changed) - camel_folder_change_info_change_uid(vf->changes, vuid); - - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo); + camel_folder_change_info_change_uid(vf->changes, vuid); + camel_message_info_free((CamelMessageInfo *)vinfo); } if (uinfo) { - int changed = FALSE; - - if (uinfo->info.flags != info->flags){ - uinfo->info.flags = info->flags; - changed = TRUE; - } - - changed |= camel_flag_list_copy(&uinfo->info.user_flags, &info->user_flags); - changed |= camel_tag_list_copy(&uinfo->info.user_tags, &info->user_tags); - if (changed) - camel_folder_change_info_change_uid(folder_unmatched->changes, vuid); - - camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo); + camel_folder_change_info_change_uid(folder_unmatched->changes, vuid); + camel_message_info_free((CamelMessageInfo *)uinfo); } camel_folder_free_message_info(sub, info); } else { if (vinfo) { folder_changed_remove_uid(sub, uid, hash, FALSE, vf); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo); + camel_message_info_free((CamelMessageInfo *)vinfo); } if (uinfo) - camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)uinfo); + camel_message_info_free((CamelMessageInfo *)uinfo); } } } @@ -1464,7 +1257,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg) g_ptr_array_add(newchanged, (char *)uid); } else { g_ptr_array_add(always_changed, (char *)uid); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo); + camel_message_info_free((CamelMessageInfo *)vinfo); } } changed = newchanged; @@ -1568,7 +1361,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg) dd(printf(" removing uid '%s' [did match]\n", uid)); folder_changed_remove_uid(sub, uid, hash, TRUE, vf); } - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo); + camel_message_info_free((CamelMessageInfo *)vinfo); } } g_hash_table_destroy(matches_hash); @@ -1644,7 +1437,7 @@ static CamelSessionThreadOps folder_changed_ops = { }; static void -folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf) +folder_changed_base(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo *changes) { struct _folder_changed_msg *m; CamelSession *session = ((CamelService *)((CamelFolder *)vf)->parent_store)->session; @@ -1659,6 +1452,12 @@ folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder camel_session_thread_queue(session, &m->msg, 0); } +static void +folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf) +{ + ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_changed(vf, sub, changes); +} + /* track vanishing folders */ static void subfolder_deleted(CamelFolder *f, void *event_data, CamelVeeFolder *vf) @@ -1673,6 +1472,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8]) CamelFolderChangeInfo *changes = NULL; CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL; + CamelFolderSummary *ssummary = sub->summary; CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); @@ -1684,7 +1484,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8]) if (mi == NULL) continue; - if (mi->folder == sub) { + if (mi->real->summary == ssummary) { char *uid = (char *)camel_message_info_uid(mi); char *oldkey; void *oldval; @@ -1709,7 +1509,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8]) } } - camel_folder_summary_info_free(((CamelFolder *)vf)->summary, (CamelMessageInfo *)mi); + camel_message_info_free((CamelMessageInfo *)mi); } if (camel_folder_change_info_changed(vf->changes)) { @@ -1726,7 +1526,7 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8]) } static void -subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf) +folder_renamed_base(CamelVeeFolder *vf, CamelFolder *f, const char *old) { char hash[8]; CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; @@ -1744,6 +1544,12 @@ subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf) } static void +folder_renamed(CamelFolder *sub, const char *old, CamelVeeFolder *vf) +{ + ((CamelVeeFolderClass *)((CamelObject *)vf)->klass)->folder_renamed(vf, sub, old); +} + +static void vee_freeze (CamelFolder *folder) { CamelVeeFolder *vfolder = (CamelVeeFolder *)folder; @@ -1788,3 +1594,148 @@ vee_thaw(CamelFolder *folder) /* call parent implementation */ CAMEL_FOLDER_CLASS (camel_vee_folder_parent)->thaw(folder); } + +/* vfolder base implementaitons */ +static void +vee_add_folder(CamelVeeFolder *vf, CamelFolder *sub) +{ + vee_rebuild_folder(vf, sub, NULL); +} + +static void +vee_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) +{ + vee_folder_remove_folder(vf, sub); +} + +static void +vee_set_expression(CamelVeeFolder *vf, const char *query) +{ + struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); + GList *node; + + CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + + /* no change, do nothing */ + if ((vf->expression && query && strcmp(vf->expression, query) == 0) + || (vf->expression == NULL && query == NULL)) { + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); + return; + } + + g_free(vf->expression); + if (query) + vf->expression = g_strdup(query); + + node = p->folders; + while (node) { + CamelFolder *f = node->data; + + if (camel_vee_folder_rebuild_folder(vf, f, NULL) == -1) + break; + + node = node->next; + } + + CAMEL_VEE_FOLDER_LOCK(vf, changed_lock); + g_list_free(p->folders_changed); + p->folders_changed = NULL; + CAMEL_VEE_FOLDER_UNLOCK(vf, changed_lock); + + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); +} + +static void +camel_vee_folder_class_init (CamelVeeFolderClass *klass) +{ + CamelFolderClass *folder_class = (CamelFolderClass *) klass; + + camel_vee_folder_parent = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ())); + + folder_class->refresh_info = vee_refresh_info; + folder_class->sync = vee_sync; + folder_class->expunge = vee_expunge; + + folder_class->get_message = vee_get_message; + folder_class->append_message = vee_append_message; + folder_class->transfer_messages_to = vee_transfer_messages_to; + + folder_class->search_by_expression = vee_search_by_expression; + folder_class->search_by_uids = vee_search_by_uids; + + folder_class->rename = vee_rename; + folder_class->delete = vee_delete; + + folder_class->freeze = vee_freeze; + folder_class->thaw = vee_thaw; + + klass->set_expression = vee_set_expression; + klass->add_folder = vee_add_folder; + klass->remove_folder = vee_remove_folder; + klass->rebuild_folder = vee_rebuild_folder; + klass->folder_changed = folder_changed_base; + klass->folder_renamed = folder_renamed_base; +} + +static void +camel_vee_folder_init (CamelVeeFolder *obj) +{ + struct _CamelVeeFolderPrivate *p; + CamelFolder *folder = (CamelFolder *)obj; + + p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); + + folder->folder_flags |= (CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY | + CAMEL_FOLDER_HAS_SEARCH_CAPABILITY); + + /* FIXME: what to do about user flags if the subfolder doesn't support them? */ + folder->permanent_flags = CAMEL_MESSAGE_ANSWERED | + CAMEL_MESSAGE_DELETED | + CAMEL_MESSAGE_DRAFT | + CAMEL_MESSAGE_FLAGGED | + CAMEL_MESSAGE_SEEN; + + obj->changes = camel_folder_change_info_new(); + obj->search = camel_folder_search_new(); + + p->summary_lock = g_mutex_new(); + p->subfolder_lock = g_mutex_new(); + p->changed_lock = g_mutex_new(); +} + +static void +camel_vee_folder_finalise (CamelObject *obj) +{ + CamelVeeFolder *vf = (CamelVeeFolder *)obj; + struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); + CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL; + GList *node; + + /* TODO: there may be other leaks? */ + + /* This may invoke sub-classes with partially destroyed state, they must deal with this */ + if (vf == folder_unmatched) { + for (node = p->folders;node;node = g_list_next(node)) + camel_object_unref(node->data); + } else { + while (p->folders) { + CamelFolder *f = p->folders->data; + + camel_vee_folder_remove_folder(vf, f); + } + } + + g_free(vf->expression); + + g_list_free(p->folders); + g_list_free(p->folders_changed); + + camel_folder_change_info_free(vf->changes); + camel_object_unref((CamelObject *)vf->search); + + g_mutex_free(p->summary_lock); + g_mutex_free(p->subfolder_lock); + g_mutex_free(p->changed_lock); + + g_free(p); +} diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h index 79f13a7280..bccdf2c7ab 100644 --- a/camel/camel-vee-folder.h +++ b/camel/camel-vee-folder.h @@ -1,8 +1,8 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 2000 Ximian Inc. + * Copyright (C) 2000 Ximian Inc. * - * Authors: Michael Zucchi <notzed@ximian.com> + * Authors: Michael Zucchi <notzed@ximian.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -30,6 +30,7 @@ extern "C" { #include <glib.h> #include <camel/camel-folder.h> +#include <camel/camel-vee-summary.h> #define CAMEL_VEE_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vee_folder_get_type (), CamelVeeFolder) #define CAMEL_VEE_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_folder_get_type (), CamelVeeFolderClass) @@ -38,19 +39,12 @@ extern "C" { typedef struct _CamelVeeFolder CamelVeeFolder; typedef struct _CamelVeeFolderClass CamelVeeFolderClass; -/* our message info includes the parent folder */ -typedef struct _CamelVeeMessageInfo { - CamelMessageInfo info; - CamelFolder *folder; -} CamelVeeMessageInfo; - struct _CamelVeeFolder { CamelFolder parent; struct _CamelVeeFolderPrivate *priv; char *expression; /* query expression */ - char *vname; /* local name */ guint32 flags; /* folder open flags */ @@ -64,6 +58,19 @@ struct _CamelVeeFolder { struct _CamelVeeFolderClass { CamelFolderClass parent_class; + + /* TODO: Some of this may need some additional work/thinking through, it works for now*/ + + void (*add_folder)(CamelVeeFolder *, CamelFolder *); + void (*remove_folder)(CamelVeeFolder *, CamelFolder *); + int (*rebuild_folder)(CamelVeeFolder *, CamelFolder *, CamelException *); + + void (*set_expression)(CamelVeeFolder *, const char *); + + /* Called for a folder-changed event on a source folder */ + void (*folder_changed)(CamelVeeFolder *, CamelFolder *sub, CamelFolderChangeInfo *changes); + /* Called for a folder-renamed event on a source folder */ + void (*folder_renamed)(CamelVeeFolder *, CamelFolder *sub, const char *old); }; #define CAMEL_UNMATCHED_NAME "UNMATCHED" @@ -72,11 +79,12 @@ CamelType camel_vee_folder_get_type (void); CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name, guint32 flags); void camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags); -CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const CamelVeeMessageInfo *vinfo, char **realuid); +CamelFolder *camel_vee_folder_get_location(CamelVeeFolder *vf, const struct _CamelVeeMessageInfo *vinfo, char **realuid); void camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub); void camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub); void camel_vee_folder_set_folders (CamelVeeFolder *vf, GList *folders); +int camel_vee_folder_rebuild_folder(CamelVeeFolder *vf, CamelFolder *sub, CamelException *ex); void camel_vee_folder_set_expression (CamelVeeFolder *vf, const char *expr); void camel_vee_folder_hash_folder (CamelFolder *folder, char buffer[8]); diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 90c6ee1f95..8068339f28 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -179,8 +179,8 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel vf = (CamelVeeFolder *)camel_vee_folder_new(store, folder_name, flags); if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) { /* Check that parents exist, if not, create dummy ones */ - name = alloca(strlen(vf->vname)+1); - strcpy(name, vf->vname); + name = alloca(strlen(((CamelFolder *)vf)->full_name)+1); + strcpy(name, ((CamelFolder *)vf)->full_name); p = name; while ( (p = strchr(p, '/'))) { *p = 0; @@ -198,7 +198,7 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel *p++='/'; } - change_folder(store, vf->vname, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf)); + change_folder(store, ((CamelFolder *)vf)->full_name, CHANGE_ADD, camel_folder_get_message_count((CamelFolder *)vf)); } return (CamelFolder *)vf; diff --git a/camel/camel-vee-summary.c b/camel/camel-vee-summary.c new file mode 100644 index 0000000000..6c44e0fa1e --- /dev/null +++ b/camel/camel-vee-summary.c @@ -0,0 +1,227 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2000 Ximian Inc. + * + * Authors: Michael Zucchi <notzed@ximian.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/stat.h> +#include <sys/uio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#include "camel-vee-summary.h" +#include "camel-folder.h" + +#define d(x) + +static CamelFolderSummaryClass *camel_vee_summary_parent; + +static void +vee_message_info_free(CamelFolderSummary *s, CamelMessageInfo *info) +{ + CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)info; + + g_free(info->uid); + camel_message_info_free(mi->real); +} + +static CamelMessageInfo * +vee_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi) +{ + CamelVeeMessageInfo *to; + const CamelVeeMessageInfo *from = (const CamelVeeMessageInfo *)mi; + + to = (CamelVeeMessageInfo *)camel_message_info_new(s); + + to->real = camel_message_info_clone(from->real); + to->info.summary = s; + + return (CamelMessageInfo *)to; +} + +static const void * +vee_info_ptr(const CamelMessageInfo *mi, int id) +{ + return camel_message_info_ptr(((CamelVeeMessageInfo *)mi)->real, id); +} + +static guint32 +vee_info_uint32(const CamelMessageInfo *mi, int id) +{ + return camel_message_info_uint32(((CamelVeeMessageInfo *)mi)->real, id); +} + +static time_t +vee_info_time(const CamelMessageInfo *mi, int id) +{ + return camel_message_info_time(((CamelVeeMessageInfo *)mi)->real, id); +} + +static gboolean +vee_info_user_flag(const CamelMessageInfo *mi, const char *id) +{ + return camel_message_info_user_flag(((CamelVeeMessageInfo *)mi)->real, id); +} + +static const char * +vee_info_user_tag(const CamelMessageInfo *mi, const char *id) +{ + return camel_message_info_user_tag(((CamelVeeMessageInfo *)mi)->real, id); +} + +static gboolean +vee_info_set_user_flag(CamelMessageInfo *mi, const char *name, gboolean value) +{ + int res = FALSE; + + if (mi->uid) + res = camel_message_info_set_user_flag(((CamelVeeMessageInfo *)mi)->real, name, value); + + return res; +} + +static gboolean +vee_info_set_user_tag(CamelMessageInfo *mi, const char *name, const char *value) +{ + int res = FALSE; + + if (mi->uid) + res = camel_message_info_set_user_tag(((CamelVeeMessageInfo *)mi)->real, name, value); + + return res; +} + +static gboolean +vee_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set) +{ + int res = FALSE; + + if (mi->uid) + res = camel_message_info_set_flags(((CamelVeeMessageInfo *)mi)->real, flags, set); + + return res; +} + +static void +camel_vee_summary_class_init (CamelVeeSummaryClass *klass) +{ + ((CamelFolderSummaryClass *)klass)->message_info_clone = vee_message_info_clone; + ((CamelFolderSummaryClass *)klass)->message_info_free = vee_message_info_free; + + ((CamelFolderSummaryClass *)klass)->info_ptr = vee_info_ptr; + ((CamelFolderSummaryClass *)klass)->info_uint32 = vee_info_uint32; + ((CamelFolderSummaryClass *)klass)->info_time = vee_info_time; + ((CamelFolderSummaryClass *)klass)->info_user_flag = vee_info_user_flag; + ((CamelFolderSummaryClass *)klass)->info_user_tag = vee_info_user_tag; + +#if 0 + ((CamelFolderSummaryClass *)klass)->info_set_string = vee_info_set_string; + ((CamelFolderSummaryClass *)klass)->info_set_uint32 = vee_info_set_uint32; + ((CamelFolderSummaryClass *)klass)->info_set_time = vee_info_set_time; + ((CamelFolderSummaryClass *)klass)->info_set_references = vee_info_set_references; +#endif + ((CamelFolderSummaryClass *)klass)->info_set_user_flag = vee_info_set_user_flag; + ((CamelFolderSummaryClass *)klass)->info_set_user_tag = vee_info_set_user_tag; + + ((CamelFolderSummaryClass *)klass)->info_set_flags = vee_info_set_flags; +} + +static void +camel_vee_summary_init (CamelVeeSummary *obj) +{ + CamelFolderSummary *s = (CamelFolderSummary *)obj; + + s->message_info_size = sizeof(CamelVeeMessageInfo); + s->content_info_size = 0; +} + +CamelType +camel_vee_summary_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + camel_vee_summary_parent = (CamelFolderSummaryClass *)camel_folder_summary_get_type(); + + type = camel_type_register( + camel_folder_summary_get_type(), "CamelVeeSummary", + sizeof (CamelVeeSummary), + sizeof (CamelVeeSummaryClass), + (CamelObjectClassInitFunc) camel_vee_summary_class_init, + NULL, + (CamelObjectInitFunc) camel_vee_summary_init, + NULL); + } + + return type; +} + +/** + * camel_vee_summary_new: + * @parent: Folder its attached to. + * + * This will create a new CamelVeeSummary object and read in the + * summary data from disk, if it exists. + * + * Return value: A new CamelVeeSummary object. + **/ +CamelFolderSummary * +camel_vee_summary_new(CamelFolder *parent) +{ + CamelVeeSummary *s; + + s = (CamelVeeSummary *)camel_object_new(camel_vee_summary_get_type()); + s->summary.folder = parent; + + return &s->summary; +} + +CamelVeeMessageInfo * +camel_vee_summary_add(CamelVeeSummary *s, CamelMessageInfo *info, const char hash[8]) +{ + CamelVeeMessageInfo *mi; + char *vuid; + const char *uid; + + uid = camel_message_info_uid(info); + vuid = g_malloc(strlen(uid)+9); + memcpy(vuid, hash, 8); + strcpy(vuid+8, uid); + mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(&s->summary, vuid); + if (mi) { + d(printf("w:clash, we already have '%s' in summary\n", vuid)); + camel_message_info_free((CamelMessageInfo *)mi); + g_free(vuid); + return NULL; + } + + mi = (CamelVeeMessageInfo *)camel_message_info_new(&s->summary); + mi->real = info; + camel_message_info_ref(info); + mi->info.uid = vuid; + + camel_folder_summary_add(&s->summary, (CamelMessageInfo *)mi); + + return mi; +} diff --git a/camel/camel-vee-summary.h b/camel/camel-vee-summary.h new file mode 100644 index 0000000000..aa2683a19c --- /dev/null +++ b/camel/camel-vee-summary.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2000 Ximian Inc. + * + * Authors: + * Michael Zucchi <notzed@ximian.com> + * Dan Winship <danw@ximian.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _CAMEL_VEE_SUMMARY_H +#define _CAMEL_VEE_SUMMARY_H + +#include <camel/camel-folder-summary.h> +#include <camel/camel-exception.h> + +struct _CamelVeeFolder; +struct _CamelFolder; + +#define CAMEL_VEE_SUMMARY(obj) CAMEL_CHECK_CAST (obj, camel_vee_summary_get_type (), CamelVeeSummary) +#define CAMEL_VEE_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vee_summary_get_type (), CamelVeeSummaryClass) +#define CAMEL_IS_VEE_SUMMARY(obj) CAMEL_CHECK_TYPE (obj, camel_vee_summary_get_type ()) + +typedef struct _CamelVeeSummary CamelVeeSummary; +typedef struct _CamelVeeSummaryClass CamelVeeSummaryClass; + +typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo; + +struct _CamelVeeMessageInfo { + CamelMessageInfo info; + + CamelMessageInfo *real; +}; + +struct _CamelVeeSummary { + CamelFolderSummary summary; +}; + +struct _CamelVeeSummaryClass { + CamelFolderSummaryClass parent_class; + +}; + +CamelType camel_vee_summary_get_type (void); +CamelFolderSummary *camel_vee_summary_new(struct _CamelFolder *parent); + +CamelVeeMessageInfo * camel_vee_summary_add(CamelVeeSummary *s, CamelMessageInfo *info, const char hash[8]); + +#endif /* ! _CAMEL_VEE_SUMMARY_H */ + diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c index 91e4b8a3a1..63656f438f 100644 --- a/camel/camel-vtrash-folder.c +++ b/camel/camel-vtrash-folder.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Authors: Jeffrey Stedfast <fejj@ximian.com> + * Michael Zucchi <notzed@ximian.com> * * Copyright 2001 Ximian, Inc. (www.ximian.com) * @@ -28,6 +29,7 @@ #include "camel-vee-store.h" #include "camel-mime-message.h" #include "camel-i18n.h" +#include "camel-private.h" #include <string.h> @@ -49,23 +51,7 @@ static struct { static CamelVeeFolderClass *camel_vtrash_folder_parent; -static void vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message, - const CamelMessageInfo *info, char **appended_uid, - CamelException *ex); -static void vtrash_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, - CamelFolder *dest, GPtrArray **transferred_uids, - gboolean delete_originals, CamelException *ex); - -static void -camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) -{ - CamelFolderClass *folder_class = (CamelFolderClass *) klass; - - camel_vtrash_folder_parent = CAMEL_VEE_FOLDER_CLASS(camel_vee_folder_get_type()); - - folder_class->append_message = vtrash_append_message; - folder_class->transfer_messages_to = vtrash_transfer_messages_to; -} +static void camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass); static void camel_vtrash_folder_init (CamelVTrashFolder *vtrash) @@ -121,6 +107,77 @@ camel_vtrash_folder_new (CamelStore *parent_store, enum _camel_vtrash_folder_t t return (CamelFolder *)vtrash; } +static int +vtrash_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args) +{ + CamelFolder *folder = (CamelFolder *)object; + int i; + guint32 tag; + int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1; + + for (i=0;i<args->argc;i++) { + CamelArgGet *arg = &args->argv[i]; + + tag = arg->tag; + + /* NB: this is a copy of camel-folder.c with the unread count logic altered. + makes sure its still atomically calculated */ + switch (tag & CAMEL_ARG_TAG) { + case CAMEL_FOLDER_ARG_UNREAD: + case CAMEL_FOLDER_ARG_DELETED: + case CAMEL_FOLDER_ARG_JUNKED: + case CAMEL_FOLDER_ARG_VISIBLE: + /* This is so we can get the values atomically, and also so we can calculate them only once */ + if (unread == -1) { + int j; + CamelMessageInfo *info; + + unread = 0; + count = camel_folder_summary_count(folder->summary); + for (j=0; j<count; j++) { + if ((info = camel_folder_summary_index(folder->summary, j))) { + guint32 flags = camel_message_info_flags(info); + + if ((flags & (CAMEL_MESSAGE_SEEN)) == 0) + unread++; + if (flags & CAMEL_MESSAGE_DELETED) + deleted++; + if (flags & CAMEL_MESSAGE_JUNK) + junked++; + if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0) + visible++; + camel_message_info_free(info); + } + } + } + + switch (tag & CAMEL_ARG_TAG) { + case CAMEL_FOLDER_ARG_UNREAD: + count = unread; + break; + case CAMEL_FOLDER_ARG_DELETED: + count = deleted; + break; + case CAMEL_FOLDER_ARG_JUNKED: + count = junked; + break; + case CAMEL_FOLDER_ARG_VISIBLE: + count = visible; + break; + } + + *arg->ca_int = count; + break; + default: + continue; + } + + arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE; + } + + return ((CamelObjectClass *)camel_vtrash_folder_parent)->getv(object, ex, args); +} + static void vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, char **appended_uid, @@ -199,20 +256,20 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, continue; } - if (dest == mi->folder) { + if (dest == mi->real->summary->folder) { /* Just unset the flag on the original message */ camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0); } else { if (batch == NULL) batch = g_hash_table_new(NULL, NULL); - md = g_hash_table_lookup(batch, mi->folder); + md = g_hash_table_lookup(batch, mi->real->summary->folder); if (md == NULL) { md = g_malloc0(sizeof(*md)); - md->folder = mi->folder; + md->folder = mi->real->summary->folder; camel_object_ref((CamelObject *)md->folder); md->uids = g_ptr_array_new(); md->dest = dest; - g_hash_table_insert(batch, mi->folder, md); + g_hash_table_insert(batch, mi->real->summary->folder, md); } tuid = uids->pdata[i]; @@ -228,3 +285,322 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, g_hash_table_destroy(batch); } } + +static GPtrArray * +vtrash_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex) +{ + GList *node; + GPtrArray *matches, *result = g_ptr_array_new(), *uids = g_ptr_array_new(); + struct _CamelVeeFolderPrivate *p = ((CamelVeeFolder *)folder)->priv; + + /* we optimise the search by only searching for messages which we have anyway */ + CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock); + node = p->folders; + while (node) { + CamelFolder *f = node->data; + int i; + char hash[8]; + GPtrArray *infos = camel_folder_get_summary(f); + + camel_vee_folder_hash_folder(f, hash); + + for (i=0;i<infos->len;i++) { + CamelMessageInfo *mi = infos->pdata[i]; + + if (camel_message_info_flags(mi) & ((CamelVTrashFolder *)folder)->bit) + g_ptr_array_add(uids, (void *)camel_message_info_uid(mi)); + } + + if (uids->len > 0 + && (matches = camel_folder_search_by_uids(f, expression, uids, NULL))) { + for (i = 0; i < matches->len; i++) { + char *uid = matches->pdata[i], *vuid; + + vuid = g_malloc(strlen(uid)+9); + memcpy(vuid, hash, 8); + strcpy(vuid+8, uid); + g_ptr_array_add(result, vuid); + } + camel_folder_search_free(f, matches); + } + g_ptr_array_set_size(uids, 0); + camel_folder_free_summary(f, infos); + + node = g_list_next(node); + } + CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock); + + g_ptr_array_free(uids, TRUE); + + return result; +} + +static GPtrArray * +vtrash_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex) +{ + GList *node; + GPtrArray *matches, *result = g_ptr_array_new(), *folder_uids = g_ptr_array_new(); + struct _CamelVeeFolderPrivate *p = ((CamelVeeFolder *)folder)->priv; + + CAMEL_VEE_FOLDER_LOCK(folder, subfolder_lock); + + node = p->folders; + while (node) { + CamelFolder *f = node->data; + int i; + char hash[8]; + + camel_vee_folder_hash_folder(f, hash); + + /* map the vfolder uid's to the source folder uid's first */ + g_ptr_array_set_size(uids, 0); + for (i=0;i<uids->len;i++) { + char *uid = uids->pdata[i]; + + if (strlen(uid) >= 8 && strncmp(uid, hash, 8) == 0) { + CamelMessageInfo *mi; + + mi = camel_folder_get_message_info(f, uid+8); + if (mi) { + if(camel_message_info_flags(mi) & ((CamelVTrashFolder *)folder)->bit) + g_ptr_array_add(folder_uids, uid+8); + camel_folder_free_message_info(f, mi); + } + } + } + + if (folder_uids->len > 0 + && (matches = camel_folder_search_by_uids(f, expression, folder_uids, ex))) { + for (i = 0; i < matches->len; i++) { + char *uid = matches->pdata[i], *vuid; + + vuid = g_malloc(strlen(uid)+9); + memcpy(vuid, hash, 8); + strcpy(vuid+8, uid); + g_ptr_array_add(result, vuid); + } + camel_folder_search_free(f, matches); + } + node = g_list_next(node); + } + + CAMEL_VEE_FOLDER_UNLOCK(folder, subfolder_lock); + + g_ptr_array_free(folder_uids, TRUE); + + return result; +} + +static void +vtrash_uid_removed(CamelVTrashFolder *vf, const char *uid, char hash[8]) +{ + char *vuid; + CamelVeeMessageInfo *vinfo; + + vuid = g_alloca(strlen(uid)+9); + memcpy(vuid, hash, 8); + strcpy(vuid+8, uid); + vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf)->summary, vuid); + if (vinfo) { + camel_folder_change_info_remove_uid(((CamelVeeFolder *)vf)->changes, vuid); + camel_folder_summary_remove(((CamelFolder *)vf)->summary, (CamelMessageInfo *)vinfo); + camel_message_info_free(vinfo); + } +} + +static void +vtrash_uid_added(CamelVTrashFolder *vf, const char *uid, CamelMessageInfo *info, char hash[8]) +{ + char *vuid; + CamelVeeMessageInfo *vinfo; + + vuid = g_alloca(strlen(uid)+9); + memcpy(vuid, hash, 8); + strcpy(vuid+8, uid); + vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)vf)->summary, vuid); + if (vinfo == NULL) { + camel_vee_summary_add((CamelVeeSummary *)((CamelFolder *)vf)->summary, info, hash); + camel_folder_change_info_add_uid(((CamelVeeFolder *)vf)->changes, vuid); + } else { + camel_folder_change_info_change_uid(((CamelVeeFolder *)vf)->changes, vuid); + camel_message_info_free(vinfo); + } +} + +static void +vtrash_folder_changed(CamelVeeFolder *vf, CamelFolder *sub, CamelFolderChangeInfo *changes) +{ + CamelMessageInfo *info; + char hash[8]; + CamelFolderChangeInfo *vf_changes = NULL; + int i; + + camel_vee_folder_hash_folder(sub, hash); + + CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); + + /* remove any removed that we also have */ + for (i=0;i<changes->uid_removed->len;i++) + vtrash_uid_removed((CamelVTrashFolder *)vf, (const char *)changes->uid_removed->pdata[i], hash); + + /* check any changed still deleted/junked */ + for (i=0;i<changes->uid_changed->len;i++) { + const char *uid = changes->uid_changed->pdata[i]; + + info = camel_folder_get_message_info(sub, uid); + if (info == NULL) + continue; + + if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit) == 0) + vtrash_uid_removed((CamelVTrashFolder *)vf, uid, hash); + else + vtrash_uid_added((CamelVTrashFolder *)vf, uid, info, hash); + + camel_message_info_free(info); + } + + /* add any new ones which are already matching */ + for (i=0;i<changes->uid_added->len;i++) { + const char *uid = changes->uid_added->pdata[i]; + + info = camel_folder_get_message_info(sub, uid); + if (info == NULL) + continue; + + if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit) != 0) + vtrash_uid_added((CamelVTrashFolder *)vf, uid, info, hash); + + camel_message_info_free(info); + } + + if (camel_folder_change_info_changed(((CamelVeeFolder *)vf)->changes)) { + vf_changes = ((CamelVeeFolder *)vf)->changes; + ((CamelVeeFolder *)vf)->changes = camel_folder_change_info_new(); + } + + CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock); + + if (vf_changes) { + camel_object_trigger_event(vf, "folder_changed", vf_changes); + camel_folder_change_info_free(vf_changes); + } +} + +static void +vtrash_add_folder(CamelVeeFolder *vf, CamelFolder *sub) +{ + GPtrArray *infos; + int i; + char hash[8]; + CamelFolderChangeInfo *vf_changes = NULL; + + camel_vee_folder_hash_folder(sub, hash); + + CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); + + infos = camel_folder_get_summary(sub); + for (i=0;i<infos->len;i++) { + CamelMessageInfo *info = infos->pdata[i]; + + if ((camel_message_info_flags(info) & ((CamelVTrashFolder *)vf)->bit)) + vtrash_uid_added((CamelVTrashFolder *)vf, camel_message_info_uid(info), info, hash); + } + camel_folder_free_summary(sub, infos); + + if (camel_folder_change_info_changed(vf->changes)) { + vf_changes = vf->changes; + vf->changes = camel_folder_change_info_new(); + } + + CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock); + + if (vf_changes) { + camel_object_trigger_event(vf, "folder_changed", vf_changes); + camel_folder_change_info_free(vf_changes); + } +} + +static void +vtrash_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) +{ + GPtrArray *infos; + int i; + char hash[8]; + CamelFolderChangeInfo *vf_changes = NULL; + CamelFolderSummary *ssummary = sub->summary; + int start, last; + + camel_vee_folder_hash_folder(sub, hash); + + CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); + + start = -1; + last = -1; + infos = camel_folder_get_summary(sub); + for (i=0;i<infos->len;i++) { + CamelVeeMessageInfo *mi = infos->pdata[i]; + + if (mi == NULL) + continue; + + if (mi->real->summary == ssummary) { + const char *uid = camel_message_info_uid(mi); + + camel_folder_change_info_remove_uid(vf->changes, uid); + + if (last == -1) { + last = start = i; + } else if (last+1 == i) { + last = i; + } else { + camel_folder_summary_remove_range(((CamelFolder *)vf)->summary, start, last); + i -= (last-start)+1; + start = last = i; + } + } + } + camel_folder_free_summary(sub, infos); + + if (last != -1) + camel_folder_summary_remove_range(((CamelFolder *)vf)->summary, start, last); + + if (camel_folder_change_info_changed(vf->changes)) { + vf_changes = vf->changes; + vf->changes = camel_folder_change_info_new(); + } + + CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock); + + if (vf_changes) { + camel_object_trigger_event(vf, "folder_changed", vf_changes); + camel_folder_change_info_free(vf_changes); + } +} + +static int +vtrash_rebuild_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex) +{ + /* we should always be in sync */ + return 0; +} + +static void +camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) +{ + CamelFolderClass *folder_class = (CamelFolderClass *) klass; + + camel_vtrash_folder_parent = CAMEL_VEE_FOLDER_CLASS(camel_vee_folder_get_type()); + + ((CamelObjectClass *)klass)->getv = vtrash_getv; + + folder_class->append_message = vtrash_append_message; + folder_class->transfer_messages_to = vtrash_transfer_messages_to; + folder_class->search_by_expression = vtrash_search_by_expression; + folder_class->search_by_uids = vtrash_search_by_uids; + + ((CamelVeeFolderClass *)klass)->add_folder = vtrash_add_folder; + ((CamelVeeFolderClass *)klass)->remove_folder = vtrash_remove_folder; + ((CamelVeeFolderClass *)klass)->rebuild_folder = vtrash_rebuild_folder; + + ((CamelVeeFolderClass *)klass)->folder_changed = vtrash_folder_changed; +} diff --git a/camel/providers/Makefile.am b/camel/providers/Makefile.am index 22ea481954..4ae70e9926 100644 --- a/camel/providers/Makefile.am +++ b/camel/providers/Makefile.am @@ -14,3 +14,4 @@ endif SUBDIRS = pop3 sendmail smtp imap $(NNTP_DIR) local $(IMAPP_DIR) $(IMAP4_DIR) groupwise + diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 6d6908e265..189844dfec 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -237,7 +237,7 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name, camel_folder_construct (folder, parent, folder_name, short_name); summary_file = g_strdup_printf ("%s/summary", folder_dir); - folder->summary = camel_imap_summary_new (summary_file); + folder->summary = camel_imap_summary_new (folder, summary_file); g_free (summary_file); if (!folder->summary) { camel_object_unref (CAMEL_OBJECT (folder)); @@ -387,7 +387,7 @@ camel_imap_folder_selected (CamelFolder *folder, CamelImapResponse *response, info = camel_folder_summary_index (folder->summary, count - 1); val = strtoul (camel_message_info_uid (info), NULL, 10); - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); if (uid == 0 || uid != val) imap_folder->need_rescan = TRUE; } @@ -575,7 +575,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex) ok = camel_imap_command_start (store, folder, ex, "UID FETCH 1:%s (FLAGS)", camel_message_info_uid (info)); - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); if (!ok) { camel_operation_end (NULL); return; @@ -632,7 +632,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex) iinfo = (CamelImapMessageInfo *)info; if (strcmp (camel_message_info_uid (info), new[i].uid) != 0) { - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); seq = i + 1; g_array_append_val (removed, seq); i--; @@ -646,8 +646,8 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex) server_set = new[i].flags & ~iinfo->server_flags; server_cleared = iinfo->server_flags & ~new[i].flags; - - info->flags = (info->flags | server_set) & ~server_cleared; + + iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared; iinfo->server_flags = new[i].flags; if (changes == NULL) @@ -655,7 +655,7 @@ imap_rescan (CamelFolder *folder, int exists, CamelException *ex) camel_folder_change_info_change_uid(changes, new[i].uid); } - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); g_free (new[i].uid); } @@ -697,7 +697,7 @@ static GPtrArray * get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set) { GPtrArray *matches; - CamelMessageInfo *info; + CamelImapMessageInfo *info; int i, max, range; GString *gset; @@ -706,11 +706,11 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, char **set) max = camel_folder_summary_count (folder->summary); range = -1; for (i = 0; i < max && !UID_SET_FULL (gset->len, UID_SET_LIMIT); i++) { - info = camel_folder_summary_index (folder->summary, i); + info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i); if (!info) continue; - if ((info->flags & mask) != flags) { - camel_folder_summary_info_free (folder->summary, info); + if ((info->info.flags & mask) != flags) { + camel_message_info_free((CamelMessageInfo *)info); if (range != -1) { if (range != i - 1) { info = matches->pdata[matches->len - 1]; @@ -758,7 +758,7 @@ imap_sync_online (CamelFolder *folder, CamelException *ex) { CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); CamelImapResponse *response = NULL; - CamelMessageInfo *info; + CamelImapMessageInfo *info; CamelException local_ex; GPtrArray *matches; char *set, *flaglist; @@ -779,33 +779,33 @@ imap_sync_online (CamelFolder *folder, CamelException *ex) */ max = camel_folder_summary_count (folder->summary); for (i = 0; i < max; i++) { - if (!(info = camel_folder_summary_index (folder->summary, i))) + if (!(info = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, i))) continue; - if (!(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) { - camel_folder_summary_info_free (folder->summary, info); + if (!(info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) { + camel_message_info_free((CamelMessageInfo *)info); continue; } /* Note: Cyrus is broken and will not accept an empty-set of flags so... if this is true then we want to unset the previously set flags.*/ - unset = !(info->flags & folder->permanent_flags); + unset = !(info->info.flags & folder->permanent_flags); /* Note: get_matching() uses UID_SET_LIMIT to limit the size of the uid-set string. We don't have to loop here to flush all the matching uids because they will be scooped up later by our parent loop (I think?). -- Jeff */ - matches = get_matching (folder, info->flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED), + matches = get_matching (folder, info->info.flags & (folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED), folder->permanent_flags | CAMEL_MESSAGE_FOLDER_FLAGGED, &set); - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); if (matches == NULL) continue; /* FIXME: since we don't know the previously set flags, if unset is TRUE then just unset all the flags? */ - flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->flags & folder->permanent_flags); + flaglist = imap_create_flag_list (unset ? folder->permanent_flags : info->info.flags & folder->permanent_flags); /* Note: to `unset' flags, use -FLAGS.SILENT (<flag list>) */ response = camel_imap_command (store, folder, &local_ex, @@ -820,16 +820,15 @@ imap_sync_online (CamelFolder *folder, CamelException *ex) if (!camel_exception_is_set (&local_ex)) { for (j = 0; j < matches->len; j++) { info = matches->pdata[j]; - info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; - ((CamelImapMessageInfo *) info)->server_flags = - info->flags & CAMEL_IMAP_SERVER_FLAGS; + info->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; + ((CamelImapMessageInfo *) info)->server_flags = info->info.flags & CAMEL_IMAP_SERVER_FLAGS; } camel_folder_summary_touch (folder->summary); } for (j = 0; j < matches->len; j++) { info = matches->pdata[j]; - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(&info->info); } g_ptr_array_free (matches, TRUE); @@ -1167,10 +1166,11 @@ do_append (CamelFolder *folder, CamelMimeMessage *message, CamelStreamFilter *streamfilter; GByteArray *ba; char *flagstr, *end; - - /* create flag string param */ - if (info && info->flags) - flagstr = imap_create_flag_list (info->flags); + guint32 flags; + + flags = camel_message_info_flags(info); + if (flags) + flagstr = imap_create_flag_list (flags); else flagstr = NULL; @@ -1357,7 +1357,7 @@ imap_transfer_offline (CamelFolder *source, GPtrArray *uids, camel_imap_summary_add_offline_uncached (dest->summary, destuid, mi); camel_imap_message_cache_copy (sc, uid, dc, destuid, ex); - camel_folder_summary_info_free (source->summary, mi); + camel_message_info_free(mi); camel_folder_change_info_add_uid (changes, destuid); if (transferred_uids) @@ -1968,12 +1968,12 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - CamelMessageInfo *mi; + CamelImapMessageInfo *mi; CamelMimeMessage *msg = NULL; CamelStream *stream = NULL; int retry; - mi = camel_folder_summary_uid (folder->summary, uid); + mi = (CamelImapMessageInfo *)camel_folder_summary_uid (folder->summary, uid); if (mi == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("Cannot get message: %s\n %s"), uid, _("No such message")); @@ -2001,11 +2001,11 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) /* If the message is small or only 1 part, or server doesn't do 4v1 (properly) fetch it in one piece. */ if (store->server_level < IMAP_LEVEL_IMAP4REV1 || store->braindamaged - || mi->size < IMAP_SMALL_BODY_SIZE - || (!content_info_incomplete(mi->content) && !mi->content->childs)) { + || mi->info.size < IMAP_SMALL_BODY_SIZE + || (!content_info_incomplete(mi->info.content) && !mi->info.content->childs)) { msg = get_message_simple (imap_folder, uid, NULL, ex); } else { - if (content_info_incomplete (mi->content)) { + if (content_info_incomplete (mi->info.content)) { /* For larger messages, fetch the structure and build a message * with offline parts. (We check mi->content->type rather than * mi->content because camel_folder_summary_info_new always creates @@ -2038,7 +2038,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) } if (body) - imap_parse_body ((const char **) &body, folder, mi->content); + imap_parse_body ((const char **) &body, folder, mi->info.content); if (fetch_data) g_datalist_clear (&fetch_data); @@ -2049,7 +2049,7 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) if (camel_debug_start("imap:folder")) { printf("Folder get message '%s' folder info ->\n", uid); - camel_message_info_dump(mi); + camel_message_info_dump((CamelMessageInfo *)mi); camel_debug_end(); } @@ -2059,10 +2059,10 @@ imap_get_message (CamelFolder *folder, const char *uid, CamelException *ex) * fall back to fetching the entire thing and * let the mailer's "bad MIME" code handle it. */ - if (content_info_incomplete (mi->content)) + if (content_info_incomplete (mi->info.content)) msg = get_message_simple (imap_folder, uid, NULL, ex); else - msg = get_message (imap_folder, uid, mi->content, ex); + msg = get_message (imap_folder, uid, mi->info.content, ex); } } while (msg == NULL && retry < 2 @@ -2072,7 +2072,7 @@ done: /* FIXME, this shouldn't be done this way. */ if (msg) camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url); fail: - camel_folder_summary_info_free (folder->summary, mi); + camel_message_info_free(&mi->info); return msg; } @@ -2201,7 +2201,7 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages, { CamelMimeMessage *msg; CamelStream *stream; - CamelMessageInfo *mi; + CamelImapMessageInfo *mi; const char *idate; int seq; @@ -2221,14 +2221,14 @@ add_message_from_data (CamelFolder *folder, GPtrArray *messages, return; } - mi = camel_folder_summary_info_new_from_message (folder->summary, msg); + mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg); camel_object_unref (CAMEL_OBJECT (msg)); if ((idate = g_datalist_get_data (&data, "INTERNALDATE"))) - mi->date_received = decode_internaldate (idate); + mi->info.date_received = decode_internaldate (idate); - if (mi->date_received == -1) - mi->date_received = mi->date_sent; + if (mi->info.date_received == -1) + mi->info.date_received = mi->info.date_sent; messages->pdata[seq - first] = mi; } @@ -2253,7 +2253,7 @@ imap_update_summary (CamelFolder *folder, int exists, int i, seq, first, size, got; CamelImapResponseType type; const char *header_spec; - CamelMessageInfo *mi, *info; + CamelImapMessageInfo *mi, *info; CamelStream *stream; char *uid, *resp; GData *data; @@ -2272,9 +2272,9 @@ imap_update_summary (CamelFolder *folder, int exists, seq = camel_folder_summary_count (folder->summary); first = seq + 1; if (seq > 0) { - mi = camel_folder_summary_index (folder->summary, seq - 1); + mi = (CamelImapMessageInfo *)camel_folder_summary_index (folder->summary, seq - 1); uidval = strtoul(camel_message_info_uid (mi), NULL, 10); - camel_folder_summary_info_free (folder->summary, mi); + camel_message_info_free(&mi->info); } else uidval = 0; @@ -2433,24 +2433,23 @@ imap_update_summary (CamelFolder *folder, int exists, continue; } - mi = camel_message_info_new (); - camel_message_info_dup_to (pmi, mi); + mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi); } uid = g_datalist_get_data (&data, "UID"); if (uid) - camel_message_info_set_uid (mi, g_strdup (uid)); + mi->info.uid = g_strdup (uid); flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS")); if (flags) { ((CamelImapMessageInfo *)mi)->server_flags = flags; /* "or" them in with the existing flags that may * have been set by summary_info_new_from_message. */ - mi->flags |= flags; + mi->info.flags |= flags; } size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE")); if (size) - mi->size = size; + mi->info.size = size; g_datalist_clear (&data); } @@ -2474,7 +2473,7 @@ imap_update_summary (CamelFolder *folder, int exists, i + first); break; } - info = camel_folder_summary_uid(folder->summary, uid); + info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid); if (info) { for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) { if (folder->summary->messages->pdata[seq] == info) @@ -2486,20 +2485,20 @@ imap_update_summary (CamelFolder *folder, int exists, _("Unexpected server response: Identical UIDs provided for messages %d and %d"), seq + 1, i + first); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(&info->info); break; } - camel_folder_summary_add (folder->summary, mi); + camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi); camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi)); - if ((mi->flags & CAMEL_IMAP_MESSAGE_RECENT)) + if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT)) camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi)); } for ( ; i < messages->len; i++) { if ((mi = messages->pdata[i])) - camel_folder_summary_info_free(folder->summary, mi); + camel_message_info_free(&mi->info); } g_ptr_array_free (messages, TRUE); @@ -2517,7 +2516,7 @@ imap_update_summary (CamelFolder *folder, int exists, if (messages) { for (i = 0; i < messages->len; i++) { if (messages->pdata[i]) - camel_folder_summary_info_free (folder->summary, messages->pdata[i]); + camel_message_info_free(messages->pdata[i]); } g_ptr_array_free (messages, TRUE); } @@ -2553,7 +2552,7 @@ camel_imap_folder_changed (CamelFolder *folder, int exists, camel_imap_message_cache_remove (imap_folder->cache, camel_message_info_uid (info)); CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock); camel_folder_summary_remove (folder->summary, info); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); } } diff --git a/camel/providers/imap/camel-imap-message-cache.c b/camel/providers/imap/camel-imap-message-cache.c index 17fa9ca5c8..3099602613 100644 --- a/camel/providers/imap/camel-imap-message-cache.c +++ b/camel/providers/imap/camel-imap-message-cache.c @@ -176,7 +176,7 @@ camel_imap_message_cache_new (const char *path, CamelFolderSummary *summary, info = camel_folder_summary_uid (summary, uid); if (info) { - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); cache_put (cache, uid, d->d_name, NULL); } else g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, d->d_name)); diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index b22743e72a..a2ecb71b91 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -1047,7 +1047,7 @@ imap_forget_folder (CamelImapStore *imap_store, const char *folder_name, CamelEx } summary_file = g_strdup_printf ("%s/summary", folder_dir); - summary = camel_imap_summary_new (summary_file); + summary = camel_imap_summary_new (NULL, summary_file); if (!summary) { g_free (summary_file); g_free (folder_dir); @@ -1597,14 +1597,17 @@ imap_disconnect_online (CamelService *service, gboolean clean, CamelException *e static gboolean imap_summary_is_dirty (CamelFolderSummary *summary) { - CamelMessageInfo *info; + CamelImapMessageInfo *info; int max, i; - + int found = FALSE; + max = camel_folder_summary_count (summary); - for (i = 0; i < max; i++) { - info = camel_folder_summary_index (summary, i); - if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) - return TRUE; + for (i = 0; i < max && !found; i++) { + info = (CamelImapMessageInfo *)camel_folder_summary_index (summary, i); + if (info) { + found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED; + camel_message_info_free(info); + } } return FALSE; diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c index 6251f8b85b..3e1d024ab4 100644 --- a/camel/providers/imap/camel-imap-summary.c +++ b/camel/providers/imap/camel-imap-summary.c @@ -71,6 +71,21 @@ camel_imap_summary_get_type (void) return type; } +static CamelMessageInfo * +imap_message_info_clone(CamelFolderSummary *s, const CamelMessageInfo *mi) +{ + CamelImapMessageInfo *to; + const CamelImapMessageInfo *from = (const CamelImapMessageInfo *)mi; + + to = (CamelImapMessageInfo *)camel_imap_summary_parent->message_info_clone(s, mi); + to->server_flags = from->server_flags; + + /* FIXME: parent clone should do this */ + to->info.content = camel_folder_summary_content_info_new(s); + + return (CamelMessageInfo *)to; +} + static void camel_imap_summary_class_init (CamelImapSummaryClass *klass) { @@ -78,6 +93,8 @@ camel_imap_summary_class_init (CamelImapSummaryClass *klass) camel_imap_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS (camel_type_get_global_classfuncs (camel_folder_summary_get_type())); + cfs_class->message_info_clone = imap_message_info_clone; + cfs_class->summary_header_load = summary_header_load; cfs_class->summary_header_save = summary_header_save; cfs_class->message_info_load = message_info_load; @@ -98,6 +115,7 @@ camel_imap_summary_init (CamelImapSummary *obj) /** * camel_imap_summary_new: + * @folder: Parent folder. * @filename: the file to store the summary in. * * This will create a new CamelImapSummary object and read in the @@ -106,10 +124,11 @@ camel_imap_summary_init (CamelImapSummary *obj) * Return value: A new CamelImapSummary object. **/ CamelFolderSummary * -camel_imap_summary_new (const char *filename) +camel_imap_summary_new (struct _CamelFolder *folder, const char *filename) { - CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY ( - camel_object_new (camel_imap_summary_get_type ())); + CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (camel_object_new (camel_imap_summary_get_type ())); + + summary->folder = folder; camel_folder_summary_set_build_content (summary, TRUE); camel_folder_summary_set_filename (summary, filename); @@ -177,7 +196,7 @@ message_info_load (CamelFolderSummary *s, FILE *in) return info; error: - camel_folder_summary_info_free (s, info); + camel_message_info_free(info); return NULL; } @@ -218,52 +237,40 @@ camel_imap_summary_add_offline (CamelFolderSummary *summary, const char *uid, CamelMimeMessage *message, const CamelMessageInfo *info) { - CamelMessageInfo *mi; - CamelFlag *flag; - CamelTag *tag; + CamelImapMessageInfo *mi; + const CamelFlag *flag; + const CamelTag *tag; /* Create summary entry */ - mi = camel_folder_summary_info_new_from_message (summary, message); + mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (summary, message); /* Copy flags 'n' tags */ - mi->flags = info->flags; - flag = info->user_flags; + mi->info.flags = camel_message_info_flags(info); + + flag = camel_message_info_user_flags(info); while (flag) { - camel_flag_set (&mi->user_flags, flag->name, TRUE); + camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE); flag = flag->next; } - tag = info->user_tags; + tag = camel_message_info_user_tags(info); while (tag) { - camel_tag_set (&mi->user_tags, tag->name, tag->value); + camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value); tag = tag->next; } - mi->size = info->size; + mi->info.size = camel_message_info_size(info); + mi->info.uid = g_strdup (uid); - /* Set uid and add to summary */ - camel_message_info_set_uid (mi, g_strdup (uid)); - camel_folder_summary_add (summary, mi); + camel_folder_summary_add (summary, (CamelMessageInfo *)mi); } void camel_imap_summary_add_offline_uncached (CamelFolderSummary *summary, const char *uid, const CamelMessageInfo *info) { - CamelMessageInfo *mi; - CamelMessageContentInfo *ci; - - /* Create summary entry */ - mi = camel_folder_summary_info_new (summary); - ci = camel_folder_summary_content_info_new (summary); - - camel_message_info_dup_to (info, mi); - mi->content = ci; - - /* copy our private fields */ - ((CamelImapMessageInfo *)mi)->server_flags = - ((CamelImapMessageInfo *)info)->server_flags; + CamelImapMessageInfo *mi; - /* Set uid and add to summary */ - camel_message_info_set_uid (mi, g_strdup (uid)); - camel_folder_summary_add (summary, mi); + mi = camel_message_info_clone(info); + mi->info.uid = g_strdup(uid); + camel_folder_summary_add (summary, (CamelMessageInfo *)mi); } diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h index e7402aac84..04fb9b829a 100644 --- a/camel/providers/imap/camel-imap-summary.h +++ b/camel/providers/imap/camel-imap-summary.h @@ -47,7 +47,7 @@ typedef struct _CamelImapMessageContentInfo { } CamelImapMessageContentInfo; typedef struct _CamelImapMessageInfo { - CamelMessageInfo info; + CamelMessageInfoBase info; guint32 server_flags; } CamelImapMessageInfo; @@ -65,7 +65,7 @@ struct _CamelImapSummaryClass { }; CamelType camel_imap_summary_get_type (void); -CamelFolderSummary *camel_imap_summary_new (const char *filename); +CamelFolderSummary *camel_imap_summary_new (struct _CamelFolder *folder, const char *filename); void camel_imap_summary_add_offline (CamelFolderSummary *summary, const char *uid, diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index ca94c180ec..a557f7fcae 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -1061,7 +1061,7 @@ get_summary_uid_numeric (CamelFolderSummary *summary, int index) info = camel_folder_summary_index (summary, index); uid = strtoul (camel_message_info_uid (info), NULL, 10); - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); return uid; } diff --git a/camel/providers/imap4/camel-imap4-folder.c b/camel/providers/imap4/camel-imap4-folder.c index 7ee109a5b4..921d7aa2ed 100644 --- a/camel/providers/imap4/camel-imap4-folder.c +++ b/camel/providers/imap4/camel-imap4-folder.c @@ -459,7 +459,7 @@ imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex) for (j = 0; j < sync->len; j++) { iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[j]); - camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags); + camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags); if (diff.changed & imap4_flags[i].flag) { if (diff.bits & imap4_flags[i].flag) { g_ptr_array_add (on_set, info); @@ -492,8 +492,8 @@ imap4_sync_changes (CamelFolder *folder, GPtrArray *sync, CamelException *ex) for (i = 0; i < sync->len; i++) { iinfo = (CamelIMAP4MessageInfo *) (info = sync->pdata[i]); - info->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; - iinfo->server_flags = info->flags & folder->permanent_flags; + iinfo->info.flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; + iinfo->server_flags = iinfo->info.flags & folder->permanent_flags; } return 0; @@ -522,17 +522,17 @@ imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) max = camel_folder_summary_count (folder->summary); for (i = 0; i < max; i++) { iinfo = (CamelIMAP4MessageInfo *) (info = camel_folder_summary_index (folder->summary, i)); - if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) { - camel_imap4_flags_diff (&diff, iinfo->server_flags, info->flags); + if (iinfo->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) { + camel_imap4_flags_diff (&diff, iinfo->server_flags, iinfo->info.flags); diff.changed &= folder->permanent_flags; /* weed out flag changes that we can't sync to the server */ if (!diff.changed) - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); else g_ptr_array_add (sync, info); } else { - camel_folder_summary_info_free (folder->summary, info); + camel_message_info_free(info); } } @@ -540,7 +540,7 @@ imap4_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) retval = imap4_sync_changes (folder, sync, ex); for (i = 0; i < sync->len; i++) - camel_folder_summary_info_free (folder->summary, sync->pdata[i]); + camel_message_info_free(sync->pdata[i]); g_ptr_array_free (sync, TRUE); @@ -695,7 +695,7 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, if ((info = camel_folder_summary_index (summary, index - 1))) { iinfo = (CamelIMAP4MessageInfo *) info; - info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, flags); + iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, flags); iinfo->server_flags = flags; changes = camel_folder_change_info_new (); @@ -703,7 +703,7 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_object_trigger_event (engine->folder, "folder_changed", changes); camel_folder_change_info_free (changes); - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); } } else { /* wtf? */ @@ -856,6 +856,7 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelIMAP4Engine *engine = ((CamelIMAP4Store *) folder->parent_store)->engine; CamelSession *session = ((CamelService *) folder->parent_store)->session; CamelIMAP4Summary *summary = (CamelIMAP4Summary *) folder->summary; + const CamelIMAP4MessageInfo *iinfo = (const CamelIMAP4MessageInfo *)info; CamelIMAP4RespCode *resp; CamelIMAP4Command *ic; CamelFolderInfo *fi; @@ -873,11 +874,11 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message, CAMEL_SERVICE_LOCK (folder->parent_store, connect_lock); /* construct the option flags list */ - if (info->flags & folder->permanent_flags) { + if (iinfo->info.flags & folder->permanent_flags) { p = g_stpcpy (flags, " ("); for (i = 0; i < G_N_ELEMENTS (imap4_flags); i++) { - if ((info->flags & imap4_flags[i].flag) & folder->permanent_flags) { + if ((iinfo->info.flags & imap4_flags[i].flag) & folder->permanent_flags) { p = g_stpcpy (p, imap4_flags[i].name); *p++ = ' '; } @@ -890,13 +891,13 @@ imap4_append_message (CamelFolder *folder, CamelMimeMessage *message, } /* construct the optional date_time string */ - if (info->date_received != (time_t) -1) { + if (iinfo->info.date_received != (time_t) -1) { int tzone; #ifdef HAVE_LOCALTIME_R localtime_r (&info->date_received, &tm); #else - memcpy (&tm, localtime (&info->date_received), sizeof (tm)); + memcpy (&tm, localtime (&iinfo->info.date_received), sizeof (tm)); #endif #if defined (HAVE_TM_GMTOFF) @@ -1118,7 +1119,7 @@ imap4_transfer_messages_to (CamelFolder *src, GPtrArray *uids, CamelFolder *dest done: for (i = 0; i < infos->len; i++) - camel_folder_summary_info_free (src->summary, infos->pdata[i]); + camel_message_info_free(infos->pdata[i]); g_ptr_array_free (infos, TRUE); CAMEL_SERVICE_LOCK (src->parent_store, connect_lock); diff --git a/camel/providers/imap4/camel-imap4-search.c b/camel/providers/imap4/camel-imap4-search.c index f7cb5acb99..7102e2fa0f 100644 --- a/camel/providers/imap4/camel-imap4-search.c +++ b/camel/providers/imap4/camel-imap4-search.c @@ -123,7 +123,7 @@ untagged_search (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, sprintf (uid, "%u", token->v.number); if ((info = camel_folder_summary_uid (summary, uid))) { g_ptr_array_add (matches, (char *) camel_message_info_uid (info)); - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); } } diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c index 4d2395b049..c8832b54a6 100644 --- a/camel/providers/imap4/camel-imap4-store.c +++ b/camel/providers/imap4/camel-imap4-store.c @@ -1112,28 +1112,12 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr fi->flags = list->flags; fi->unread = -1; fi->total = -1; - - if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) { - if (folder && !strcmp (folder->full_name, fi->full_name)) { - /* can't STATUS this folder since it is SELECTED, besides - it would be wasteful */ - CamelMessageInfo *info; - int index; - - fi->total = camel_folder_summary_count (folder->summary); - - fi->unread = 0; - for (index = 0; index < fi->total; index++) { - if (!(info = camel_folder_summary_index (folder->summary, index))) - continue; - - if ((info->flags & CAMEL_MESSAGE_SEEN) == 0) - fi->unread++; - - camel_folder_summary_info_free (folder->summary, info); - } - } else { - imap4_status (store, fi); - } + + /* SELECTED folder, just get it from the folder */ + if (folder && !strcmp (folder->full_name, fi->full_name)) { + camel_object_get(folder, NULL, CAMEL_FOLDER_TOTAL, &fi->total, CAMEL_FOLDER_UNREAD, &fi->unread, 0); + } else if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST)) { + imap4_status (store, fi); } g_free (list->name); diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c index ef3e7e3bbc..ce31d87181 100644 --- a/camel/providers/imap4/camel-imap4-summary.c +++ b/camel/providers/imap4/camel-imap4-summary.c @@ -36,6 +36,7 @@ #include <e-util/md5-utils.h> #include <camel/camel-file-utils.h> +#include <camel/camel-string-utils.h> #include <camel/camel-i18n.h> #include "camel-imap4-store.h" @@ -57,7 +58,7 @@ static void camel_imap4_summary_finalize (CamelObject *object); static int imap4_header_load (CamelFolderSummary *summary, FILE *fin); static int imap4_header_save (CamelFolderSummary *summary, FILE *fout); -static CamelMessageInfo *imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header); +static CamelMessageInfo *imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header); static CamelMessageInfo *imap4_message_info_load (CamelFolderSummary *summary, FILE *fin); static int imap4_message_info_save (CamelFolderSummary *summary, FILE *fout, CamelMessageInfo *info); @@ -94,7 +95,7 @@ camel_imap4_summary_class_init (CamelIMAP4SummaryClass *klass) summary_class->summary_header_load = imap4_header_load; summary_class->summary_header_save = imap4_header_save; - summary_class->message_info_new = imap4_message_info_new; + summary_class->message_info_new_from_header = imap4_message_info_new_from_header; summary_class->message_info_load = imap4_message_info_load; summary_class->message_info_save = imap4_message_info_save; } @@ -430,7 +431,8 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t { unsigned char md5sum[16]; char *nstring; - + CamelIMAP4MessageInfo *iinfo = (CamelIMAP4MessageInfo *)info; + if (camel_imap4_engine_next_token (engine, token, ex) == -1) return -1; @@ -439,18 +441,20 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t return -1; } - if (envelope_decode_date (engine, &info->date_sent, ex) == -1) + if (envelope_decode_date (engine, &iinfo->info.date_sent, ex) == -1) goto exception; /* subject */ if (envelope_decode_nstring (engine, &nstring, TRUE, ex) == -1) goto exception; - camel_message_info_set_subject (info, nstring); + iinfo->info.subject = camel_pstring_strdup(nstring); + g_free(nstring); /* from */ if (envelope_decode_addresses (engine, &nstring, ex) == -1) goto exception; - camel_message_info_set_from (info, nstring); + iinfo->info.from = camel_pstring_strdup(nstring); + g_free(nstring); /* sender */ if (envelope_decode_addresses (engine, &nstring, ex) == -1) @@ -465,12 +469,14 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t /* to */ if (envelope_decode_addresses (engine, &nstring, ex) == -1) goto exception; - camel_message_info_set_to (info, nstring); + iinfo->info.to = camel_pstring_strdup(nstring); + g_free(nstring); /* cc */ if (envelope_decode_addresses (engine, &nstring, ex) == -1) goto exception; - camel_message_info_set_cc (info, nstring); + iinfo->info.cc = camel_pstring_strdup(nstring); + g_free(nstring); /* bcc */ if (envelope_decode_addresses (engine, &nstring, ex) == -1) @@ -482,7 +488,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t goto exception; if (nstring != NULL) { - info->references = decode_references (nstring); + iinfo->info.references = decode_references (nstring); g_free (nstring); } @@ -492,7 +498,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t if (nstring != NULL) { md5_get_digest (nstring, strlen (nstring), md5sum); - memcpy (info->message_id.id.hash, md5sum, sizeof (info->message_id.id.hash)); + memcpy (iinfo->info.message_id.id.hash, md5sum, sizeof (iinfo->info.message_id.id.hash)); g_free (nstring); } @@ -666,7 +672,7 @@ imap4_fetch_all_free (struct imap4_fetch_all_t *fetch) if (!(envelope = fetch->added->pdata[i])) continue; - camel_folder_summary_info_free (fetch->summary, envelope->info); + camel_message_info_free(envelope->info); g_free (envelope); } @@ -714,13 +720,13 @@ imap4_fetch_all_add (struct imap4_fetch_all_t *fetch) if (envelope->changed != IMAP4_FETCH_ALL) { d(fprintf (stderr, "Hmmm, IMAP4 server didn't give us everything for message %d\n", i + 1)); - camel_folder_summary_info_free (fetch->summary, envelope->info); + camel_message_info_free(envelope->info); g_free (envelope); continue; } if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (envelope->info)))) { - camel_folder_summary_info_free (fetch->summary, envelope->info); + camel_message_info_free(envelope->info); g_free (envelope); continue; } @@ -769,14 +775,14 @@ imap4_fetch_all_update (struct imap4_fetch_all_t *fetch) new_iinfo = (CamelIMAP4MessageInfo *) envelope->info; iinfo = (CamelIMAP4MessageInfo *) info; - flags = info->flags; - info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, new_iinfo->server_flags); + flags = iinfo->info.flags; + iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, new_iinfo->server_flags); iinfo->server_flags = new_iinfo->server_flags; - if (info->flags != flags) + if (iinfo->info.flags != flags) camel_folder_change_info_change_uid (changes, camel_message_info_uid (info)); } - camel_folder_summary_info_free (fetch->summary, info); + camel_message_info_free(info); } for (i = 0; i < fetch->added->len; i++) { @@ -788,13 +794,13 @@ imap4_fetch_all_update (struct imap4_fetch_all_t *fetch) info = envelope->info; if (!first && camel_message_info_uid (info)) { if ((info = camel_folder_summary_uid (fetch->summary, camel_message_info_uid (info)))) { - camel_folder_summary_info_free (fetch->summary, info); + camel_message_info_free(info); } else { first = i + fetch->first; } } - camel_folder_summary_info_free (fetch->summary, envelope->info); + camel_message_info_free(envelope->info); g_free (envelope); } @@ -835,7 +841,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind g_ptr_array_set_size (added, index - fetch->first + 1); if (!(envelope = added->pdata[index - fetch->first])) { - iinfo = (CamelIMAP4MessageInfo *) (info = camel_folder_summary_info_new (summary)); + iinfo = (CamelIMAP4MessageInfo *) (info = camel_message_info_new (summary)); envelope = g_new (struct imap4_envelope_t, 1); added->pdata[index - fetch->first] = envelope; envelope->info = info; @@ -876,9 +882,9 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind g_warning ("Hmmm, server is sending us ENVELOPE data for a message we didn't ask for (message %u)\n", index); - tmp = camel_folder_summary_info_new (summary); + tmp = camel_message_info_new (summary); rv = decode_envelope (engine, tmp, token, ex); - camel_folder_summary_info_free (summary, tmp); + camel_message_info_free(tmp); if (rv == -1) goto exception; @@ -889,7 +895,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind if (camel_imap4_parse_flags_list (engine, &server_flags, ex) == -1) return -1; - info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, server_flags); + iinfo->info.flags = camel_imap4_merge_flags (iinfo->server_flags, iinfo->info.flags, server_flags); iinfo->server_flags = server_flags; changed |= IMAP4_FETCH_FLAGS; @@ -899,11 +905,11 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind switch (token->token) { case CAMEL_IMAP4_TOKEN_NIL: - info->date_received = (time_t) -1; + iinfo->info.date_received = (time_t) -1; break; case CAMEL_IMAP4_TOKEN_ATOM: case CAMEL_IMAP4_TOKEN_QSTRING: - info->date_received = decode_internaldate (token->v.qstring); + iinfo->info.date_received = decode_internaldate (token->v.qstring); break; default: goto unexpected; @@ -917,7 +923,7 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind if (token->token != CAMEL_IMAP4_TOKEN_NUMBER) goto unexpected; - info->size = token->v.number; + iinfo->info.size = token->v.number; changed |= IMAP4_FETCH_RFC822SIZE; } else if (!strcmp (token->v.atom, "UID")) { @@ -935,7 +941,8 @@ untagged_fetch_all (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 ind g_assert_not_reached (); } } else { - camel_message_info_set_uid (info, g_strdup (uid)); + g_free(info->uid); + info->uid = g_strdup (uid); g_hash_table_insert (fetch->uid_hash, (void *) camel_message_info_uid (info), envelope); changed |= IMAP4_FETCH_UID; } @@ -1071,11 +1078,11 @@ imap4_build_summary (CamelFolderSummary *summary, guint32 first, guint32 last) #endif static CamelMessageInfo * -imap4_message_info_new (CamelFolderSummary *summary, struct _camel_header_raw *header) +imap4_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header) { CamelMessageInfo *info; - info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new (summary, header); + info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_new_from_header (summary, header); ((CamelIMAP4MessageInfo *) info)->server_flags = 0; @@ -1100,7 +1107,7 @@ imap4_message_info_load (CamelFolderSummary *summary, FILE *fin) exception: - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); return NULL; } @@ -1178,7 +1185,7 @@ camel_imap4_summary_set_uidvalidity (CamelFolderSummary *summary, guint32 uidval continue; camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info)); - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); } camel_folder_summary_clear (summary); @@ -1215,7 +1222,7 @@ camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid) changes = camel_folder_change_info_new (); camel_folder_change_info_remove_uid (changes, uid); - camel_folder_summary_info_free (summary, info); + camel_message_info_free(info); camel_folder_summary_remove_index (summary, seqid); camel_object_trigger_event (imap4_summary->folder, "folder_changed", changes); diff --git a/camel/providers/imap4/camel-imap4-summary.h b/camel/providers/imap4/camel-imap4-summary.h index 7de05a5cc6..9af962115b 100644 --- a/camel/providers/imap4/camel-imap4-summary.h +++ b/camel/providers/imap4/camel-imap4-summary.h @@ -45,7 +45,7 @@ typedef struct _CamelIMAP4SummaryClass CamelIMAP4SummaryClass; #define CAMEL_IMAP4_MESSAGE_RECENT (1 << 17) struct _CamelIMAP4MessageInfo { - CamelMessageInfo parent_info; + CamelMessageInfoBase info; guint32 server_flags; }; diff --git a/camel/providers/imapp/ChangeLog b/camel/providers/imapp/ChangeLog index 9c70d8d7b9..63b46ae57a 100644 --- a/camel/providers/imapp/ChangeLog +++ b/camel/providers/imapp/ChangeLog @@ -1,3 +1,7 @@ +2004-11-11 Not Zed <NotZed@Ximian.com> + + * updates for camel folder summary api changes. + 2004-09-30 Not Zed <NotZed@Ximian.com> * camel-imapp-engine.c: make the build again, warnings, doesn't diff --git a/camel/providers/imapp/camel-imapp-driver.c b/camel/providers/imapp/camel-imapp-driver.c index aa1f2a273e..c9a9e45042 100644 --- a/camel/providers/imapp/camel-imapp-driver.c +++ b/camel/providers/imapp/camel-imapp-driver.c @@ -332,7 +332,7 @@ imapp_write_flags(CamelIMAPPDriver *id, guint32 orset, gboolean on, CamelFolderS ic = camel_imapp_engine_command_new(id->engine, "STORE", NULL, "UID STORE "); flush = imapp_uidset_add(&ss, ic, camel_message_info_uid(info)); } - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); } if (i == count-1 && ic != NULL) @@ -391,7 +391,7 @@ camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder off_orset |= ( flags ^ sflags ) & ~flags; on_orset |= (flags ^ sflags) & flags; } - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); } if (on_orset || off_orset) { @@ -407,7 +407,7 @@ camel_imapp_driver_sync(CamelIMAPPDriver *id, gboolean expunge, CamelIMAPPFolder if (info == NULL) continue; info->server_flags = info->info.flags & CAMEL_IMAPP_SERVER_FLAGS; - camel_folder_summary_info_free(summary, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); } camel_folder_summary_touch(summary); /* could save summary here, incase of failure? */ @@ -656,7 +656,7 @@ driver_resp_expunge(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) if (info) { printf("expunging msg %d\n", id); camel_folder_summary_remove(summary, info); - camel_folder_summary_info_free(summary, info); + camel_message_info_free(info); camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info)); } else { printf("can not find msg %u from expunge\n", id); @@ -670,7 +670,7 @@ static int driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) { struct _fetch_info *finfo = NULL; - CamelMessageInfo *info, *uinfo; + CamelIMAPPMessageInfo *info, *uinfo; unsigned int i; CamelFolderSummary *summary; @@ -684,36 +684,36 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) finfo = imap_parse_fetch(ie->stream); imap_dump_fetch(finfo); - info = camel_folder_summary_index(summary, id-1); + info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1); if (info == NULL) { if (finfo->uid == NULL) { printf("got fetch response for currently unknown message %u\n", id); goto done; } - uinfo = camel_folder_summary_uid(summary, finfo->uid); + uinfo = (CamelIMAPPMessageInfo *)camel_folder_summary_uid(summary, finfo->uid); if (uinfo) { /* we have a problem ... index mismatch */ printf("index mismatch, uid '%s' not at index '%u'\n", finfo->uid, id); - camel_folder_summary_info_free(summary, uinfo); + camel_message_info_free(uinfo); } /* pad out the summary till we have enough indexes */ for (i=camel_folder_summary_count(summary);i<id;i++) { - info = camel_folder_summary_info_new(summary); + info = camel_message_info_new(summary); if (i == id-1) { printf("inserting new info @ %u\n", i); - camel_message_info_set_uid(info, g_strdup(finfo->uid)); + info->info.uid = g_strdup(finfo->uid); } else { char uidtmp[32]; sprintf(uidtmp, "blank-%u", i); - camel_message_info_set_uid(info, g_strdup(uidtmp)); + info->info.uid = g_strdup(uidtmp); printf("inserting empty uid %s\n", uidtmp); } - camel_folder_summary_add(summary, info); + camel_folder_summary_add(summary, (CamelMessageInfo *)info); } - info = camel_folder_summary_index(summary, id-1); + info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1); g_assert(info != NULL); } else { if (finfo->uid) { @@ -723,9 +723,9 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) finfo->uid, id, camel_message_info_uid(info)); camel_folder_change_info_remove_uid(sdata->folder->changes, camel_message_info_uid(info)); - camel_folder_summary_remove(summary, info); - camel_folder_summary_info_free(summary, info); - info = camel_folder_summary_index(summary, id-1); + camel_folder_summary_remove(summary, (CamelMessageInfo *)info); + camel_message_info_free(info); + info = (CamelIMAPPMessageInfo *)camel_folder_summary_index(summary, id-1); } } else { printf("got info for unknown message %u\n", id); @@ -735,19 +735,19 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) if (info) { if (finfo->got & FETCH_MINFO) { /* if we only use ENVELOPE? */ - camel_message_info_set_subject(info, g_strdup(camel_message_info_subject(finfo->minfo))); - camel_message_info_set_from(info, g_strdup(camel_message_info_from(finfo->minfo))); - camel_message_info_set_to(info, g_strdup(camel_message_info_to(finfo->minfo))); - camel_message_info_set_cc(info, g_strdup(camel_message_info_cc(finfo->minfo))); - info->date_sent = finfo->minfo->date_sent; + info->info.subject = g_strdup(camel_message_info_subject(finfo->minfo)); + info->info.from = g_strdup(camel_message_info_from(finfo->minfo)); + info->info.to = g_strdup(camel_message_info_to(finfo->minfo)); + info->info.cc = g_strdup(camel_message_info_cc(finfo->minfo)); + info->info.date_sent = camel_message_info_date_sent(finfo->minfo); camel_folder_change_info_add_uid(sdata->folder->changes, camel_message_info_uid(info)); printf("adding change info uid '%s'\n", camel_message_info_uid(info)); } if (finfo->got & FETCH_FLAGS) { - if ((info->flags & CAMEL_IMAPP_SERVER_FLAGS) != (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS)) { + if ((info->info.flags & CAMEL_IMAPP_SERVER_FLAGS) != (camel_message_info_flags(finfo) & CAMEL_IMAPP_SERVER_FLAGS)) { camel_folder_change_info_change_uid(sdata->folder->changes, camel_message_info_uid(info)); - info->flags = (info->flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (finfo->flags & CAMEL_IMAPP_SERVER_FLAGS); + info->info.flags = (info->info.flags & ~(CAMEL_IMAPP_SERVER_FLAGS)) | (camel_message_info_flags(finfo) & CAMEL_IMAPP_SERVER_FLAGS); camel_folder_summary_touch(summary); } ((CamelIMAPPMessageInfo *)info)->server_flags = finfo->flags & CAMEL_IMAPP_SERVER_FLAGS; @@ -770,7 +770,7 @@ driver_resp_fetch(CamelIMAPPEngine *ie, guint32 id, CamelIMAPPDriver *sdata) } } - camel_folder_summary_info_free(summary, info); + camel_message_info_free(info); } else { printf("dont know what to do with message\n"); } diff --git a/camel/providers/imapp/camel-imapp-folder.c b/camel/providers/imapp/camel-imapp-folder.c index aed7534afe..e85048d92c 100644 --- a/camel/providers/imapp/camel-imapp-folder.c +++ b/camel/providers/imapp/camel-imapp-folder.c @@ -68,7 +68,6 @@ imap_folder_class_init (CamelIMAPPFolderClass *camel_imapp_folder_class) camel_folder_class->sync = imap_sync; camel_folder_class->get_message = imap_get_message; - /*camel_folder_class->set_message_flags = imap_set_message_flags;*/ } static void diff --git a/camel/providers/imapp/camel-imapp-store.c b/camel/providers/imapp/camel-imapp-store.c index 23b6d3ca32..60d2816096 100644 --- a/camel/providers/imapp/camel-imapp-store.c +++ b/camel/providers/imapp/camel-imapp-store.c @@ -810,7 +810,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) if (strcmp(finfo->uid, camel_message_info_uid(info)) != 0) { printf("summary at index %d has uid %s expected %s\n", id, camel_message_info_uid(info), finfo->uid); /* uid mismatch??? try do it based on uid instead? try to reorder? i dont know? */ - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); + camel_message_info_free(info); info = camel_folder_summary_uid(((CamelFolder *)istore->selected)->summary, finfo->uid); } } @@ -859,7 +859,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) CamelMimeParser *mp; if (pending == NULL) - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); + camel_message_info_free(info); mp = camel_mime_parser_new(); camel_mime_parser_init_with_stream(mp, finfo->header); info = camel_folder_summary_info_new_from_parser(((CamelFolder *)istore->selected)->summary, mp); @@ -872,7 +872,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) /* FIXME: use a dlist */ e_dlist_remove((EDListNode *)pending); g_hash_table_remove(istore->pending_fetch_table, camel_message_info_uid(pending->info)); - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, pending->info); + camel_message_info_free(pending->info); /*e_memchunk_free(istore->pending_fetch_chunks, pending);*/ } } else if (finfo->got & FETCH_FLAGS) { @@ -884,7 +884,7 @@ static int store_resp_fetch(CamelIMAPPEngine *ie, guint32 id, void *data) } } else { if (pending == NULL) - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); + camel_message_info_free(info); printf("got unexpected fetch response?\n"); imap_dump_fetch(finfo); } @@ -974,7 +974,7 @@ camel_imapp_store_folder_selected(CamelIMAPPStore *store, CamelIMAPPFolder *fold if (info) { printf("message info [%d] =\n", i); camel_message_info_dump(info); - camel_folder_summary_info_free(((CamelFolder *)istore->selected)->summary, info); + camel_message_info_free(info); } } } CAMEL_CATCH (e) { diff --git a/camel/providers/imapp/camel-imapp-store.h b/camel/providers/imapp/camel-imapp-store.h index 97b7afd1d1..ace5288986 100644 --- a/camel/providers/imapp/camel-imapp-store.h +++ b/camel/providers/imapp/camel-imapp-store.h @@ -44,7 +44,7 @@ struct _pending_fetch { struct _pending_fetch *next; struct _pending_fetch *prev; - CamelMessageInfo *info; + struct _CamelMessageInfo *info; }; typedef struct { diff --git a/camel/providers/imapp/camel-imapp-summary.c b/camel/providers/imapp/camel-imapp-summary.c index 05f0ec55c7..1b5a2c7155 100644 --- a/camel/providers/imapp/camel-imapp-summary.c +++ b/camel/providers/imapp/camel-imapp-summary.c @@ -168,7 +168,7 @@ message_info_load(CamelFolderSummary *s, FILE *in) return info; error: - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); return NULL; } diff --git a/camel/providers/imapp/camel-imapp-summary.h b/camel/providers/imapp/camel-imapp-summary.h index 215ad2465a..1189bac075 100644 --- a/camel/providers/imapp/camel-imapp-summary.h +++ b/camel/providers/imapp/camel-imapp-summary.h @@ -42,7 +42,7 @@ typedef struct _CamelIMAPPSummaryClass CamelIMAPPSummaryClass; typedef struct _CamelIMAPPSummary CamelIMAPPSummary; typedef struct _CamelIMAPPMessageInfo { - CamelMessageInfo info; + CamelMessageInfoBase info; guint32 server_flags; } CamelIMAPPMessageInfo; diff --git a/camel/providers/imapp/camel-imapp-utils.c b/camel/providers/imapp/camel-imapp-utils.c index 19bdb3b036..51e0fe19b0 100644 --- a/camel/providers/imapp/camel-imapp-utils.c +++ b/camel/providers/imapp/camel-imapp-utils.c @@ -6,6 +6,7 @@ #include <camel/camel-folder-summary.h> #include <camel/camel-store.h> #include <camel/camel-utf8.h> +#include <camel/camel-string-utils.h> #include "camel-imapp-folder.h" #include "camel-imapp-stream.h" @@ -585,7 +586,7 @@ imap_parse_envelope(CamelIMAPPStream *is) unsigned char *token; struct _camel_header_address *addr, *addr_from; char *addrstr; - struct _CamelMessageInfo *minfo; + struct _CamelMessageInfoBase *minfo; /* envelope ::= "(" env_date SPACE env_subject SPACE env_from SPACE env_sender SPACE env_reply_to SPACE env_to @@ -594,7 +595,7 @@ imap_parse_envelope(CamelIMAPPStream *is) p(printf("envelope\n")); - minfo = camel_message_info_new(); + minfo = (CamelMessageInfoBase *)camel_message_info_new(NULL); CAMEL_TRY { tok = camel_imapp_stream_token(is, &token, &len); @@ -607,8 +608,7 @@ imap_parse_envelope(CamelIMAPPStream *is) /* env_subject ::= nstring */ tok = camel_imapp_stream_nstring(is, &token); - /* DUH: this free's it!: camel_message_info_set_subject(minfo, token); */ - e_poolv_set(minfo->strings, CAMEL_MESSAGE_INFO_SUBJECT, token, FALSE); + minfo->subject = camel_pstring_strdup(token); /* we merge from/sender into from, append should probably merge more smartly? */ @@ -630,7 +630,8 @@ imap_parse_envelope(CamelIMAPPStream *is) if (addr_from) { addrstr = camel_header_address_list_format(addr_from); - camel_message_info_set_from(minfo, addrstr); + minfo->from = camel_pstring_strdup(addrstr); + g_free(addrstr); camel_header_address_list_clear(&addr_from); } @@ -644,7 +645,8 @@ imap_parse_envelope(CamelIMAPPStream *is) addr = imap_parse_address_list(is); if (addr) { addrstr = camel_header_address_list_format(addr); - camel_message_info_set_to(minfo, addrstr); + minfo->to = camel_pstring_strdup(addrstr); + g_free(addrstr); camel_header_address_list_clear(&addr); } @@ -652,7 +654,8 @@ imap_parse_envelope(CamelIMAPPStream *is) addr = imap_parse_address_list(is); if (addr) { addrstr = camel_header_address_list_format(addr); - camel_message_info_set_cc(minfo, addrstr); + minfo->cc = camel_pstring_strdup(addrstr); + g_free(addrstr); camel_header_address_list_clear(&addr); } @@ -680,7 +683,7 @@ imap_parse_envelope(CamelIMAPPStream *is) camel_exception_throw_ex(ex); } CAMEL_DONE; - return minfo; + return (CamelMessageInfo *)minfo; } struct _CamelMessageContentInfo * @@ -771,7 +774,7 @@ imap_parse_body(CamelIMAPPStream *is) /* what do we do with the envelope?? */ minfo = imap_parse_envelope(is); /* what do we do with the message content info?? */ - minfo->content = imap_parse_body(is); + ((CamelMessageInfoBase *)minfo)->content = imap_parse_body(is); camel_message_info_free(minfo); minfo = NULL; d(printf("Scanned envelope - what do i do with it?\n")); diff --git a/camel/providers/imapp/camel-imapp-utils.h b/camel/providers/imapp/camel-imapp-utils.h index e0974bdc96..2734cd0dc3 100644 --- a/camel/providers/imapp/camel-imapp-utils.h +++ b/camel/providers/imapp/camel-imapp-utils.h @@ -65,8 +65,8 @@ struct _fetch_info { CamelStream *body; /* BODY[.*](<.*>)? */ CamelStream *text; /* RFC822.TEXT */ CamelStream *header; /* RFC822.HEADER */ - CamelMessageInfo *minfo; /* ENVELOPE */ - CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */ + struct _CamelMessageInfo *minfo; /* ENVELOPE */ + struct _CamelMessageContentInfo *cinfo; /* BODYSTRUCTURE,BODY */ guint32 size; /* RFC822.SIZE */ guint32 offset; /* start offset of a BODY[]<offset.length> request */ guint32 flags; /* FLAGS */ diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c index e515dd54c6..0a4f96b552 100644 --- a/camel/providers/local/camel-local-summary.c +++ b/camel/providers/local/camel-local-summary.c @@ -46,10 +46,10 @@ static int summary_header_load (CamelFolderSummary *, FILE *); static int summary_header_save (CamelFolderSummary *, FILE *); -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *); -static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); -static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi); +static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi); +static char *local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi); static int local_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); static int local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); @@ -89,7 +89,7 @@ camel_local_summary_class_init(CamelLocalSummaryClass *klass) sklass->summary_header_load = summary_header_load; sklass->summary_header_save = summary_header_save; - sklass->message_info_new = message_info_new; + sklass->message_info_new_from_header = message_info_new_from_header; klass->load = local_summary_load; klass->check = local_summary_check; @@ -106,7 +106,7 @@ camel_local_summary_init(CamelLocalSummary *obj) struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelMessageInfo); + s->message_info_size = sizeof(CamelLocalMessageInfo); s->content_info_size = sizeof(CamelMessageContentInfo); /* and a unique file version */ @@ -166,13 +166,13 @@ void camel_local_summary_check_force(CamelLocalSummary *cls) } char * -camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info) +camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *info) { return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->encode_x_evolution(cls, info); } int -camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info) +camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info) { return ((CamelLocalSummaryClass *)(CAMEL_OBJECT_GET_CLASS(cls)))->decode_x_evolution(cls, xev, info); } @@ -273,7 +273,7 @@ camel_local_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changei for (i=0;i<camel_folder_summary_count(s);i++) { CamelMessageInfo *info = camel_folder_summary_index(s, i); do_stat_mi(cls, &stats, info); - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } printf("\nMemory used by summary:\n\n"); @@ -418,43 +418,42 @@ local_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeIn static CamelMessageInfo * local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex) { - CamelMessageInfo *mi; + CamelLocalMessageInfo *mi; char *xev; d(printf("Adding message to summary\n")); - mi = camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg); + mi = (CamelLocalMessageInfo *)camel_folder_summary_add_from_message((CamelFolderSummary *)cls, msg); if (mi) { d(printf("Added, uid = %s\n", mi->uid)); if (info) { - CamelTag *tag = info->user_tags; - CamelFlag *flag = info->user_flags; + const CamelTag *tag = camel_message_info_user_tags(info); + const CamelFlag *flag = camel_message_info_user_flags(info); while (flag) { - camel_flag_set(&mi->user_flags, flag->name, TRUE); + camel_message_info_set_user_flag((CamelMessageInfo *)mi, flag->name, TRUE); flag = flag->next; } while (tag) { - camel_tag_set(&mi->user_tags, tag->name, tag->value); + camel_message_info_set_user_tag((CamelMessageInfo *)mi, tag->name, tag->value); tag = tag->next; } - mi->flags = mi->flags | (info->flags & 0xffff); - if (info->size) - mi->size = info->size; + mi->info.flags |= (camel_message_info_flags(info) & 0xffff); + mi->info.size = camel_message_info_size(info); } /* we need to calculate the size ourselves */ - if (mi->size == 0) { + if (mi->info.size == 0) { CamelStreamNull *sn = (CamelStreamNull *)camel_stream_null_new(); camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, (CamelStream *)sn); - mi->size = sn->written; + mi->info.size = sn->written; camel_object_unref((CamelObject *)sn); } - mi->flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED); + mi->info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED); xev = camel_local_summary_encode_x_evolution(cls, mi); camel_medium_set_header((CamelMedium *)msg, "X-Evolution", xev); g_free(xev); @@ -464,17 +463,17 @@ local_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMess camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Unable to add message to summary: unknown reason")); } - return mi; + return (CamelMessageInfo *)mi; } static char * -local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi) +local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi) { GString *out = g_string_new(""); struct _camel_header_param *params = NULL; GString *val = g_string_new(""); - CamelFlag *flag = mi->user_flags; - CamelTag *tag = mi->user_tags; + CamelFlag *flag = mi->info.user_flags; + CamelTag *tag = mi->info.user_tags; char *ret; const char *p, *uidstr; guint32 uid; @@ -485,9 +484,9 @@ local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo while (*p && isdigit(*p)) p++; if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) { - g_string_printf (out, "%08x-%04x", uid, mi->flags & 0xffff); + g_string_printf (out, "%08x-%04x", uid, mi->info.flags & 0xffff); } else { - g_string_printf (out, "%s-%04x", uidstr, mi->flags & 0xffff); + g_string_printf (out, "%s-%04x", uidstr, mi->info.flags & 0xffff); } if (flag || tag) { @@ -525,23 +524,22 @@ local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo } static int -local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi) +local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi) { struct _camel_header_param *params, *scan; guint32 uid, flags; char *header; int i; + char uidstr[20]; + + uidstr[0] = 0; /* check for uid/flags */ header = camel_header_token_decode(xev); if (header && strlen(header) == strlen("00000000-0000") && sscanf(header, "%08x-%04x", &uid, &flags) == 2) { - char uidstr[20]; - if (mi) { + if (mi) sprintf(uidstr, "%u", uid); - camel_message_info_set_uid(mi, g_strdup(uidstr)); - mi->flags = flags; - } } else { g_free(header); return -1; @@ -560,9 +558,8 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM if (!strcasecmp(scan->name, "flags")) { char **flagv = g_strsplit(scan->value, ",", 1000); - for (i=0;flagv[i];i++) { - camel_flag_set(&mi->user_flags, flagv[i], TRUE); - } + for (i=0;flagv[i];i++) + camel_message_info_set_user_flag((CamelMessageInfo *)mi, flagv[i], TRUE); g_strfreev(flagv); } else if (!strcasecmp(scan->name, "tags")) { char **tagv = g_strsplit(scan->value, ",", 10000); @@ -572,7 +569,7 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM val = strchr(tagv[i], '='); if (val) { *val++ = 0; - camel_tag_set(&mi->user_tags, tagv[i], val); + camel_message_info_set_user_tag((CamelMessageInfo *)mi, tagv[i], val); val[-1]='='; } } @@ -582,6 +579,10 @@ local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelM } camel_header_param_list_free(params); } + + mi->info.uid = g_strdup(uidstr); + mi->info.flags = flags; + return 0; } @@ -615,12 +616,12 @@ summary_header_save(CamelFolderSummary *s, FILE *out) } static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) +message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { - CamelMessageInfo *mi; + CamelLocalMessageInfo *mi; CamelLocalSummary *cls = (CamelLocalSummary *)s; - mi = ((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new(s, h); + mi = (CamelLocalMessageInfo *)((CamelFolderSummaryClass *)camel_local_summary_parent)->message_info_new_from_header(s, h); if (mi) { const char *xev; int doindex = FALSE; @@ -628,8 +629,8 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) xev = camel_header_raw_find(&h, "X-Evolution", NULL); if (xev==NULL || camel_local_summary_decode_x_evolution(cls, xev, mi) == -1) { /* to indicate it has no xev header */ - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); + mi->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; + mi->info.uid = camel_folder_summary_next_uid_string(s); /* shortcut, no need to look it up in the index library */ doindex = TRUE; @@ -647,5 +648,5 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) } } - return mi; + return (CamelMessageInfo *)mi; } diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h index 99a520f243..cc7dc3eb2d 100644 --- a/camel/providers/local/camel-local-summary.h +++ b/camel/providers/local/camel-local-summary.h @@ -40,6 +40,12 @@ enum { CAMEL_MESSAGE_FOLDER_NOTSEEN = 1<<19, /* have we seen this in processing this loop? */ }; +typedef struct _CamelLocalMessageInfo CamelLocalMessageInfo; + +struct _CamelLocalMessageInfo { + CamelMessageInfoBase info; +}; + struct _CamelLocalSummary { CamelFolderSummary parent; @@ -60,8 +66,8 @@ struct _CamelLocalSummaryClass { int (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); - char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelMessageInfo *info); - int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info); + char *(*encode_x_evolution)(CamelLocalSummary *cls, const CamelLocalMessageInfo *info); + int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info); }; CamelType camel_local_summary_get_type (void); @@ -80,8 +86,8 @@ CamelMessageInfo *camel_local_summary_add(CamelLocalSummary *cls, CamelMimeMessa void camel_local_summary_check_force(CamelLocalSummary *cls); /* generate an X-Evolution header line */ -char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *info); -int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info); +char *camel_local_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *info); +int camel_local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *info); /* utility functions - write headers to a file with optional X-Evolution header and/or status header */ int camel_local_summary_write_headers(int fd, struct _camel_header_raw *header, const char *xevline, const char *status, const char *xstatus); diff --git a/camel/providers/local/camel-maildir-folder.c b/camel/providers/local/camel-maildir-folder.c index 669e636527..b74f6e5ace 100644 --- a/camel/providers/local/camel-maildir-folder.c +++ b/camel/providers/local/camel-maildir-folder.c @@ -153,7 +153,7 @@ camel_maildir_folder_new(CamelStore *parent_store, const char *full_name, guint3 static CamelLocalSummary *maildir_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index) { - return (CamelLocalSummary *)camel_maildir_summary_new(path, folder, index); + return (CamelLocalSummary *)camel_maildir_summary_new((CamelFolder *)lf, path, folder, index); } static void @@ -251,7 +251,7 @@ static CamelMimeMessage *maildir_get_message(CamelFolder * folder, const gchar * /* what do we do if the message flags (and :info data) changes? filename mismatch - need to recheck I guess */ name = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename(mdi)); - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c index 9c4097a3cb..eac22d23c6 100644 --- a/camel/providers/local/camel-maildir-store.c +++ b/camel/providers/local/camel-maildir-store.c @@ -283,7 +283,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags) root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store); path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name); folderpath = g_strdup_printf("%s/%s", root, fi->full_name); - s = (CamelFolderSummary *)camel_maildir_summary_new(path, folderpath, NULL); + s = (CamelFolderSummary *)camel_maildir_summary_new(NULL, path, folderpath, NULL); if (camel_folder_summary_header_load(s) != -1) { fi->unread = s->unread_count; fi->total = s->saved_count; diff --git a/camel/providers/local/camel-maildir-summary.c b/camel/providers/local/camel-maildir-summary.c index 8b15c2b991..07183d2cb4 100644 --- a/camel/providers/local/camel-maildir-summary.c +++ b/camel/providers/local/camel-maildir-summary.c @@ -49,7 +49,7 @@ #define CAMEL_MAILDIR_SUMMARY_VERSION (0x2000) static CamelMessageInfo *message_info_load(CamelFolderSummary *s, FILE *in); -static CamelMessageInfo *message_info_new(CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *); static void message_info_free(CamelFolderSummary *, CamelMessageInfo *mi); static int maildir_summary_load(CamelLocalSummary *cls, int forceindex, CamelException *ex); @@ -58,8 +58,8 @@ static int maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelF static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, CamelException *ex); static char *maildir_summary_next_uid_string(CamelFolderSummary *s); -static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); -static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi); +static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi); +static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi); static void camel_maildir_summary_class_init (CamelMaildirSummaryClass *class); static void camel_maildir_summary_init (CamelMaildirSummary *gspaper); @@ -104,7 +104,7 @@ camel_maildir_summary_class_init (CamelMaildirSummaryClass *class) /* override methods */ sklass->message_info_load = message_info_load; - sklass->message_info_new = message_info_new; + sklass->message_info_new_from_header = message_info_new_from_header; sklass->message_info_free = message_info_free; sklass->next_uid_string = maildir_summary_next_uid_string; @@ -151,15 +151,20 @@ camel_maildir_summary_finalise(CamelObject *obj) /** * camel_maildir_summary_new: + * @folder: parent folder. + * @filename: Path to root of this maildir directory (containing new/tmp/cur directories). + * @index: Index if one is reqiured. * * Create a new CamelMaildirSummary object. * * Return value: A new #CamelMaildirSummary object. **/ -CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index) +CamelMaildirSummary *camel_maildir_summary_new(struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index) { CamelMaildirSummary *o = (CamelMaildirSummary *)camel_object_new(camel_maildir_summary_get_type ()); + ((CamelFolderSummary *)o)->folder = folder; + camel_local_summary_construct((CamelLocalSummary *)o, filename, maildirdir, index); return o; } @@ -178,17 +183,17 @@ static struct { }; /* convert the uid + flags into a unique:info maildir format */ -char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info) +char *camel_maildir_summary_info_to_name(const CamelMaildirMessageInfo *info) { const char *uid; char *p, *buf; int i; - + uid = camel_message_info_uid (info); buf = g_alloca (strlen (uid) + strlen (":2,") + (sizeof (flagbits) / sizeof (flagbits[0])) + 1); p = buf + sprintf (buf, "%s:2,", uid); for (i = 0; i < sizeof (flagbits) / sizeof (flagbits[0]); i++) { - if (info->flags & flagbits[i].flagbit) + if (info->info.info.flags & flagbits[i].flagbit) *p++ = flagbits[i].flag; } *p = 0; @@ -197,7 +202,7 @@ char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info) } /* returns 0 if the info matches (or there was none), otherwise we changed it */ -int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name) +int camel_maildir_summary_name_to_info(CamelMaildirMessageInfo *info, const char *name) { char *p, c; guint32 set = 0; /* what we set */ @@ -210,7 +215,7 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name) while ((c = *p++)) { /* we could assume that the flags are in order, but its just as easy not to require */ for (i=0;i<sizeof(flagbits)/sizeof(flagbits[0]);i++) { - if (flagbits[i].flag == c && (info->flags & flagbits[i].flagbit) == 0) { + if (flagbits[i].flag == c && (info->info.info.flags & flagbits[i].flagbit) == 0) { set |= flagbits[i].flagbit; } /*all |= flagbits[i].flagbit;*/ @@ -219,10 +224,10 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name) /* changed? */ /*if ((info->flags & all) != set) {*/ - if ((info->flags & set) != set) { + if ((info->info.info.flags & set) != set) { /* ok, they did change, only add the new flags ('merge flags'?) */ /*info->flags &= all; if we wanted to set only the new flags, which we probably dont */ - info->flags |= set; + info->info.info.flags |= set; return 1; } } @@ -231,12 +236,12 @@ int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name) } /* for maildir, x-evolution isn't used, so dont try and get anything out of it */ -static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi) +static int maildir_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelLocalMessageInfo *mi) { return -1; } -static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelMessageInfo *mi) +static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const CamelLocalMessageInfo *mi) { return NULL; } @@ -246,9 +251,9 @@ static char *maildir_summary_encode_x_evolution(CamelLocalSummary *cls, const Ca */ static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *changes, CamelException *ex) { - CamelMessageInfo *mi; + CamelMaildirMessageInfo *mi; - mi = ((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex); + mi = (CamelMaildirMessageInfo *)((CamelLocalSummaryClass *) parent_class)->add(cls, msg, info, changes, ex); if (mi) { if (info) { camel_maildir_info_set_filename(mi, camel_maildir_summary_info_to_name(mi)); @@ -256,35 +261,35 @@ static CamelMessageInfo *maildir_summary_add(CamelLocalSummary *cls, CamelMimeMe } } - return mi; + return (CamelMessageInfo *)mi; } -static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_header_raw *h) +static CamelMessageInfo *message_info_new_from_header(CamelFolderSummary * s, struct _camel_header_raw *h) { CamelMessageInfo *mi, *info; CamelMaildirSummary *mds = (CamelMaildirSummary *)s; CamelMaildirMessageInfo *mdi; const char *uid; - mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new(s, h); + mi = ((CamelFolderSummaryClass *) parent_class)->message_info_new_from_header(s, h); /* assign the uid and new filename */ if (mi) { mdi = (CamelMaildirMessageInfo *)mi; uid = camel_message_info_uid(mi); if (uid==NULL || uid[0] == 0) - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); + mdi->info.info.uid = camel_folder_summary_next_uid_string(s); /* handle 'duplicates' */ info = camel_folder_summary_uid(s, uid); if (info) { d(printf("already seen uid '%s', just summarising instead\n", uid)); - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); mdi = (CamelMaildirMessageInfo *)(mi = info); } /* with maildir we know the real received date, from the filename */ - mi->date_received = strtoul(camel_message_info_uid(mi), NULL, 10); + mdi->info.info.date_received = strtoul(camel_message_info_uid(mi), NULL, 10); if (mds->priv->current_file) { #if 0 @@ -293,7 +298,7 @@ static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_ #endif /* if setting from a file, grab the flags from it */ camel_maildir_info_set_filename(mi, g_strdup(mds->priv->current_file)); - camel_maildir_summary_name_to_info(mi, mds->priv->current_file); + camel_maildir_summary_name_to_info(mdi, mds->priv->current_file); #if 0 /* Actually, I dont think all this effort is worth it at all ... */ @@ -313,7 +318,7 @@ static CamelMessageInfo *message_info_new(CamelFolderSummary * s, struct _camel_ #endif } else { /* if creating a file, set its name from the flags we have */ - camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mi)); + camel_maildir_info_set_filename(mdi, camel_maildir_summary_info_to_name(mdi)); d(printf("Setting filename to %s\n", camel_maildir_info_filename(mi))); } } @@ -393,7 +398,7 @@ message_info_load(CamelFolderSummary *s, FILE *in) && (name = g_hash_table_lookup(mds->priv->load_map, camel_message_info_uid(mi)))) { d(printf("Setting filename of %s to %s\n", camel_message_info_uid(mi), name)); camel_maildir_info_set_filename(mi, g_strdup(name)); - camel_maildir_summary_name_to_info(mi, name); + camel_maildir_summary_name_to_info((CamelMaildirMessageInfo *)mi, name); } } @@ -502,19 +507,19 @@ remove_summary(char *key, CamelMessageInfo *info, struct _remove_data *rd) if (rd->changes) camel_folder_change_info_remove_uid(rd->changes, key); camel_folder_summary_remove((CamelFolderSummary *)rd->cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)rd->cls, info); + camel_message_info_free(info); } static int sort_receive_cmp(const void *ap, const void *bp) { - const CamelMessageInfo - *a = *((CamelMessageInfo **)ap), - *b = *((CamelMessageInfo **)bp); + const CamelMaildirMessageInfo + *a = *((CamelMaildirMessageInfo **)ap), + *b = *((CamelMaildirMessageInfo **)bp); - if (a->date_received < b->date_received) + if (a->info.info.date_received < b->info.info.date_received) return -1; - else if (a->date_received > b->date_received) + else if (a->info.info.date_received > b->info.info.date_received) return 1; return 0; @@ -594,7 +599,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca info = g_hash_table_lookup(left, uid); if (info) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); g_hash_table_remove(left, uid); } @@ -634,7 +639,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca # endif #endif } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } g_free(uid); } @@ -669,7 +674,7 @@ maildir_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Ca /* already in summary? shouldn't happen, but just incase ... */ if ((info = camel_folder_summary_uid((CamelFolderSummary *)cls, name))) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); newname = destname = camel_folder_summary_next_uid_string(s); } else { newname = NULL; @@ -741,7 +746,7 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange info = camel_folder_summary_index((CamelFolderSummary *)cls, i); mdi = (CamelMaildirMessageInfo *)info; - if (info && (info->flags & CAMEL_MESSAGE_DELETED) && expunge) { + if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_DELETED) && expunge) { name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi)); d(printf("deleting %s\n", name)); if (unlink(name) == 0 || errno==ENOENT) { @@ -754,8 +759,8 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange camel_folder_summary_remove((CamelFolderSummary *)cls, info); } g_free(name); - } else if (info && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) { - char *newname = camel_maildir_summary_info_to_name(info); + } else if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) { + char *newname = camel_maildir_summary_info_to_name(mdi); char *dest; /* do we care about additional metainfo stored inside the message? */ @@ -798,9 +803,9 @@ maildir_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChange } /* strip FOLDER_MESSAGE_FLAGED, etc */ - info->flags &= 0xffff; + mdi->info.info.flags &= 0xffff; } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } camel_operation_end(NULL); diff --git a/camel/providers/local/camel-maildir-summary.h b/camel/providers/local/camel-maildir-summary.h index 0cae785c6c..4ecaf368f5 100644 --- a/camel/providers/local/camel-maildir-summary.h +++ b/camel/providers/local/camel-maildir-summary.h @@ -37,19 +37,15 @@ typedef struct _CamelMaildirMessageContentInfo { CamelMessageContentInfo info; } CamelMaildirMessageContentInfo; -#if defined (DOEPOOLV) || defined (DOESTRV) enum { CAMEL_MAILDIR_INFO_FILENAME = CAMEL_MESSAGE_INFO_LAST, CAMEL_MAILDIR_INFO_LAST, }; -#endif typedef struct _CamelMaildirMessageInfo { - CamelMessageInfo info; + CamelLocalMessageInfo info; -#if !defined (DOEPOOLV) && !defined (DOESTRV) char *filename; /* maildir has this annoying status shit on the end of the filename, use this to get the real message id */ -#endif } CamelMaildirMessageInfo; struct _CamelMaildirSummary { @@ -66,19 +62,15 @@ struct _CamelMaildirSummaryClass { }; CamelType camel_maildir_summary_get_type (void); -CamelMaildirSummary *camel_maildir_summary_new (const char *filename, const char *maildirdir, CamelIndex *index); +CamelMaildirSummary *camel_maildir_summary_new (struct _CamelFolder *folder, const char *filename, const char *maildirdir, CamelIndex *index); /* convert some info->flags to/from the messageinfo */ -char *camel_maildir_summary_info_to_name(const CamelMessageInfo *info); -int camel_maildir_summary_name_to_info(CamelMessageInfo *info, const char *name); +char *camel_maildir_summary_info_to_name(const CamelMaildirMessageInfo *info); +int camel_maildir_summary_name_to_info(CamelMaildirMessageInfo *info, const char *name); -#if defined (DOEPOOLV) || defined (DOESTRV) -#define camel_maildir_info_filename(x) camel_message_info_string((const CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME) -#define camel_maildir_info_set_filename(x, s) camel_message_info_set_string((CamelMessageInfo *)(x), CAMEL_MAILDIR_INFO_FILENAME, s) -#else +/* TODO: could proably use get_string stuff */ #define camel_maildir_info_filename(x) (((CamelMaildirMessageInfo *)x)->filename) #define camel_maildir_info_set_filename(x, s) (g_free(((CamelMaildirMessageInfo *)x)->filename),((CamelMaildirMessageInfo *)x)->filename = s) -#endif #endif /* ! _CAMEL_MAILDIR_SUMMARY_H */ diff --git a/camel/providers/local/camel-mbox-folder.c b/camel/providers/local/camel-mbox-folder.c index b4926b9b04..d213b444fc 100644 --- a/camel/providers/local/camel-mbox-folder.c +++ b/camel/providers/local/camel-mbox-folder.c @@ -56,13 +56,6 @@ static CamelLocalFolderClass *parent_class = NULL; static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex); static void mbox_unlock(CamelLocalFolder *lf); -#ifdef STATUS_PINE -static gboolean mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set); -#endif - -static void mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value); -static void mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); - static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, const CamelMessageInfo * info, char **appended_uid, CamelException *ex); static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index); @@ -83,12 +76,6 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class) camel_folder_class->append_message = mbox_append_message; camel_folder_class->get_message = mbox_get_message; -#ifdef STATUS_PINE - camel_folder_class->set_message_flags = mbox_set_message_flags; -#endif - camel_folder_class->set_message_user_flag = mbox_set_message_user_flag; - camel_folder_class->set_message_user_tag = mbox_set_message_user_tag; - lclass->get_full_path = camel_mbox_folder_get_full_path; lclass->get_meta_path = camel_mbox_folder_get_meta_path; lclass->create_summary = mbox_create_summary; @@ -207,7 +194,7 @@ camel_mbox_folder_get_meta_path (CamelLocalFolder *lf, const char *toplevel_dir, static CamelLocalSummary *mbox_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index) { - return (CamelLocalSummary *)camel_mbox_summary_new(path, folder, index); + return (CamelLocalSummary *)camel_mbox_summary_new((CamelFolder *)lf, path, folder, index); } static int mbox_lock(CamelLocalFolder *lf, CamelLockType type, CamelException *ex) @@ -421,7 +408,7 @@ retry: g_assert(info->frompos != -1); frompos = info->frompos; - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); /* we use an fd instead of a normal stream here - the reason is subtle, camel_mime_part will cache the whole message in memory if the stream is non-seekable (which it is when built from a parser @@ -493,66 +480,3 @@ fail: return message; } - -#ifdef STATUS_PINE -static gboolean -mbox_set_message_flags(CamelFolder *folder, const char *uid, guint32 flags, guint32 set) -{ - /* Basically, if anything could change the Status line, presume it does */ - if (((CamelMboxSummary *)folder->summary)->xstatus - && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) { - flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; - set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; - } - - return ((CamelFolderClass *)parent_class)->set_message_flags(folder, uid, flags, set); -} -#endif - -static void -mbox_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name, gboolean value) -{ - CamelMessageInfo *info; - - g_return_if_fail(folder->summary != NULL); - - info = camel_folder_summary_uid(folder->summary, uid); - if (info == NULL) - return; - - if (camel_flag_set(&info->user_flags, name, value)) { - CamelFolderChangeInfo *changes = camel_folder_change_info_new(); - - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(folder->summary); - - camel_folder_change_info_change_uid(changes, uid); - camel_object_trigger_event(folder, "folder_changed", changes); - camel_folder_change_info_free(changes); - } - camel_folder_summary_info_free(folder->summary, info); -} - -static void -mbox_set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value) -{ - CamelMessageInfo *info; - - g_return_if_fail(folder->summary != NULL); - - info = camel_folder_summary_uid(folder->summary, uid); - if (info == NULL) - return; - - if (camel_tag_set(&info->user_tags, name, value)) { - CamelFolderChangeInfo *changes = camel_folder_change_info_new(); - - info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; - camel_folder_summary_touch(folder->summary); - - camel_folder_change_info_change_uid(changes, uid); - camel_object_trigger_event (folder, "folder_changed", changes); - camel_folder_change_info_free(changes); - } - camel_folder_summary_info_free(folder->summary, info); -} diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c index f98c87a8ea..a9e581cdd7 100644 --- a/camel/providers/local/camel-mbox-store.c +++ b/camel/providers/local/camel-mbox-store.c @@ -618,7 +618,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags) path = camel_mbox_folder_get_meta_path(NULL, root, fi->full_name, ".ev-summary"); folderpath = camel_mbox_folder_get_full_path(NULL, root, fi->full_name); - mbs = (CamelMboxSummary *)camel_mbox_summary_new(path, folderpath, NULL); + mbs = (CamelMboxSummary *)camel_mbox_summary_new(NULL, path, folderpath, NULL); if (camel_folder_summary_header_load((CamelFolderSummary *)mbs) != -1) { fi->unread = ((CamelFolderSummary *)mbs)->unread_count; fi->total = ((CamelFolderSummary *)mbs)->saved_count; diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c index 60dcf34c1c..9dcee0a9c8 100644 --- a/camel/providers/local/camel-mbox-summary.c +++ b/camel/providers/local/camel-mbox-summary.c @@ -51,13 +51,13 @@ static int summary_header_load (CamelFolderSummary *, FILE *); static int summary_header_save (CamelFolderSummary *, FILE *); -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *); -static CamelMessageInfo * message_info_new_from_parser (CamelFolderSummary *, CamelMimeParser *); +static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *); static CamelMessageInfo * message_info_load (CamelFolderSummary *, FILE *); static int message_info_save (CamelFolderSummary *, FILE *, CamelMessageInfo *); /*static void message_info_free (CamelFolderSummary *, CamelMessageInfo *);*/ -static char *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *mi); +static char *mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi); static int mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, CamelException *ex); static int mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, CamelException *ex); @@ -100,6 +100,44 @@ camel_mbox_summary_get_type(void) return type; } +static gboolean +mbox_info_set_user_flag(CamelMessageInfo *mi, const char *name, gboolean value) +{ + int res; + + res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_flag(mi, name, value); + if (res) + ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; + + return res; +} + +static gboolean +mbox_info_set_user_tag(CamelMessageInfo *mi, const char *name, const char *value) +{ + int res; + + res = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_user_tag(mi, name, value); + if (res) + ((CamelLocalMessageInfo *)mi)->info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED|CAMEL_MESSAGE_FOLDER_XEVCHANGE; + + return res; +} + +#ifdef STATUS_PINE +static gboolean +mbox_info_set_flags(CamelMessageInfo *mi, guint32 flags, guint32 set) +{ + /* Basically, if anything could change the Status line, presume it does */ + if (((CamelMboxSummary *)mi->summary)->xstatus + && (flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_ANSWERED|CAMEL_MESSAGE_DELETED))) { + flags |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; + set |= CAMEL_MESSAGE_FOLDER_XEVCHANGE|CAMEL_MESSAGE_FOLDER_FLAGGED; + } + + return ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->info_set_flags(mi, flags, set); +} +#endif static void camel_mbox_summary_class_init(CamelMboxSummaryClass *klass) @@ -112,11 +150,17 @@ camel_mbox_summary_class_init(CamelMboxSummaryClass *klass) sklass->summary_header_load = summary_header_load; sklass->summary_header_save = summary_header_save; - sklass->message_info_new = message_info_new; + sklass->message_info_new_from_header = message_info_new_from_header; sklass->message_info_new_from_parser = message_info_new_from_parser; sklass->message_info_load = message_info_load; sklass->message_info_save = message_info_save; /*sklass->message_info_free = message_info_free;*/ + + sklass->info_set_user_flag = mbox_info_set_user_flag; + sklass->info_set_user_tag = mbox_info_set_user_tag; +#ifdef STATUS_PINE + sklass->info_set_flags = mbox_info_set_flags; +#endif lklass->encode_x_evolution = mbox_summary_encode_x_evolution; lklass->check = mbox_summary_check; @@ -156,10 +200,12 @@ camel_mbox_summary_finalise(CamelObject *obj) * Return value: A new CamelMboxSummary widget. **/ CamelMboxSummary * -camel_mbox_summary_new(const char *filename, const char *mbox_name, CamelIndex *index) +camel_mbox_summary_new(struct _CamelFolder *folder, const char *filename, const char *mbox_name, CamelIndex *index) { CamelMboxSummary *new = (CamelMboxSummary *)camel_object_new(camel_mbox_summary_get_type()); + ((CamelFolderSummary *)new)->folder = folder; + camel_local_summary_construct((CamelLocalSummary *)new, filename, mbox_name, index); return new; } @@ -170,19 +216,20 @@ void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state) } static char * -mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelMessageInfo *mi) +mbox_summary_encode_x_evolution (CamelLocalSummary *cls, const CamelLocalMessageInfo *mi) { const char *p, *uidstr; guint32 uid; - - p = uidstr = camel_message_info_uid (mi); - while (*p && isdigit (*p)) + + /* This is busted, it is supposed to encode ALL DATA */ + p = uidstr = camel_message_info_uid(mi); + while (*p && isdigit(*p)) p++; - if (*p == 0 && sscanf (uidstr, "%u", &uid) == 1) { - return g_strdup_printf ("%08x-%04x", uid, mi->flags & 0xffff); + if (*p == 0 && sscanf(uidstr, "%u", &uid) == 1) { + return g_strdup_printf("%08x-%04x", uid, mi->info.flags & 0xffff); } else { - return g_strdup_printf ("%s-%04x", uidstr, mi->flags & 0xffff); + return g_strdup_printf("%s-%04x", uidstr, mi->info.flags & 0xffff); } } @@ -220,16 +267,15 @@ summary_header_save(CamelFolderSummary *s, FILE *out) } static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) +message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { - CamelMessageInfo *mi; + CamelMboxMessageInfo *mi; CamelMboxSummary *mbs = (CamelMboxSummary *)s; - mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new(s, h); + mi = (CamelMboxMessageInfo *)((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_new_from_header(s, h); if (mi) { - CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi; const char *xev, *uid; - CamelMessageInfo *info = NULL; + CamelMboxMessageInfo *info = NULL; int add = 0; /* bitmask of things to add, 1 assign uid, 2, just add as new, 4 = recent */ #ifdef STATUS_PINE const char *status = NULL, *xstatus = NULL; @@ -248,19 +294,19 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) /* if we have an xev header, use it, else assign a new one */ xev = camel_header_raw_find(&h, "X-Evolution", NULL); if (xev != NULL - && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, mi) == 0) { + && camel_local_summary_decode_x_evolution((CamelLocalSummary *)s, xev, &mi->info) == 0) { uid = camel_message_info_uid(mi); d(printf("found valid x-evolution: %s\n", uid)); - info = camel_folder_summary_uid(s, uid); + info = (CamelMboxMessageInfo *)camel_folder_summary_uid(s, uid); if (info) { - if ((info->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) { - info->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; - camel_folder_summary_info_free(s, mi); - mbi = (CamelMboxMessageInfo *)(mi = info); + if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) { + info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; + camel_message_info_free(mi); + mi = info; } else { add = 7; d(printf("seen '%s' before, adding anew\n", uid)); - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } } else { add = 2; @@ -272,8 +318,8 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) } if (add&1) { - mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; - camel_message_info_set_uid(mi, camel_folder_summary_next_uid_string(s)); + mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_NOXEV; + mi->info.info.uid = camel_folder_summary_next_uid_string(s); } else { camel_folder_summary_set_uid(s, strtoul(camel_message_info_uid(mi), NULL, 10)); } @@ -281,9 +327,9 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) if (mbs->xstatus && add&2) { /* use the status as the flags when we read it the first time */ if (status) - mi->flags = (mi->flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS); + mi->info.info.flags = (mi->info.info.flags & ~(STATUS_STATUS)) | (flags & STATUS_STATUS); if (xstatus) - mi->flags = (mi->flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS); + mi->info.info.flags = (mi->info.info.flags & ~(STATUS_XSTATUS)) | (flags & STATUS_XSTATUS); } #endif if (mbs->changes) { @@ -293,10 +339,10 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) camel_folder_change_info_recent_uid(mbs->changes, camel_message_info_uid(mi)); } - mbi->frompos = -1; + mi->frompos = -1; } - return mi; + return (CamelMessageInfo *)mi; } static CamelMessageInfo * @@ -331,7 +377,7 @@ message_info_load(CamelFolderSummary *s, FILE *in) return mi; error: - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); return NULL; } @@ -357,7 +403,7 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan CamelFolderSummary *s = (CamelFolderSummary *)cls; CamelMboxSummary *mbs = (CamelMboxSummary *)cls; CamelMimeParser *mp; - CamelMessageInfo *mi; + CamelMboxMessageInfo *mi; int fd; int ok = 0; struct stat st; @@ -404,12 +450,12 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan from the old end, so everything must be treated as new */ count = camel_folder_summary_count(s); for (i=0;i<count;i++) { - mi = camel_folder_summary_index(s, i); + mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); if (offset == 0) - mi->flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN; + mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN; else - mi->flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; - camel_folder_summary_info_free(s, mi); + mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN; + camel_message_info_free(mi); } mbs->changes = changeinfo; @@ -434,17 +480,17 @@ summary_update(CamelLocalSummary *cls, off_t offset, CamelFolderChangeInfo *chan count = camel_folder_summary_count(s); for (i=0;i<count;i++) { - mi = camel_folder_summary_index(s, i); + mi = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); /* must've dissapeared from the file? */ - if (mi->flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) { + if (mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) { d(printf("uid '%s' vanished, removing", camel_message_info_uid(mi))); if (changeinfo) camel_folder_change_info_remove_uid(changeinfo, camel_message_info_uid(mi)); - camel_folder_summary_remove(s, mi); + camel_folder_summary_remove(s, (CamelMessageInfo *)mi); count--; i--; } - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); } mbs->changes = NULL; @@ -495,7 +541,7 @@ mbox_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changes, Camel if (info) { camel_folder_change_info_remove_uid(changes, camel_message_info_uid(info)); - camel_folder_summary_info_free(s, info); + camel_message_info_free(info); } } camel_folder_summary_clear(s); @@ -661,8 +707,8 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan d(printf("Checking message %s %08x\n", camel_message_info_uid(info), info->info.flags)); - if ((info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) { - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) { + camel_message_info_free((CamelMessageInfo *)info); info = NULL; continue; } @@ -696,7 +742,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan g_warning("We're supposed to have a valid x-ev header, but we dont"); goto error; } - xevnew = camel_local_summary_encode_x_evolution(cls, (CamelMessageInfo *)info); + xevnew = camel_local_summary_encode_x_evolution(cls, &info->info); /* SIGH: encode_param_list is about the only function which folds headers by itself. This should be fixed somehow differently (either parser doesn't fold headers, or param_list doesn't, or something */ @@ -725,8 +771,8 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan camel_mime_parser_drop_step(mp); camel_mime_parser_drop_step(mp); - info->info.flags &= 0xffff; - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + info->info.info.flags &= 0xffff; + camel_message_info_free((CamelMessageInfo *)info); } d(printf("Closing folders\n")); @@ -751,7 +797,7 @@ mbox_summary_sync_quick(CamelMboxSummary *mbs, gboolean expunge, CamelFolderChan if (mp) camel_object_unref((CamelObject *)mp); if (info) - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); camel_operation_end(NULL); @@ -778,14 +824,15 @@ mbox_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInf /* check what work we have to do, if any */ for (i=0;quick && i<count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); + CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); + g_assert(info); - if ((expunge && (info->flags & CAMEL_MESSAGE_DELETED)) || - (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE))) + if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) || + (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_XEVCHANGE))) quick = FALSE; else - work |= (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0; - camel_folder_summary_info_free(s, info); + work |= (info->info.info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0; + camel_message_info_free(info); } /* yuck i hate this logic, but its to simplify the 'all ok, update summary' and failover cases */ @@ -888,7 +935,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh } lastdel = FALSE; - if ((flags&1) && info->info.flags & CAMEL_MESSAGE_DELETED) { + if ((flags&1) && info->info.info.flags & CAMEL_MESSAGE_DELETED) { const char *uid = camel_message_info_uid(info); d(printf("Deleting %s\n", uid)); @@ -899,7 +946,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh /* remove it from the change list */ camel_folder_change_info_remove_uid(changeinfo, uid); camel_folder_summary_remove(s, (CamelMessageInfo *)info); - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); count--; i--; info = NULL; @@ -915,7 +962,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh write(fdout, fromline, strlen(fromline)); } - if (info && info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) { + if (info && info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED)) { d(printf("Updating header for %s flags = %08x\n", camel_message_info_uid(info), info->info.flags)); if (camel_mime_parser_step(mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM_END) { @@ -923,11 +970,11 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh goto error; } - xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, (CamelMessageInfo *)info); + xevnew = camel_local_summary_encode_x_evolution((CamelLocalSummary *)cls, &info->info); #ifdef STATUS_PINE if (mbs->xstatus) { - encode_status(((CamelMessageInfo *)info)->flags & STATUS_STATUS, statnew); - encode_status(((CamelMessageInfo *)info)->flags & STATUS_XSTATUS, xstatnew); + encode_status(info->info.info.flags & STATUS_STATUS, statnew); + encode_status(info->info.info.flags & STATUS_XSTATUS, xstatnew); len = camel_local_summary_write_headers(fdout, camel_mime_parser_headers_raw(mp), xevnew, statnew, xstatnew); } else { #endif @@ -942,7 +989,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh g_strerror (errno)); goto error; } - info->info.flags &= 0xffff; + info->info.info.flags &= 0xffff; g_free(xevnew); xevnew = NULL; camel_mime_parser_drop_step(mp); @@ -972,7 +1019,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh d(printf("we are now at %d, from = %d\n", (int)camel_mime_parser_tell(mp), (int)camel_mime_parser_tell_start_from(mp))); camel_mime_parser_unstep(mp); - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); info = NULL; } } @@ -992,7 +1039,7 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh if (mp) camel_object_unref((CamelObject *)mp); if (info) - camel_folder_summary_info_free(s, (CamelMessageInfo *)info); + camel_message_info_free((CamelMessageInfo *)info); return -1; } @@ -1001,20 +1048,20 @@ camel_mbox_summary_sync_mbox(CamelMboxSummary *cls, guint32 flags, CamelFolderCh static CamelMessageInfo * mbox_summary_add(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *ci, CamelException *ex) { - CamelMessageInfo *mi; + CamelMboxMessageInfo *mi; - mi = ((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex); + mi = (CamelMboxMessageInfo *)((CamelLocalSummaryClass *)camel_mbox_summary_parent)->add(cls, msg, info, ci, ex); if (mi && ((CamelMboxSummary *)cls)->xstatus) { char status[8]; /* we snoop and add status/x-status headers to suit */ - encode_status(mi->flags & STATUS_STATUS, status); + encode_status(mi->info.info.flags & STATUS_STATUS, status); camel_medium_set_header((CamelMedium *)msg, "Status", status); - encode_status(mi->flags & STATUS_XSTATUS, status); + encode_status(mi->info.info.flags & STATUS_XSTATUS, status); camel_medium_set_header((CamelMedium *)msg, "X-Status", status); } - return mi; + return (CamelMessageInfo *)mi; } static struct { diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h index 34402ad264..9089fe7c8e 100644 --- a/camel/providers/local/camel-mbox-summary.h +++ b/camel/providers/local/camel-mbox-summary.h @@ -38,7 +38,7 @@ typedef struct _CamelMboxMessageContentInfo { } CamelMboxMessageContentInfo; typedef struct _CamelMboxMessageInfo { - CamelMessageInfo info; + CamelLocalMessageInfo info; off_t frompos; } CamelMboxMessageInfo; @@ -64,7 +64,7 @@ struct _CamelMboxSummaryClass { }; CamelType camel_mbox_summary_get_type (void); -CamelMboxSummary *camel_mbox_summary_new (const char *filename, const char *mbox_name, CamelIndex *index); +CamelMboxSummary *camel_mbox_summary_new (struct _CamelFolder *, const char *filename, const char *mbox_name, CamelIndex *index); /* do we honour/use xstatus headers, etc */ void camel_mbox_summary_xstatus(CamelMboxSummary *mbs, int state); diff --git a/camel/providers/local/camel-mh-folder.c b/camel/providers/local/camel-mh-folder.c index fd054933c5..1b054a4547 100644 --- a/camel/providers/local/camel-mh-folder.c +++ b/camel/providers/local/camel-mh-folder.c @@ -117,7 +117,7 @@ camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 fla static CamelLocalSummary *mh_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index) { - return (CamelLocalSummary *)camel_mh_summary_new(path, folder, index); + return (CamelLocalSummary *)camel_mh_summary_new((CamelFolder *)lf, path, folder, index); } static void @@ -205,7 +205,7 @@ static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, } /* we only need it to check the message exists */ - camel_folder_summary_info_free(folder->summary, info); + camel_message_info_free(info); name = g_strdup_printf("%s/%s", lf->folder_path, uid); if ((message_stream = camel_stream_fs_new_with_name(name, O_RDONLY, 0)) == NULL) { diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c index cc2f3ce9c9..03b6db92bd 100644 --- a/camel/providers/local/camel-mh-store.c +++ b/camel/providers/local/camel-mh-store.c @@ -324,7 +324,7 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags) root = camel_local_store_get_toplevel_dir((CamelLocalStore *)store); path = g_strdup_printf("%s/%s.ev-summary", root, fi->full_name); folderpath = g_strdup_printf("%s/%s", root, fi->full_name); - s = (CamelFolderSummary *)camel_mh_summary_new(path, folderpath, NULL); + s = (CamelFolderSummary *)camel_mh_summary_new(NULL, path, folderpath, NULL); if (camel_folder_summary_header_load(s) != -1) { fi->unread = s->unread_count; fi->total = s->saved_count; diff --git a/camel/providers/local/camel-mh-summary.c b/camel/providers/local/camel-mh-summary.c index d51bf7a108..fe0201e4f2 100644 --- a/camel/providers/local/camel-mh-summary.c +++ b/camel/providers/local/camel-mh-summary.c @@ -123,10 +123,12 @@ camel_mh_summary_finalise(CamelObject *obj) * * Return value: A new #CamelMhSummary object. **/ -CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index) +CamelMhSummary *camel_mh_summary_new(struct _CamelFolder *folder, const char *filename, const char *mhdir, CamelIndex *index) { CamelMhSummary *o = (CamelMhSummary *)camel_object_new(camel_mh_summary_get_type ()); + ((CamelFolderSummary *)o)->folder = folder; + camel_local_summary_construct((CamelLocalSummary *)o, filename, mhdir, index); return o; } @@ -204,7 +206,7 @@ remove_summary(char *key, CamelMessageInfo *info, CamelLocalSummary *cls) if (cls->index) camel_index_delete_name(cls->index, camel_message_info_uid(info)); camel_folder_summary_remove((CamelFolderSummary *)cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } static int @@ -272,7 +274,7 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came if (info != NULL) { g_hash_table_remove(left, camel_message_info_uid(info)); camel_folder_summary_remove((CamelFolderSummary *)cls, info); - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } camel_mh_summary_add(cls, d->d_name, forceindex); } else { @@ -280,10 +282,10 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came CamelMessageInfo *old = g_hash_table_lookup(left, uid); if (old) { - camel_folder_summary_info_free((CamelFolderSummary *)cls, old); + camel_message_info_free(old); g_hash_table_remove(left, uid); } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } } } @@ -300,7 +302,7 @@ mh_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, Came } static int -mh_summary_sync_message(CamelLocalSummary *cls, CamelMessageInfo *info, CamelException *ex) +mh_summary_sync_message(CamelLocalSummary *cls, CamelLocalMessageInfo *info, CamelException *ex) { CamelMimeParser *mp; const char *xev, *buffer; @@ -378,7 +380,7 @@ static int mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changes, CamelException *ex) { int count, i; - CamelMessageInfo *info; + CamelLocalMessageInfo *info; char *name; const char *uid; @@ -391,9 +393,9 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo count = camel_folder_summary_count((CamelFolderSummary *)cls); for (i=count-1;i>=0;i--) { - info = camel_folder_summary_index((CamelFolderSummary *)cls, i); + info = (CamelLocalMessageInfo *)camel_folder_summary_index((CamelFolderSummary *)cls, i); g_assert(info); - if (expunge && (info->flags & CAMEL_MESSAGE_DELETED)) { + if (expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) { uid = camel_message_info_uid(info); name = g_strdup_printf("%s/%s", cls->folder_path, uid); d(printf("deleting %s\n", name)); @@ -404,17 +406,17 @@ mh_summary_sync(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo camel_index_delete_name(cls->index, (char *)uid); camel_folder_change_info_remove_uid(changes, uid); - camel_folder_summary_remove((CamelFolderSummary *)cls, info); + camel_folder_summary_remove((CamelFolderSummary *)cls, (CamelMessageInfo *)info); } g_free(name); - } else if (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) { + } else if (info->info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV|CAMEL_MESSAGE_FOLDER_FLAGGED)) { if (mh_summary_sync_message(cls, info, ex) != -1) { - info->flags &= 0xffff; + info->info.flags &= 0xffff; } else { g_warning("Problem occured when trying to expunge, ignored"); } } - camel_folder_summary_info_free((CamelFolderSummary *)cls, info); + camel_message_info_free(info); } return ((CamelLocalSummaryClass *)parent_class)->sync(cls, expunge, changes, ex); diff --git a/camel/providers/local/camel-mh-summary.h b/camel/providers/local/camel-mh-summary.h index 4ee30df63b..d2fdcd1e4a 100644 --- a/camel/providers/local/camel-mh-summary.h +++ b/camel/providers/local/camel-mh-summary.h @@ -47,7 +47,7 @@ struct _CamelMhSummaryClass { }; CamelType camel_mh_summary_get_type (void); -CamelMhSummary *camel_mh_summary_new (const char *filename, const char *mhdir, CamelIndex *index); +CamelMhSummary *camel_mh_summary_new(struct _CamelFolder *, const char *filename, const char *mhdir, CamelIndex *index); #endif /* ! _CAMEL_MH_SUMMARY_H */ diff --git a/camel/providers/local/camel-spool-folder.c b/camel/providers/local/camel-spool-folder.c index b9cb643189..c4c7da91b6 100644 --- a/camel/providers/local/camel-spool-folder.c +++ b/camel/providers/local/camel-spool-folder.c @@ -160,7 +160,7 @@ spool_get_meta_path(CamelLocalFolder *lf, const char *toplevel_dir, const char * static CamelLocalSummary * spool_create_summary(CamelLocalFolder *lf, const char *path, const char *folder, CamelIndex *index) { - return (CamelLocalSummary *)camel_spool_summary_new(folder); + return (CamelLocalSummary *)camel_spool_summary_new((CamelFolder *)lf, folder); } static int diff --git a/camel/providers/local/camel-spool-summary.c b/camel/providers/local/camel-spool-summary.c index 3e4fb533ab..c8e074ae99 100644 --- a/camel/providers/local/camel-spool-summary.c +++ b/camel/providers/local/camel-spool-summary.c @@ -106,10 +106,12 @@ camel_spool_summary_finalise(CamelObject *obj) } CamelSpoolSummary * -camel_spool_summary_new(const char *mbox_name) +camel_spool_summary_new(struct _CamelFolder *folder, const char *mbox_name) { CamelSpoolSummary *new = (CamelSpoolSummary *)camel_object_new(camel_spool_summary_get_type()); + ((CamelFolderSummary *)new)->folder = folder; + camel_local_summary_construct((CamelLocalSummary *)new, NULL, mbox_name, NULL); return new; } @@ -318,10 +320,10 @@ spool_summary_check(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, C work = FALSE; count = camel_folder_summary_count(s); for (i=0;!work && i<count; i++) { - CamelMessageInfo *info = camel_folder_summary_index(s, i); + CamelMboxMessageInfo *info = (CamelMboxMessageInfo *)camel_folder_summary_index(s, i); g_assert(info); - work = (info->flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0; - camel_folder_summary_info_free(s, info); + work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0; + camel_message_info_free((CamelMessageInfo *)info); } /* if we do, then write out the headers using sync_full, etc */ diff --git a/camel/providers/local/camel-spool-summary.h b/camel/providers/local/camel-spool-summary.h index b72aeda527..2849c8cc20 100644 --- a/camel/providers/local/camel-spool-summary.h +++ b/camel/providers/local/camel-spool-summary.h @@ -47,7 +47,7 @@ CamelType camel_spool_summary_get_type (void); void camel_spool_summary_construct (CamelSpoolSummary *new, const char *filename, const char *spool_name, CamelIndex *index); /* create the summary, in-memory only */ -CamelSpoolSummary *camel_spool_summary_new(const char *filename); +CamelSpoolSummary *camel_spool_summary_new(struct _CamelFolder *, const char *filename); /* load/check the summary */ int camel_spool_summary_load(CamelSpoolSummary *cls, int forceindex, CamelException *ex); diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index 7f06555b43..de0f4cd222 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -511,7 +511,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti g_free(root); root = g_strdup_printf("%s.ev-summary", nntp_folder->storage_path); - folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (root); + folder->summary = (CamelFolderSummary *) camel_nntp_summary_new (folder, root); g_free(root); camel_folder_summary_load (folder->summary); diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c index bb2dda8809..213c6f9045 100644 --- a/camel/providers/nntp/camel-nntp-summary.c +++ b/camel/providers/nntp/camel-nntp-summary.c @@ -60,7 +60,7 @@ struct _CamelNNTPSummaryPrivate { #define _PRIVATE(o) (((CamelNNTPSummary *)(o))->priv) -static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _camel_header_raw *); +static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *); static int summary_header_load(CamelFolderSummary *, FILE *); static int summary_header_save(CamelFolderSummary *, FILE *); @@ -94,7 +94,7 @@ camel_nntp_summary_class_init(CamelNNTPSummaryClass *klass) camel_nntp_summary_parent = CAMEL_FOLDER_SUMMARY_CLASS(camel_type_get_global_classfuncs(camel_folder_summary_get_type())); - sklass->message_info_new = message_info_new; + sklass->message_info_new_from_header = message_info_new_from_header; sklass->summary_header_load = summary_header_load; sklass->summary_header_save = summary_header_save; } @@ -108,7 +108,7 @@ camel_nntp_summary_init(CamelNNTPSummary *obj) p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); /* subclasses need to set the right instance data sizes */ - s->message_info_size = sizeof(CamelMessageInfo); + s->message_info_size = sizeof(CamelMessageInfoBase); s->content_info_size = sizeof(CamelMessageContentInfo); /* and a unique file version */ @@ -124,10 +124,12 @@ camel_nntp_summary_finalise(CamelObject *obj) } CamelNNTPSummary * -camel_nntp_summary_new(const char *path) +camel_nntp_summary_new(struct _CamelFolder *folder, const char *path) { CamelNNTPSummary *cns = (CamelNNTPSummary *)camel_object_new(camel_nntp_summary_get_type()); + ((CamelFolderSummary *)cns)->folder = folder; + camel_folder_summary_set_filename((CamelFolderSummary *)cns, path); camel_folder_summary_set_build_content((CamelFolderSummary *)cns, FALSE); @@ -135,9 +137,9 @@ camel_nntp_summary_new(const char *path) } static CamelMessageInfo * -message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) +message_info_new_from_header(CamelFolderSummary *s, struct _camel_header_raw *h) { - CamelMessageInfo *mi; + CamelMessageInfoBase *mi; CamelNNTPSummary *cns = (CamelNNTPSummary *)s; /* error to call without this setup */ @@ -147,13 +149,13 @@ message_info_new(CamelFolderSummary *s, struct _camel_header_raw *h) /* we shouldn't be here if we already have this uid */ g_assert(camel_folder_summary_uid(s, cns->priv->uid) == NULL); - mi = ((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new(s, h); + mi = (CamelMessageInfoBase *)((CamelFolderSummaryClass *)camel_nntp_summary_parent)->message_info_new_from_header(s, h); if (mi) { - camel_message_info_set_uid(mi, cns->priv->uid); + mi->uid = g_strdup(cns->priv->uid); cns->priv->uid = NULL; } - return mi; + return (CamelMessageInfo *)mi; } static int @@ -207,7 +209,7 @@ static int add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, unsigned int low, CamelFolderChangeInfo *changes, CamelException *ex) { CamelFolderSummary *s; - CamelMessageInfo *mi; + CamelMessageInfoBase *mi; struct _camel_header_raw *headers = NULL; char *line, *tab; int len, ret; @@ -271,16 +273,16 @@ add_range_xover(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, /* truncated line? ignore? */ if (xover == NULL) { - mi = camel_folder_summary_uid(s, cns->priv->uid); + mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid); if (mi == NULL) { - mi = camel_folder_summary_add_from_header(s, headers); + mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header(s, headers); if (mi) { mi->size = size; cns->high = n; camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi)); } } else { - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); } } @@ -352,7 +354,7 @@ add_range_head(CamelNNTPSummary *cns, CamelNNTPStore *store, unsigned int high, camel_folder_change_info_add_uid(changes, camel_message_info_uid(mi)); } else { /* already have, ignore */ - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); } if (cns->priv->uid) { g_free(cns->priv->uid); @@ -445,7 +447,7 @@ camel_nntp_summary_check(CamelNNTPSummary *cns, CamelNNTPStore *store, char *lin i--; } - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); } } cns->low = f; @@ -473,12 +475,12 @@ update: count = camel_folder_summary_count(s); for (i = 0; i < count; i++) { - CamelMessageInfo *mi = camel_folder_summary_index(s, i); + CamelMessageInfoBase *mi = (CamelMessageInfoBase *)camel_folder_summary_index(s, i); if (mi) { if ((mi->flags & CAMEL_MESSAGE_SEEN) == 0) unread++; - camel_folder_summary_info_free(s, mi); + camel_message_info_free(mi); } } diff --git a/camel/providers/nntp/camel-nntp-summary.h b/camel/providers/nntp/camel-nntp-summary.h index fb58cea75a..2aff4319e1 100644 --- a/camel/providers/nntp/camel-nntp-summary.h +++ b/camel/providers/nntp/camel-nntp-summary.h @@ -48,7 +48,7 @@ struct _CamelNNTPSummaryClass { }; CamelType camel_nntp_summary_get_type (void); -CamelNNTPSummary *camel_nntp_summary_new(const char *path); +CamelNNTPSummary *camel_nntp_summary_new(struct _CamelFolder *folder, const char *path); int camel_nntp_summary_check(CamelNNTPSummary *cns, struct _CamelNNTPStore *store, char *line, struct _CamelFolderChangeInfo *changes, struct _CamelException *ex); |