diff options
author | 2014-07-24 12:04:10 -0700 | |
---|---|---|
committer | 2014-07-24 12:04:10 -0700 | |
commit | 108bb69dab1a0e6fcc17115c0e94feadaf820216 (patch) | |
tree | 26ac82f97fb499ae8624047b2643f11b6bbde0dd /src | |
parent | 1f243bb124f03e2b8710dc70f31010ab42cdf964 (diff) | |
parent | dfc73dd7ad39d13e2cb06b2a308dbab38105c786 (diff) |
Merge branch 'master' of https://github.com/MailCore/mailcore2 into iOS8AndLibCpp
Diffstat (limited to 'src')
22 files changed, 346 insertions, 196 deletions
diff --git a/src/async/imap/MCIMAPAppendMessageOperation.cc b/src/async/imap/MCIMAPAppendMessageOperation.cc index 06a42b2d..23eaaea0 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.cc +++ b/src/async/imap/MCIMAPAppendMessageOperation.cc @@ -18,6 +18,7 @@ IMAPAppendMessageOperation::IMAPAppendMessageOperation() mMessageData = NULL; mFlags = MessageFlagNone; mCustomFlags = NULL; + mDate = (time_t) -1; mCreatedUID = 0; } @@ -57,6 +58,16 @@ Array * IMAPAppendMessageOperation::customFlags() return customFlags(); } +void IMAPAppendMessageOperation::setDate(time_t date) +{ + mDate = date; +} + +time_t IMAPAppendMessageOperation::date() +{ + return mDate; +} + uint32_t IMAPAppendMessageOperation::createdUID() { return mCreatedUID; @@ -65,7 +76,7 @@ uint32_t IMAPAppendMessageOperation::createdUID() void IMAPAppendMessageOperation::main() { ErrorCode error; - session()->session()->appendMessageWithCustomFlags(folder(), mMessageData, mFlags, mCustomFlags, this, &mCreatedUID, &error); + session()->session()->appendMessageWithCustomFlagsAndDate(folder(), mMessageData, mFlags, mCustomFlags, mDate, this, &mCreatedUID, &error); setError(error); } diff --git a/src/async/imap/MCIMAPAppendMessageOperation.h b/src/async/imap/MCIMAPAppendMessageOperation.h index bca461d7..463d65d4 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.h +++ b/src/async/imap/MCIMAPAppendMessageOperation.h @@ -31,6 +31,9 @@ namespace mailcore { virtual void setCustomFlags(Array * customFlags); virtual Array * customFlags(); + virtual void setDate(time_t date); + virtual time_t date(); + virtual uint32_t createdUID(); public: // subclass behavior @@ -40,6 +43,7 @@ namespace mailcore { Data * mMessageData; MessageFlag mFlags; Array * mCustomFlags; + time_t mDate; uint32_t mCreatedUID; }; diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index c0ee27f1..1f1808df 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -333,43 +333,43 @@ IMAPFolderStatusOperation * IMAPAsyncSession::folderStatusOperation(String * fol IMAPFetchFoldersOperation * IMAPAsyncSession::fetchSubscribedFoldersOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->fetchSubscribedFoldersOperation(); } IMAPFetchFoldersOperation * IMAPAsyncSession::fetchAllFoldersOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->fetchAllFoldersOperation(); } IMAPOperation * IMAPAsyncSession::renameFolderOperation(String * folder, String * otherName) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->renameFolderOperation(folder, otherName); } IMAPOperation * IMAPAsyncSession::deleteFolderOperation(String * folder) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->deleteFolderOperation(folder); } IMAPOperation * IMAPAsyncSession::createFolderOperation(String * folder) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->createFolderOperation(folder); } IMAPOperation * IMAPAsyncSession::subscribeFolderOperation(String * folder) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->subscribeFolderOperation(folder); } IMAPOperation * IMAPAsyncSession::unsubscribeFolderOperation(String * folder) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->unsubscribeFolderOperation(folder); } @@ -457,43 +457,43 @@ IMAPIdleOperation * IMAPAsyncSession::idleOperation(String * folder, uint32_t la IMAPFetchNamespaceOperation * IMAPAsyncSession::fetchNamespaceOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->fetchNamespaceOperation(); } IMAPIdentityOperation * IMAPAsyncSession::identityOperation(IMAPIdentity * identity) { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->identityOperation(identity); } IMAPOperation * IMAPAsyncSession::connectOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->connectOperation(); } IMAPOperation * IMAPAsyncSession::checkAccountOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->checkAccountOperation(); } IMAPCapabilityOperation * IMAPAsyncSession::capabilityOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->capabilityOperation(); } IMAPQuotaOperation * IMAPAsyncSession::quotaOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->quotaOperation(); } IMAPOperation * IMAPAsyncSession::noopOperation() { - IMAPAsyncConnection * session = sessionForFolder(MCSTR("INBOX")); + IMAPAsyncConnection * session = sessionForFolder(NULL); return session->noopOperation(); } diff --git a/src/async/imap/MCIMAPQuotaOperation.cc b/src/async/imap/MCIMAPQuotaOperation.cc index 6744ac4b..2268a384 100644 --- a/src/async/imap/MCIMAPQuotaOperation.cc +++ b/src/async/imap/MCIMAPQuotaOperation.cc @@ -36,6 +36,12 @@ uint32_t IMAPQuotaOperation::usage() void IMAPQuotaOperation::main() { ErrorCode error; + session()->session()->loginIfNeeded(&error); + if (error != ErrorNone) { + setError(error); + return; + } + session()->session()->getQuota(&mUsage, &mLimit, &error); setError(error); } diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc index fb3e43cb..6d2d8066 100644 --- a/src/core/abstract/MCMessageHeader.cc +++ b/src/core/abstract/MCMessageHeader.cc @@ -2,6 +2,7 @@ #include "MCAddress.h" #include "MCIterator.h" +#include "MCLibetpan.h" #include <string.h> #include <unistd.h> @@ -9,12 +10,6 @@ using namespace mailcore; -static time_t timestamp_from_date(struct mailimf_date_time * date_time); -static struct mailimf_date_time * get_date_from_timestamp(time_t timeval); -static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time); -static time_t mkgmtime(struct tm * tmp); -static int tmcomp(struct tm * atmp, struct tm * btmp); - static struct mailimf_address_list * lep_address_list_from_array(Array * addresses); static struct mailimf_mailbox_list * lep_mailbox_list_from_array(Array * addresses); static Array * lep_address_list_from_lep_addr(struct mailimf_address_list * addr_list); @@ -388,7 +383,7 @@ void MessageHeader::importIMFFields(struct mailimf_fields * fields) if (single_fields.fld_orig_date != NULL) { time_t timestamp; - timestamp = timestamp_from_date(single_fields.fld_orig_date->dt_date_time); + timestamp = timestampFromDate(single_fields.fld_orig_date->dt_date_time); setDate(timestamp); setReceivedDate(timestamp); //MCLog("%lu %lu", (unsigned long) timestamp, date()); @@ -523,169 +518,6 @@ void MessageHeader::importIMFFields(struct mailimf_fields * fields) } } -static time_t timestamp_from_date(struct mailimf_date_time * date_time) -{ - struct tm tmval; - time_t timeval; - int zone_min; - int zone_hour; - - tmval.tm_sec = date_time->dt_sec; - tmval.tm_min = date_time->dt_min; - tmval.tm_hour = date_time->dt_hour; - tmval.tm_mday = date_time->dt_day; - tmval.tm_mon = date_time->dt_month - 1; - if (date_time->dt_year < 1000) { - // workaround when century is not given in year - tmval.tm_year = date_time->dt_year + 2000 - 1900; - } - else { - tmval.tm_year = date_time->dt_year - 1900; - } - - timeval = mkgmtime(&tmval); - - if (date_time->dt_zone >= 0) { - zone_hour = date_time->dt_zone / 100; - zone_min = date_time->dt_zone % 100; - } - else { - zone_hour = -((- date_time->dt_zone) / 100); - zone_min = -((- date_time->dt_zone) % 100); - } - timeval -= zone_hour * 3600 + zone_min * 60; - - return timeval; -} - -static struct mailimf_date_time * get_date_from_timestamp(time_t timeval) -{ - struct tm gmt; - struct tm lt; - int off; - struct mailimf_date_time * date_time; - int sign; - int hour; - int min; - - gmtime_r(&timeval, &gmt); - localtime_r(&timeval, <); - - off = (int) ((mkgmtime(<) - mkgmtime(&gmt)) / 60); - if (off < 0) { - sign = -1; - } - else { - sign = 1; - } - off = off * sign; - min = off % 60; - hour = off / 60; - off = hour * 100 + min; - off = off * sign; - - date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, - lt.tm_year + 1900, - lt.tm_hour, lt.tm_min, lt.tm_sec, - off); - - return date_time; -} - -static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time) -{ - struct tm tmval; - time_t timeval; - int zone_min; - int zone_hour; - - tmval.tm_sec = date_time->dt_sec; - tmval.tm_min = date_time->dt_min; - tmval.tm_hour = date_time->dt_hour; - tmval.tm_mday = date_time->dt_day; - tmval.tm_mon = date_time->dt_month - 1; - if (date_time->dt_year < 1000) { - // workaround when century is not given in year - tmval.tm_year = date_time->dt_year + 2000 - 1900; - } - else { - tmval.tm_year = date_time->dt_year - 1900; - } - - timeval = mkgmtime(&tmval); - - if (date_time->dt_zone >= 0) { - zone_hour = date_time->dt_zone / 100; - zone_min = date_time->dt_zone % 100; - } - else { - zone_hour = -((- date_time->dt_zone) / 100); - zone_min = -((- date_time->dt_zone) % 100); - } - timeval -= zone_hour * 3600 + zone_min * 60; - - return timeval; -} - -#define INVALID_TIMESTAMP (-1) - -static int tmcomp(struct tm * atmp, struct tm * btmp) -{ - int result; - - if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && - (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && - (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && - (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && - (result = (atmp->tm_min - btmp->tm_min)) == 0) - result = atmp->tm_sec - btmp->tm_sec; - return result; -} - -static time_t mkgmtime(struct tm * tmp) -{ - int dir; - int bits; - int saved_seconds; - time_t t; - struct tm yourtm, mytm; - - yourtm = *tmp; - saved_seconds = yourtm.tm_sec; - yourtm.tm_sec = 0; - /* - ** Calculate the number of magnitude bits in a time_t - ** (this works regardless of whether time_t is - ** signed or unsigned, though lint complains if unsigned). - */ - for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) - ; - /* - ** If time_t is signed, then 0 is the median value, - ** if time_t is unsigned, then 1 << bits is median. - */ - if(bits > 40) bits = 40; - t = (t < 0) ? 0 : ((time_t) 1 << bits); - for ( ; ; ) { - gmtime_r(&t, &mytm); - dir = tmcomp(&mytm, &yourtm); - if (dir != 0) { - if (bits-- < 0) { - return INVALID_TIMESTAMP; - } - if (bits < 0) - --t; - else if (dir > 0) - t -= (time_t) 1 << bits; - else t += (time_t) 1 << bits; - continue; - } - break; - } - t += saved_seconds; - return t; -} - #pragma mark RFC 2822 mailbox conversion static Array * lep_address_list_from_lep_mailbox(struct mailimf_mailbox_list * mb_list) @@ -851,7 +683,7 @@ struct mailimf_fields * MessageHeader::createIMFFieldsAndFilterBcc(bool filterBc imfDate = NULL; if (date() != (time_t) -1) { //MCLog("%lu", date()); - imfDate = get_date_from_timestamp(date()); + imfDate = dateFromTimestamp(date()); } imfFrom = NULL; if (from() != NULL) { @@ -952,7 +784,7 @@ void MessageHeader::importIMAPEnvelope(struct mailimap_envelope * env) time_t timestamp; // date - timestamp = timestamp_from_date(date_time); + timestamp = timestampFromDate(date_time); setDate(timestamp); setReceivedDate(timestamp); mailimf_date_time_free(date_time); @@ -964,7 +796,7 @@ void MessageHeader::importIMAPEnvelope(struct mailimap_envelope * env) if (r == MAILIMAP_NO_ERROR) { time_t timestamp; - timestamp = timestamp_from_imap_date(imap_date); + timestamp = timestampFromIMAPDate(imap_date); setDate(timestamp); setReceivedDate(timestamp); mailimap_date_time_free(imap_date); @@ -1132,7 +964,7 @@ void MessageHeader::importIMAPReferences(Data * data) void MessageHeader::importIMAPInternalDate(struct mailimap_date_time * date) { - setReceivedDate(timestamp_from_imap_date(date)); + setReceivedDate(timestampFromIMAPDate(date)); } Array * MessageHeader::recipientWithReplyAll(bool replyAll, bool includeTo, bool includeCc, Array * senderEmails) diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc index 15e9a2be..43ee6bd4 100644 --- a/src/core/basetypes/MCArray.cc +++ b/src/core/basetypes/MCArray.cc @@ -212,7 +212,6 @@ static int sortCompare(Object ** pa, Object ** pb, struct sortData * data) Array * Array::sortedArray(int (* compare)(void * a, void * b, void * context), void * context) { - struct sortData data; Array * result = (Array *) this->copy()->autorelease(); result->sortArray(compare, context); return result; diff --git a/src/core/basetypes/MCHTMLCleaner.cc b/src/core/basetypes/MCHTMLCleaner.cc index 079163bf..81145c9e 100644 --- a/src/core/basetypes/MCHTMLCleaner.cc +++ b/src/core/basetypes/MCHTMLCleaner.cc @@ -43,6 +43,8 @@ String * HTMLCleaner::cleanHTML(String * input) tidyOptSetBool(tdoc, TidyDropEmptyElems, no); #endif tidyOptSetBool(tdoc, TidyXhtmlOut, yes); + tidyOptSetInt(tdoc, TidyDoctypeMode, TidyDoctypeUser); + tidyOptSetBool(tdoc, TidyMark, no); tidySetCharEncoding(tdoc, "utf8"); tidyOptSetBool(tdoc, TidyForceOutput, yes); diff --git a/src/core/basetypes/MCLibetpan.cc b/src/core/basetypes/MCLibetpan.cc index fcc1b772..1779d605 100644 --- a/src/core/basetypes/MCLibetpan.cc +++ b/src/core/basetypes/MCLibetpan.cc @@ -10,9 +10,211 @@ #include <libetpan/libetpan.h> +using namespace mailcore; + +static time_t mkgmtime(struct tm * tmp); +static int tmcomp(struct tm * atmp, struct tm * btmp); + __attribute__((constructor)) static void initialize() { // It will enable CFStream on platforms that supports it. mailstream_cfstream_enabled = 1; } + +time_t mailcore::timestampFromDate(struct mailimf_date_time * date_time) +{ + struct tm tmval; + time_t timeval; + int zone_min; + int zone_hour; + + tmval.tm_sec = date_time->dt_sec; + tmval.tm_min = date_time->dt_min; + tmval.tm_hour = date_time->dt_hour; + tmval.tm_mday = date_time->dt_day; + tmval.tm_mon = date_time->dt_month - 1; + if (date_time->dt_year < 1000) { + // workaround when century is not given in year + tmval.tm_year = date_time->dt_year + 2000 - 1900; + } + else { + tmval.tm_year = date_time->dt_year - 1900; + } + + timeval = mkgmtime(&tmval); + + if (date_time->dt_zone >= 0) { + zone_hour = date_time->dt_zone / 100; + zone_min = date_time->dt_zone % 100; + } + else { + zone_hour = -((- date_time->dt_zone) / 100); + zone_min = -((- date_time->dt_zone) % 100); + } + timeval -= zone_hour * 3600 + zone_min * 60; + + return timeval; +} + +struct mailimf_date_time * mailcore::dateFromTimestamp(time_t timeval) +{ + struct tm gmt; + struct tm lt; + int off; + struct mailimf_date_time * date_time; + int sign; + int hour; + int min; + + gmtime_r(&timeval, &gmt); + localtime_r(&timeval, <); + + off = (int) ((mkgmtime(<) - mkgmtime(&gmt)) / 60); + if (off < 0) { + sign = -1; + } + else { + sign = 1; + } + off = off * sign; + min = off % 60; + hour = off / 60; + off = hour * 100 + min; + off = off * sign; + + date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, + lt.tm_year + 1900, + lt.tm_hour, lt.tm_min, lt.tm_sec, + off); + + return date_time; +} + +struct mailimap_date_time * mailcore::imapDateFromTimestamp(time_t timeval) +{ + struct tm gmt; + struct tm lt; + int off; + struct mailimap_date_time * date_time; + int sign; + int hour; + int min; + + gmtime_r(&timeval, &gmt); + localtime_r(&timeval, <); + + off = (int) ((mkgmtime(<) - mkgmtime(&gmt)) / 60); + if (off < 0) { + sign = -1; + } + else { + sign = 1; + } + off = off * sign; + min = off % 60; + hour = off / 60; + off = hour * 100 + min; + off = off * sign; + + date_time = mailimap_date_time_new(lt.tm_mday, lt.tm_mon + 1, + lt.tm_year + 1900, + lt.tm_hour, lt.tm_min, lt.tm_sec, + off); + + return date_time; +} + +time_t mailcore::timestampFromIMAPDate(struct mailimap_date_time * date_time) +{ + struct tm tmval; + time_t timeval; + int zone_min; + int zone_hour; + + tmval.tm_sec = date_time->dt_sec; + tmval.tm_min = date_time->dt_min; + tmval.tm_hour = date_time->dt_hour; + tmval.tm_mday = date_time->dt_day; + tmval.tm_mon = date_time->dt_month - 1; + if (date_time->dt_year < 1000) { + // workaround when century is not given in year + tmval.tm_year = date_time->dt_year + 2000 - 1900; + } + else { + tmval.tm_year = date_time->dt_year - 1900; + } + + timeval = mkgmtime(&tmval); + + if (date_time->dt_zone >= 0) { + zone_hour = date_time->dt_zone / 100; + zone_min = date_time->dt_zone % 100; + } + else { + zone_hour = -((- date_time->dt_zone) / 100); + zone_min = -((- date_time->dt_zone) % 100); + } + timeval -= zone_hour * 3600 + zone_min * 60; + + return timeval; +} + +#define INVALID_TIMESTAMP (-1) + +static int tmcomp(struct tm * atmp, struct tm * btmp) +{ + int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t mkgmtime(struct tm * tmp) +{ + int dir; + int bits; + int saved_seconds; + time_t t; + struct tm yourtm, mytm; + + yourtm = *tmp; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + /* + ** Calculate the number of magnitude bits in a time_t + ** (this works regardless of whether time_t is + ** signed or unsigned, though lint complains if unsigned). + */ + for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) + ; + /* + ** If time_t is signed, then 0 is the median value, + ** if time_t is unsigned, then 1 << bits is median. + */ + if(bits > 40) bits = 40; + t = (t < 0) ? 0 : ((time_t) 1 << bits); + for ( ; ; ) { + gmtime_r(&t, &mytm); + dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (bits-- < 0) { + return INVALID_TIMESTAMP; + } + if (bits < 0) + --t; + else if (dir > 0) + t -= (time_t) 1 << bits; + else t += (time_t) 1 << bits; + continue; + } + break; + } + t += saved_seconds; + return t; +} diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h index 9670a47b..41024137 100644 --- a/src/core/basetypes/MCLibetpan.h +++ b/src/core/basetypes/MCLibetpan.h @@ -10,6 +10,16 @@ #define MAILCORE_MCLIBETPAN_H -// No API in this file. +#include <time.h> +#include <libetpan/libetpan.h> + +namespace mailcore { + + time_t timestampFromDate(struct mailimf_date_time * date_time); + time_t timestampFromIMAPDate(struct mailimap_date_time * date_time); + struct mailimf_date_time * dateFromTimestamp(time_t timeval); + struct mailimap_date_time * imapDateFromTimestamp(time_t timeval); + +} #endif diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 9a740ef6..e45f04ee 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -28,6 +28,7 @@ OperationQueue::OperationQueue() #if __APPLE__ mDispatchQueue = dispatch_get_main_queue(); #endif + _pendingCheckRunning = false; } OperationQueue::~OperationQueue() @@ -175,12 +176,19 @@ void OperationQueue::callbackOnMainThread(Operation * op) void OperationQueue::checkRunningOnMainThread(void * context) { - cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL); + retain(); // (4) + if (_pendingCheckRunning) { + cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL); + release(); // (4) + } + _pendingCheckRunning = true; performMethodAfterDelay((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, 1); + release(); // (1) } void OperationQueue::checkRunningAfterDelay(void * context) { + _pendingCheckRunning = false; pthread_mutex_lock(&mLock); if (!mQuitting) { if (mOperations->count() == 0) { @@ -194,7 +202,7 @@ void OperationQueue::checkRunningAfterDelay(void * context) // Number of operations can't be changed because it runs on main thread. // And addOperation() should also be called from main thread. - release(); // (1) + release(); // (4) } void OperationQueue::stoppedOnMainThread(void * context) diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index b5f29143..119befcc 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -48,6 +48,7 @@ namespace mailcore { #if __APPLE__ dispatch_queue_t mDispatchQueue; #endif + bool _pendingCheckRunning; void startThread(); static void runOperationsOnThread(OperationQueue * queue); diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 09ee841d..768b5c98 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -23,6 +23,7 @@ #include "MCHTMLBodyRendererTemplateCallback.h" #include "MCCertificateUtils.h" #include "MCIMAPIdentity.h" +#include "MCLibetpan.h" using namespace mailcore; @@ -1589,6 +1590,12 @@ void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError) { + this->appendMessageWithCustomFlagsAndDate(folder, messageData, flags, NULL, (time_t) -1, progressCallback, createdUID, pError); +} + +void IMAPSession::appendMessageWithCustomFlagsAndDate(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, time_t date, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError) +{ int r; struct mailimap_flag_list * flag_list; uint32_t uidvalidity; @@ -1612,8 +1619,15 @@ void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageDa mailimap_flag_list_add(flag_list, f); } } - r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, NULL, messageData->bytes(), messageData->length(), + struct mailimap_date_time * imap_date = NULL; + if (date != (time_t) -1) { + imap_date = imapDateFromTimestamp(date); + } + r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, imap_date, messageData->bytes(), messageData->length(), &uidvalidity, &uidresult); + if (imap_date != NULL) { + mailimap_date_time_free(imap_date); + } mailimap_flag_list_free(flag_list); bodyProgress(messageData->length(), messageData->length()); @@ -1655,6 +1669,7 @@ void IMAPSession::copyMessages(String * folder, IndexSet * uidSet, String * dest set = setFromIndexSet(uidSet); if (clist_count(set->set_list) == 0) { + mailimap_set_free(set); return; } @@ -2433,8 +2448,10 @@ Array * IMAPSession::fetchMessagesByUIDWithExtraHeaders(String * folder, IMAPMes struct mailimap_set * imapset = setFromIndexSet(uids); IMAPSyncResult * syncResult = fetchMessages(folder, requestKind, true, imapset, 0, NULL, 0, progressCallback, extraHeaders, pError); - if (syncResult == NULL) + if (syncResult == NULL) { + mailimap_set_free(imapset); return NULL; + } Array * result = syncResult->modifiedOrAddedMessages(); result->retain()->autorelease(); mailimap_set_free(imapset); @@ -2455,8 +2472,10 @@ Array * IMAPSession::fetchMessagesByNumberWithExtraHeaders(String * folder, IMAP struct mailimap_set * imapset = setFromIndexSet(numbers); IMAPSyncResult * syncResult = fetchMessages(folder, requestKind, false, imapset, 0, NULL, 0, progressCallback, extraHeaders, pError); - if (syncResult == NULL) + if (syncResult == NULL) { + mailimap_set_free(imapset); return NULL; + } Array * result = syncResult->modifiedOrAddedMessages(); result->retain()->autorelease(); mailimap_set_free(imapset); @@ -3293,6 +3312,7 @@ void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMA imap_set = setFromIndexSet(uids); if (clist_count(imap_set->set_list) == 0) { + mailimap_set_free(imap_set); return; } @@ -3424,6 +3444,7 @@ void IMAPSession::storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRe imap_set = setFromIndexSet(uids); if (clist_count(imap_set->set_list) == 0) { + mailimap_set_free(imap_set); return; } @@ -3607,6 +3628,10 @@ void IMAPSession::capabilitySetWithSessionState(IndexSet * capabilities) if (mailimap_has_compress_deflate(mImap)) { capabilities->addIndex(IMAPCapabilityCompressDeflate); } + if (mailimap_has_extension(mImap, (char *)"CHILDREN")) { + capabilities->addIndex(IMAPCapabilityChildren); + } + applyCapabilities(capabilities); } diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 9ebe48d6..e52dc74f 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -83,6 +83,8 @@ namespace mailcore { IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); virtual void appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); + virtual void appendMessageWithCustomFlagsAndDate(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, time_t date, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); void copyMessages(String * folder, IndexSet * uidSet, String * destFolder, HashMap ** pUidMapping, ErrorCode * pError); diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc index 384bb4e5..cd87009e 100644 --- a/src/core/rfc822/MCMessageBuilder.cc +++ b/src/core/rfc822/MCMessageBuilder.cc @@ -580,6 +580,9 @@ Array * MessageBuilder::attachments() void MessageBuilder::addAttachment(Attachment * attachment) { + if (attachment == NULL) { + return; + } if (mAttachments == NULL) { mAttachments = new Array(); } @@ -598,6 +601,9 @@ Array * MessageBuilder::relatedAttachments() void MessageBuilder::addRelatedAttachment(Attachment * attachment) { + if (attachment == NULL) { + return; + } if (mRelatedAttachments == NULL) { mRelatedAttachments = new Array(); } diff --git a/src/core/rfc822/MCMessageParser.cc b/src/core/rfc822/MCMessageParser.cc index 0366d597..d5bf84e7 100644 --- a/src/core/rfc822/MCMessageParser.cc +++ b/src/core/rfc822/MCMessageParser.cc @@ -30,6 +30,25 @@ void MessageParser::init() MessageParser::MessageParser(Data * data) { init(); + + const char * start = NULL; + unsigned int length = 0; + if (data->length() > 5) { + if (strncmp(data->bytes(), "From ", 5) == 0) { + start = data->bytes(); + for(unsigned int i = 0 ; i < data->length() ; i ++) { + if (start[i] == '\n') { + start = start + i + 1; + length = data->length() - (i + 1); + break; + } + } + } + } + if (start != NULL) { + data = Data::dataWithBytes(start, length); + } + mData = (Data *) data->retain(); mailmessage * msg; diff --git a/src/objc/imap/MCOIMAPAppendMessageOperation.h b/src/objc/imap/MCOIMAPAppendMessageOperation.h index 04d64594..1e5fbd39 100644 --- a/src/objc/imap/MCOIMAPAppendMessageOperation.h +++ b/src/objc/imap/MCOIMAPAppendMessageOperation.h @@ -17,6 +17,8 @@ @interface MCOIMAPAppendMessageOperation : MCOIMAPBaseOperation +@property (nonatomic, assign) time_t date; + /** This block will be called as bytes are sent */ diff --git a/src/objc/imap/MCOIMAPAppendMessageOperation.mm b/src/objc/imap/MCOIMAPAppendMessageOperation.mm index 042324b3..2dd16ced 100644 --- a/src/objc/imap/MCOIMAPAppendMessageOperation.mm +++ b/src/objc/imap/MCOIMAPAppendMessageOperation.mm @@ -78,4 +78,6 @@ typedef void (^CompletionType)(NSError *error, uint32_t createdUID); } } +MCO_OBJC_SYNTHESIZE_SCALAR(time_t, time_t, setDate, date) + @end diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 101f7953..7a35b7e3 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -117,7 +117,11 @@ It will make MCOIMAPSession safe. It will also set all the callbacks of operations to run on this given queue. Defaults to the main queue. This property should be used only if there's performance issue using MCOIMAPSession in the main thread. */ +#if OS_OBJECT_USE_OBJC @property (nonatomic, retain) dispatch_queue_t dispatchQueue; +#else +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; +#endif /** The value will be YES when asynchronous operations are running, else it will return NO. diff --git a/src/objc/pop/MCOPOPSession.h b/src/objc/pop/MCOPOPSession.h index 74ed216b..719b65b7 100644 --- a/src/objc/pop/MCOPOPSession.h +++ b/src/objc/pop/MCOPOPSession.h @@ -66,7 +66,11 @@ See MCOConnectionType for more information.*/ It will make MCOPOPSession safe. It will also set all the callbacks of operations to run on this given queue. Defaults to the main queue. This property should be used only if there's performance issue using MCOPOPSession in the main thread. */ +#if OS_OBJECT_USE_OBJC @property (nonatomic, retain) dispatch_queue_t dispatchQueue; +#else +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; +#endif /** @name Operations */ diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h index 8e5deaa3..5c616244 100644 --- a/src/objc/smtp/MCOSMTPSession.h +++ b/src/objc/smtp/MCOSMTPSession.h @@ -80,7 +80,11 @@ It will make MCOSMTPSession safe. It will also set all the callbacks of operations to run on this given queue. Defaults to the main queue. This property should be used only if there's performance issue using MCOSMTPSession in the main thread. */ +#if OS_OBJECT_USE_OBJC @property (nonatomic, retain) dispatch_queue_t dispatchQueue; +#else +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; +#endif /** @name Operations */ diff --git a/src/objc/utils/MCOOperation.h b/src/objc/utils/MCOOperation.h index b42dfbef..e3aa758a 100644 --- a/src/objc/utils/MCOOperation.h +++ b/src/objc/utils/MCOOperation.h @@ -23,7 +23,11 @@ /** The queue this operation dispatches the callback on. Defaults to the main queue. This property should be used only if there's performance issue creating or calling the callback in the main thread. */ +#if OS_OBJECT_USE_OBJC @property (nonatomic, retain) dispatch_queue_t callbackDispatchQueue; +#else +@property (nonatomic, assign) dispatch_queue_t callbackDispatchQueue; +#endif /** This methods is called on the main thread when the asynchronous operation is finished. Needs to be overriden by subclasses.*/ diff --git a/src/objc/utils/NSArray+MCO.mm b/src/objc/utils/NSArray+MCO.mm index 022960f0..061f8429 100644 --- a/src/objc/utils/NSArray+MCO.mm +++ b/src/objc/utils/NSArray+MCO.mm @@ -21,6 +21,9 @@ + (NSArray *) mco_arrayWithMCArray:(mailcore::Array *)array { + if (array == NULL) { + return nil; + } NSMutableArray * result = [NSMutableArray array]; for(unsigned int i = 0 ; i < array->count() ; i ++) { [result addObject:[NSObject mco_objectWithMCObject:array->objectAtIndex(i)]]; |