From: Melvin H. <mha...@us...> - 2004-01-22 03:17:06
|
Update of /cvsroot/libetpan/xetpan/src In directory sc8-pr-cvs1:/tmp/cvs-serv26666/src Modified Files: folder.c Log Message: * src/folder.c: - Adjusted header for current libEtPan! - Infrastructure for virtual messages and folders - a_Folder_noop(): do not do another noop if we had to a_Folder_connect() - a_Message_free()-> a_Message->unref() - a_Folder_append_file_async(): check if there is a user_cb before calling it. - a_Folder_virtual_process_messages(): new function to add an array messages in a virtual folder - a_Folder_virtual_process_message(): new function to add one message in a virtual folder Index: folder.c =================================================================== RCS file: /cvsroot/libetpan/xetpan/src/folder.c,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- folder.c 15 Dec 2003 15:17:14 -0000 1.32 +++ folder.c 22 Jan 2004 03:17:03 -0000 1.33 @@ -26,7 +26,7 @@ #include <string.h> #include <errno.h> -#include <cinthash.h> +#include <libetpan/cinthash.h> #include "intl.h" @@ -38,6 +38,7 @@ #include "manager.h" #include "mailbox.h" #include "message.h" +#include "vmessage.h" #ifdef USE_PYTHON_WITH_THREAD_SUPPORT #include "xep-python.h" @@ -118,6 +119,8 @@ static uint32_t Folder_tree_get_total_count(struct mailmessage_tree *msg_tree); +#define XEP_FOLDER_VIRTUAL_INITIAL_SIZE 10 + #define XEP_FOLDER_RECONNECT_MAX_TRIES 5 #define XEP_FOLDER_HASH_SIZE 128 @@ -125,6 +128,7 @@ static chash *folder_ref_hash_table; static clist *global_folder_refs; + /* Function definitions */ XePFolder * @@ -183,22 +187,43 @@ switch (type) { case XEP_FOLDER_TYPE_MAILBOX: - /* We define mailbox wise processing rules */ + /* We can also define mailbox processing rules, + * so we initialize a mailbox-type folder as a real-type one: + */ case XEP_FOLDER_TYPE_REAL: folder->rule_refs = a_Processing_ref_list_new(); folder->folder_refs = NULL; folder->condition_refs = NULL; + folder->msg_attrs = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); + if (folder->msg_attrs == NULL) + goto err; + break; case XEP_FOLDER_TYPE_VIRTUAL: folder->rule_refs = NULL; folder->folder_refs = a_Folder_ref_list_new(); folder->condition_refs = a_Processing_ref_list_new(); + folder->vmessages = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); + folder->msg_attrs = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); + folder->ep_list = x_alloc(1, struct mailmessage_list); + if (folder->ep_list) + { + folder->ep_list->msg_tab = + carray_new(XEP_FOLDER_VIRTUAL_INITIAL_SIZE); + if (folder->ep_list->msg_tab == NULL) + goto err; + } + else + goto err; break; default: break; } } return folder; + err: + a_Folder_free(folder); + return NULL; } XePFolder * @@ -276,10 +301,16 @@ { case XEP_FOLDER_TYPE_REAL: a_Processing_ref_list_free(folder->rule_refs); + /* TODO: free all attributes */ + chash_free(folder->msg_attrs); break; case XEP_FOLDER_TYPE_VIRTUAL: a_Processing_ref_list_free(folder->condition_refs); a_Folder_ref_list_free(folder->folder_refs); + /* TODO: Remove all vmessages */ + chash_free(folder->vmessages); + /* TODO: free all attributes */ + chash_free(folder->msg_attrs); break; default: break; @@ -1320,8 +1351,8 @@ if (folder->ep_folder == NULL) { r = a_Folder_connect(folder); - if (r != MAIL_NO_ERROR) - return r; + /* a_Folder_connect() already does a NOOP */ + return r; } A_LOGGING_DEBUG("session NOOP"); @@ -1467,6 +1498,9 @@ { int r; + /* NOOP helps synchronising the server before an APPEND in + * case the IMAP MAILBOX was modified by another client + */ r = a_Folder_noop(folder); if (r != MAIL_NO_ERROR) return r; @@ -1777,7 +1811,7 @@ return; append_message->data = NULL; - a_Message_free(append_message); + a_Message_unref(append_message); message = append_data->message; A_LOGGING_DEBUG("Msg %d appended", message->msg->msg_index); free(append_data); @@ -1833,7 +1867,7 @@ a_Manager_msg_set_type(msg, XEP_MANAGER_APPEND); a_Manager_msg_set_source_target(msg, NULL, &folder->thread); /* NOTE 1: if the arg_out of XEP_MANAGER_APPEND changes - * the change the arguments of user_cb below at NOTE 2. + * thne change the arguments of user_cb below at NOTE 2. */ a_Manager_msg_set_args(msg, message, message); a_Manager_msg_add_callback(msg, Folder_append_file_cb, NULL); @@ -1847,7 +1881,8 @@ { A_LOGGING_ERROR("Message not sent."); /* NOTE 2: see NOTE 1 */ - user_cb(user_data, message); + if (user_cb) + user_cb(user_data, message); } } } @@ -1856,7 +1891,7 @@ Folder_append_file_cb(void *anull, void *amessage) { /* This will also close the opened tempfile */ - a_Message_free((XePMessage *) amessage); + a_Message_unref((XePMessage *) amessage); } void @@ -1971,7 +2006,7 @@ #ifdef USE_PYTHON_WITH_THREAD_SUPPORT XePManagerThread *thread = &folder_processing->folder->thread; - /* Get GIL, global interpreter lock */ + /* Get GIL (Global Interpreter Lock) */ thread->py_thread_state = a_XePPython_thread_state_new(); #endif @@ -2082,8 +2117,80 @@ /* Virtual folders */ +void +a_Folder_virtual_process_messages(XePFolder *folder, carray *messages) +{ + unsigned int i; + unsigned int count = carray_count(messages); + struct mailmessage_tree *env_tree; + int r; + + for (i = 0; i < count; i++) + a_Folder_virtual_process_message(folder, carray_get(messages, i)); + + /* FIXME: Do not hardcode the encoding (here UTF8) */ + r = mail_build_thread(MAIL_THREAD_REFERENCES_NO_SUBJECT, + "UTF8", + folder->ep_list, + &env_tree, + mailthread_tree_timecomp); + if (r == MAIL_NO_ERROR) + { + if (folder->ep_tree) + { + mailmessage_tree_free_recursive(folder->ep_tree); + } + folder->ep_tree = env_tree; + } + A_LOGGING_SYSTEM_ERROR("mail_build_thread(): %s", maildriver_strerror(r)); +} + int a_Folder_virtual_process_message(XePFolder *folder, XePMessage *message) { - return 0; + const char *condition_ref; + XePProcessingCondition *condition; + clistiter *iter; + int matched; + XePVMessage *vmessage; + + /* This assumes folder has conditions */ + for (iter = clist_begin(folder->condition_refs); iter; iter = iter->next) + { + condition_ref = (const char *) iter->data; + condition = a_Processing_condition_get_from_ref(condition_ref); + if (a_Processing_message_match(condition->tree, message)) + break; + } + + matched = (iter != NULL); + + vmessage = a_VMessage_get_from_uid(message->folder, message->uid); + + if (matched) + { + if (!vmessage) + { + vmessage = a_VMessage_new_from_message(message); + a_VMessage_ref_folder(vmessage, folder); + carray_add(folder->ep_list, message->msg, NULL); + } + return 0; + } + else + { + if (vmessage) + { + /* XXX: efficiently remove a vmessage from an array: + * to remove from an array: put the vmessage with greatest + * index in place of the removed one. + * To avoid searching for the index of the to-be-removed + * message, we store it in the attribute structure + */ + + + a_VMessage_unref_folder(vmessage, folder); + } + return -1; + } } |