From e178892b3ba41280241284ecaed444f0763c897b Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 22 Jun 2013 12:25:02 -0700 Subject: Automatic disconnection for SMTP (Fixed #96) --- build-mac/mailcore2.xcodeproj/project.pbxproj | 10 ++++ src/async/smtp/MCSMTPAsyncSession.cc | 60 +++++++++++++--------- src/async/smtp/MCSMTPAsyncSession.h | 12 +++-- src/async/smtp/MCSMTPDisconnectOperation.cc | 29 +++++++++++ src/async/smtp/MCSMTPDisconnectOperation.h | 32 ++++++++++++ src/async/smtp/MCSMTPOperation.cc | 1 - src/async/smtp/MCSMTPSendWithDataOperation.cc | 2 + src/core/basetypes/MCMainThread.h | 11 +++-- src/core/basetypes/MCMainThread.mm | 9 +++- src/core/basetypes/MCObject.cc | 71 ++++++++++++++++++++++++++- src/core/basetypes/MCObject.h | 1 + src/core/basetypes/MCOperationQueue.cc | 20 +++++++- src/core/basetypes/MCOperationQueue.h | 65 +++++++++++++----------- src/core/basetypes/MCOperationQueueCallback.h | 22 +++++++++ src/core/smtp/MCSMTPSession.cc | 4 ++ src/core/smtp/MCSMTPSession.h | 3 ++ 16 files changed, 286 insertions(+), 66 deletions(-) create mode 100644 src/async/smtp/MCSMTPDisconnectOperation.cc create mode 100644 src/async/smtp/MCSMTPDisconnectOperation.h create mode 100644 src/core/basetypes/MCOperationQueueCallback.h diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 37a955c6..54e21f12 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ C07AD5D7FD82F8ACAB576231 /* NSError+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C07AD44B013BB42A240B4F04 /* NSError+MCO.h */; }; C07AD99B2E2054C684DB8FF6 /* NSError+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */; }; C07ADC28B83E7959BF114D46 /* MCOIMAPSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */; }; + C608167517759967001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; }; + C608167617759968001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; }; C623C58616FD6A50001BBEFC /* MCOConstants.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB26D16FD63F6000DB34C /* MCOConstants.h */; }; C623C58716FD6A61001BBEFC /* MCOOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25716FD3BC2000DB34C /* MCOOperation.h */; }; C623C58816FD6DF6001BBEFC /* NSValue+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25016FC2846000DB34C /* NSValue+MCO.h */; }; @@ -1072,6 +1074,9 @@ C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPSession.mm; sourceTree = ""; }; C07AD44B013BB42A240B4F04 /* NSError+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MCO.h"; sourceTree = ""; }; C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+MCO.mm"; sourceTree = ""; }; + C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCSMTPDisconnectOperation.cc; sourceTree = ""; }; + C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCSMTPDisconnectOperation.h; sourceTree = ""; }; + C6081678177625AD001F1018 /* MCOperationQueueCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOperationQueueCallback.h; sourceTree = ""; }; C623C58A16FD8C22001BBEFC /* MCOAbstractMessage+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOAbstractMessage+Private.h"; sourceTree = ""; }; C623C58B16FE52C0001BBEFC /* MCOHTMLRendererDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOHTMLRendererDelegate.h; sourceTree = ""; }; C623C58D16FE6B45001BBEFC /* MCOIMAPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPOperation.h; sourceTree = ""; }; @@ -1704,6 +1709,8 @@ C64EA690169E847800778456 /* MCSMTPAsyncSession.h */, C64EA79C169F29A700778456 /* MCSMTPSendWithDataOperation.cc */, C64EA79D169F29A700778456 /* MCSMTPSendWithDataOperation.h */, + C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */, + C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */, C64EA7D816A1386500778456 /* MCSMTPOperation.cc */, C64EA7D916A1386600778456 /* MCSMTPOperation.h */, C64EA7E116A1425400778456 /* MCSMTPOperationCallback.h */, @@ -1797,6 +1804,7 @@ C64EA6C0169E847800778456 /* MCOperationCallback.h */, C64EA6C1169E847800778456 /* MCOperationQueue.cc */, C64EA6C2169E847800778456 /* MCOperationQueue.h */, + C6081678177625AD001F1018 /* MCOperationQueueCallback.h */, C63CD68F16BE566D00DB18F1 /* MCHTMLCleaner.cc */, C63CD69016BE566E00DB18F1 /* MCHTMLCleaner.h */, C64BB22C16E5C1EE000DB34C /* MCIndexSet.cc */, @@ -2419,6 +2427,7 @@ C6F61F9917016B460073032E /* MCOIMAPSearchExpression.mm in Sources */, C6F61F9F17016EA10073032E /* MCOIMAPFolderInfo.m in Sources */, C6F61FB51702AB340073032E /* MCOIMAPBaseOperation.mm in Sources */, + C608167517759967001F1018 /* MCSMTPDisconnectOperation.cc in Sources */, C6A81BBF17068E5E00882C15 /* MCOSMTPSession.mm in Sources */, C6A81BC317068E9500882C15 /* MCOSMTPSendOperation.mm in Sources */, C6A81BC717068EB000882C15 /* MCOSMTPOperation.mm in Sources */, @@ -2597,6 +2606,7 @@ C6BA2C121705F4E6003F0E9E /* MCOIMAPSearchExpression.mm in Sources */, C6BA2C131705F4E6003F0E9E /* MCOIMAPFolderInfo.m in Sources */, C6BA2C141705F4E6003F0E9E /* MCOIMAPBaseOperation.mm in Sources */, + C608167617759968001F1018 /* MCSMTPDisconnectOperation.cc in Sources */, C6A81BC017068E5E00882C15 /* MCOSMTPSession.mm in Sources */, C6A81BC417068E9500882C15 /* MCOSMTPSendOperation.mm in Sources */, C6A81BC817068EB000882C15 /* MCOSMTPOperation.mm in Sources */, diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc index 95101a50..776587e6 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cc +++ b/src/async/smtp/MCSMTPAsyncSession.cc @@ -1,18 +1,39 @@ #include "MCSMTPAsyncSession.h" #include "MCSMTPSession.h" -//#include "MCSMTPSendWithRecipientOperation.h" #include "MCSMTPSendWithDataOperation.h" -//#include "MCSMTPSendWithBuilderOperation.h" #include "MCSMTPCheckAccountOperation.h" +#include "MCSMTPDisconnectOperation.h" #include "MCSMTPOperation.h" +#include "MCOperationQueueCallback.h" using namespace mailcore; +namespace mailcore { + class SMTPOperationQueueCallback : public OperationQueueCallback { + public: + SMTPOperationQueueCallback(SMTPAsyncSession * session) { + mSession = session; + } + + virtual ~SMTPOperationQueueCallback() { + } + + virtual void queueIdle() { + mSession->tryAutomaticDisconnect(); + } + + private: + SMTPAsyncSession * mSession; + }; +} + SMTPAsyncSession::SMTPAsyncSession() { mSession = new SMTPSession(); mQueue = new OperationQueue(); + mQueueCallback = new SMTPOperationQueueCallback(this); + mQueue->setCallback(mQueueCallback); } SMTPAsyncSession::~SMTPAsyncSession() @@ -113,7 +134,7 @@ bool SMTPAsyncSession::useHeloIPEnabled() void SMTPAsyncSession::runOperation(SMTPOperation * operation) { -#warning disconnect after delay + cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL); mQueue->addOperation(operation); } @@ -122,35 +143,31 @@ SMTPSession * SMTPAsyncSession::session() return mSession; } -#if 0 -SMTPOperation * SMTPAsyncSession::sendMessageOperationWithFromAndRecipient(Address * from, Array * recipients, Data * messageData) +void SMTPAsyncSession::tryAutomaticDisconnect() { - SMTPSendWithRecipientOperation * op = new SMTPSendWithRecipientOperation(); - op->setSession(this); - op->setFrom(from); - op->setRecipients(recipients); - op->setMessageData(messageData); - return (SMTPOperation *) op->autorelease(); + // It's safe since no thread is running when this function is called. + if (mSession->isDisconnected()) { + return; + } + + performMethodAfterDelay((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL, 30); } -#endif -SMTPOperation * SMTPAsyncSession::sendMessageOperation(Data * messageData) +void SMTPAsyncSession::tryAutomaticDisconnectAfterDelay(void * context) { - SMTPSendWithDataOperation * op = new SMTPSendWithDataOperation(); + SMTPDisconnectOperation * op = new SMTPDisconnectOperation(); op->setSession(this); - op->setMessageData(messageData); - return (SMTPOperation *) op->autorelease(); + op->autorelease(); + op->start(); } -#if 0 -SMTPOperation * SMTPAsyncSession::sendMessageOperation(MessageBuilder * msg) +SMTPOperation * SMTPAsyncSession::sendMessageOperation(Data * messageData) { - SMTPSendWithBuilderOperation * op = new SMTPSendWithBuilderOperation(); + SMTPSendWithDataOperation * op = new SMTPSendWithDataOperation(); op->setSession(this); - op->setBuilder(msg); + op->setMessageData(messageData); return (SMTPOperation *) op->autorelease(); } -#endif SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from) { @@ -159,4 +176,3 @@ SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from) op->setSession(this); return (SMTPOperation *) op->autorelease(); } - diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h index 0be287af..9cd7a8f0 100644 --- a/src/async/smtp/MCSMTPAsyncSession.h +++ b/src/async/smtp/MCSMTPAsyncSession.h @@ -13,6 +13,7 @@ namespace mailcore { class SMTPOperation; class SMTPSession; class Address; + class SMTPOperationQueueCallback; class SMTPAsyncSession : public Object { public: @@ -52,13 +53,14 @@ namespace mailcore { public: // private virtual void runOperation(SMTPOperation * operation); virtual SMTPSession * session(); + virtual void tryAutomaticDisconnect(); private: - SMTPSession * mSession; - OperationQueue * mQueue; - - void queue(SMTPOperation * op); - + SMTPSession * mSession; + OperationQueue * mQueue; + SMTPOperationQueueCallback * mQueueCallback; + + virtual void tryAutomaticDisconnectAfterDelay(void * context); }; } diff --git a/src/async/smtp/MCSMTPDisconnectOperation.cc b/src/async/smtp/MCSMTPDisconnectOperation.cc new file mode 100644 index 00000000..8a5b100a --- /dev/null +++ b/src/async/smtp/MCSMTPDisconnectOperation.cc @@ -0,0 +1,29 @@ +// +// SMTPDisconnectOperation.cpp +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include "MCSMTPDisconnectOperation.h" + +#include "MCSMTPAsyncSession.h" +#include "MCSMTPSession.h" + +using namespace mailcore; + +SMTPDisconnectOperation::SMTPDisconnectOperation() +{ +} + +SMTPDisconnectOperation::~SMTPDisconnectOperation() +{ +} + +void SMTPDisconnectOperation::main() +{ + session()->session()->disconnect(); + setError(ErrorCode::ErrorNone); + fprintf(stderr, "smtp disconnect\n"); +} diff --git a/src/async/smtp/MCSMTPDisconnectOperation.h b/src/async/smtp/MCSMTPDisconnectOperation.h new file mode 100644 index 00000000..dacf72a6 --- /dev/null +++ b/src/async/smtp/MCSMTPDisconnectOperation.h @@ -0,0 +1,32 @@ +// +// SMTPDisconnectOperation.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCSMTPDISCONNECTOPERATION_H_ +#define __MAILCORE_MCSMTPDISCONNECTOPERATION_H_ + +#include +#include +#include + +#ifdef __cplusplus + +namespace mailcore { + + class SMTPDisconnectOperation : public SMTPOperation { + public: + SMTPDisconnectOperation(); + virtual ~SMTPDisconnectOperation(); + + public: // subclass behavior + virtual void main(); + }; +} + +#endif + +#endif \ No newline at end of file diff --git a/src/async/smtp/MCSMTPOperation.cc b/src/async/smtp/MCSMTPOperation.cc index 532c6ab4..e8211a24 100644 --- a/src/async/smtp/MCSMTPOperation.cc +++ b/src/async/smtp/MCSMTPOperation.cc @@ -82,4 +82,3 @@ void SMTPOperation::bodyProgressOnMainThread(void * ctx) } free(context); } - diff --git a/src/async/smtp/MCSMTPSendWithDataOperation.cc b/src/async/smtp/MCSMTPSendWithDataOperation.cc index bb2c5ea9..b64f835b 100644 --- a/src/async/smtp/MCSMTPSendWithDataOperation.cc +++ b/src/async/smtp/MCSMTPSendWithDataOperation.cc @@ -38,4 +38,6 @@ void SMTPSendWithDataOperation::main() ErrorCode error; session()->session()->sendMessage(mMessageData, this, &error); setError(error); + + //tryAutomaticDisconnect(); } diff --git a/src/core/basetypes/MCMainThread.h b/src/core/basetypes/MCMainThread.h index 31819a29..c9fe4e8d 100644 --- a/src/core/basetypes/MCMainThread.h +++ b/src/core/basetypes/MCMainThread.h @@ -5,9 +5,14 @@ #ifdef __cplusplus namespace mailcore { - void callOnMainThread(void (*)(void *), void * context); - void callOnMainThreadAndWait(void (*)(void *), void * context); - void callAfterDelay(void (*)(void *), void * context, double time); + void callOnMainThread(void (*)(void *), void * context); + void callOnMainThreadAndWait(void (*)(void *), void * context); + + // Returns a "call" object. + void * callAfterDelay(void (*)(void *), void * context, double time); + + // Pass the pointer returns by callAfterDelay() to cancel a delayed call. + void cancelDelayedCall(void * call); } #endif diff --git a/src/core/basetypes/MCMainThread.mm b/src/core/basetypes/MCMainThread.mm index 0bdc2ce1..4e9c6fc7 100644 --- a/src/core/basetypes/MCMainThread.mm +++ b/src/core/basetypes/MCMainThread.mm @@ -52,13 +52,18 @@ void mailcore::callOnMainThreadAndWait(void (* function)(void *), void * context [caller release]; } -void mailcore::callAfterDelay(void (* function)(void *), void * context, double time) +void * mailcore::callAfterDelay(void (* function)(void *), void * context, double time) { LEPPPMainThreadCaller * caller; caller = [[LEPPPMainThreadCaller alloc] init]; [caller setFunction:function]; [caller setContext:context]; [caller performSelector:@selector(call) withObject:nil afterDelay:time]; - [caller release]; + return [caller autorelease]; } +void mailcore::cancelDelayedCall(void * delayedCall) +{ + LEPPPMainThreadCaller * caller = (LEPPPMainThreadCaller *) delayedCall; + [NSObject cancelPreviousPerformRequestsWithTarget:caller selector:@selector(call) object:nil]; +} diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 32d51fc4..879c194f 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "MCAutoreleasePool.h" #include "MCString.h" @@ -115,6 +116,26 @@ struct mainThreadCallData { Object * obj; void * context; Object::Method method; + void * caller; +}; + +static pthread_once_t delayedPerformOnce = PTHREAD_ONCE_INIT; +static chash * delayedPerformHash = NULL; + +static void reallyInitDelayedPerform() +{ + delayedPerformHash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); +} + +static void initDelayedPerform() +{ + pthread_once(&delayedPerformOnce, reallyInitDelayedPerform); +} + +struct mainThreadCallKeyData { + Object * obj; + void * context; + Object::Method method; }; static void performOnMainThread(void * info) @@ -134,7 +155,7 @@ static void performOnMainThread(void * info) free(data); } -static void callAfterDelay(void * info) +static void performAfterDelay(void * info) { struct mainThreadCallData * data; void * context; @@ -146,6 +167,15 @@ static void callAfterDelay(void * info) context = data->context; method = data->method; + chashdatum key; + struct mainThreadCallKeyData keyData; + keyData.obj = obj; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + chash_delete(delayedPerformHash, &key, NULL); + (obj->*method)(context); free(data); @@ -159,6 +189,7 @@ void Object::performMethodOnMainThread(Method method, void * context, bool waitU data->obj = this; data->context = context; data->method = method; + data->caller = NULL; if (waitUntilDone) { callOnMainThreadAndWait(performOnMainThread, data); @@ -170,12 +201,48 @@ void Object::performMethodOnMainThread(Method method, void * context, bool waitU void Object::performMethodAfterDelay(Method method, void * context, double delay) { + initDelayedPerform(); + struct mainThreadCallData * data; data = (struct mainThreadCallData *) calloc(sizeof(* data), 1); data->obj = this; data->context = context; data->method = method; + data->caller = callAfterDelay(performAfterDelay, data, delay); + + chashdatum key; + chashdatum value; + struct mainThreadCallKeyData keyData; + keyData.obj = this; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + value.data = (void *) data; + value.len = 0; + chash_set(delayedPerformHash, &key, &value, NULL); +} + +void Object::cancelDelayedPerformMethod(Method method, void * context) +{ + initDelayedPerform(); - callAfterDelay(performOnMainThread, data, delay); + int r; + chashdatum key; + chashdatum value; + struct mainThreadCallKeyData keyData; + keyData.obj = this; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + r = chash_get(delayedPerformHash, &key, &value); + if (r < 0) + return; + + chash_delete(delayedPerformHash, &key, NULL); + struct mainThreadCallData * data = (struct mainThreadCallData *) value.data; + cancelDelayedCall(data->caller); + free(data); } diff --git a/src/core/basetypes/MCObject.h b/src/core/basetypes/MCObject.h index 0fd65d09..01812191 100644 --- a/src/core/basetypes/MCObject.h +++ b/src/core/basetypes/MCObject.h @@ -38,6 +38,7 @@ namespace mailcore { virtual void performMethod(Method method, void * context); virtual void performMethodOnMainThread(Method method, void * context, bool waitUntilDone = false); virtual void performMethodAfterDelay(Method method, void * context, double delay); + virtual void cancelDelayedPerformMethod(Method method, void * context); private: pthread_mutex_t mLock; diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 72d0041d..f13c9cde 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -1,13 +1,15 @@ #include "MCOperationQueue.h" +#include + #include "MCOperation.h" #include "MCOperationCallback.h" +#include "MCOperationQueueCallback.h" #include "MCMainThread.h" #include "MCUtils.h" #include "MCArray.h" #include "MCLog.h" #include "MCAutoreleasePool.h" -#include using namespace mailcore; @@ -21,6 +23,8 @@ OperationQueue::OperationQueue() mStartSem = mailsem_new(); mStopSem = mailsem_new(); mWaitingFinishedSem = mailsem_new(); + mQuitting = false; + mCallback = NULL; } OperationQueue::~OperationQueue() @@ -153,6 +157,10 @@ void OperationQueue::stoppedOnMainThread(void * context) mailsem_down(mStopSem); mStarted = false; + if (mCallback) { + mCallback->queueIdle(); + } + release(); // (2) release(); // (3) @@ -181,6 +189,16 @@ unsigned int OperationQueue::count() return count; } +void OperationQueue::setCallback(OperationQueueCallback * callback) +{ + mCallback = callback; +} + +OperationQueueCallback * OperationQueue::callback() +{ + return mCallback; +} + #if 0 void OperationQueue::waitUntilAllOperationsAreFinished() { diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index b9323dea..ddfe9de2 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -10,41 +10,46 @@ #ifdef __cplusplus namespace mailcore { - - class Operation; - class Array; - class OperationQueue : public Object { - public: - OperationQueue(); - virtual ~OperationQueue(); - - virtual void addOperation(Operation * op); - + class Operation; + class OperationQueueCallback; + class Array; + + class OperationQueue : public Object { + public: + OperationQueue(); + virtual ~OperationQueue(); + + virtual void addOperation(Operation * op); + virtual unsigned int count(); - private: - Array * mOperations; - pthread_t mThreadID; - bool mStarted; - struct mailsem * mOperationSem; - struct mailsem * mStartSem; - struct mailsem * mStopSem; - pthread_mutex_t mLock; - bool mWaiting; - struct mailsem * mWaitingFinishedSem; - bool mQuitting; + virtual void setCallback(OperationQueueCallback * callback); + virtual OperationQueueCallback * callback(); - void startThread(); - static void runOperationsOnThread(OperationQueue * queue); - void runOperations(); - void callbackOnMainThread(Operation * op); - void checkRunningOnMainThread(void * context); - void checkRunningAfterDelay(void * context); + private: + Array * mOperations; + pthread_t mThreadID; + bool mStarted; + struct mailsem * mOperationSem; + struct mailsem * mStartSem; + struct mailsem * mStopSem; + pthread_mutex_t mLock; + bool mWaiting; + struct mailsem * mWaitingFinishedSem; + bool mQuitting; + OperationQueueCallback * mCallback; + + void startThread(); + static void runOperationsOnThread(OperationQueue * queue); + void runOperations(); + void callbackOnMainThread(Operation * op); + void checkRunningOnMainThread(void * context); + void checkRunningAfterDelay(void * context); void stoppedOnMainThread(void * context); - - }; - + + }; + } #endif diff --git a/src/core/basetypes/MCOperationQueueCallback.h b/src/core/basetypes/MCOperationQueueCallback.h new file mode 100644 index 00000000..bf7868ae --- /dev/null +++ b/src/core/basetypes/MCOperationQueueCallback.h @@ -0,0 +1,22 @@ +// +// MCOperationQueueCallback.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_OPERATIONQUEUECALLBACK_H_ +#define __MAILCORE_OPERATIONQUEUECALLBACK_H_ + +namespace mailcore { + + class OperationQueue; + + class OperationQueueCallback { + public: + virtual void queueIdle() {} + }; +} + +#endif diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index fd5832f3..3e49ea5f 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -679,3 +679,7 @@ void SMTPSession::sendMessage(MessageBuilder * msg, SMTPProgressCallback * callb recipients->release(); } +bool SMTPSession::isDisconnected() +{ + return mState == STATE_DISCONNECTED; +} diff --git a/src/core/smtp/MCSMTPSession.h b/src/core/smtp/MCSMTPSession.h index 70237c16..57c6e0ce 100644 --- a/src/core/smtp/MCSMTPSession.h +++ b/src/core/smtp/MCSMTPSession.h @@ -85,6 +85,9 @@ namespace mailcore { void sendMessage(Address * from, Array * /* Address */ recipients, Data * messageData, SMTPProgressCallback * callback, ErrorCode * pError); void sendMessage(MessageBuilder * msg, SMTPProgressCallback * callback, ErrorCode * pError); + + public: // private + virtual bool isDisconnected(); }; } -- cgit v1.2.3 From cf3d7e5b4438eb47973ca7dc1a657cd18e5a12dd Mon Sep 17 00:00:00 2001 From: Paul Young Date: Sat, 22 Jun 2013 16:15:11 -0400 Subject: Added switch for fetching the full message in the iOS example app. * Added per discussion in #93. * Fetching the full message is disabled by default. --- example/ios/iOS UI Test/iOS UI Test/AppDelegate.m | 1 + 1 file changed, 1 insertion(+) diff --git a/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m b/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m index 557653f7..92585ffb 100644 --- a/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m +++ b/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m @@ -13,6 +13,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"FetchFullMessageEnabled"]; return YES; } -- cgit v1.2.3 From e4cb9c41ebc8de388da788e4825eaef3ffc5f525 Mon Sep 17 00:00:00 2001 From: Paul Young Date: Sat, 22 Jun 2013 16:26:43 -0400 Subject: Added switch to settings view controller. * Removed setting of user default in app delegate. --- example/ios/iOS UI Test/iOS UI Test/AppDelegate.m | 1 - .../iOS UI Test/SettingsViewController.h | 2 + .../iOS UI Test/SettingsViewController.m | 3 + .../iOS UI Test/SettingsViewController.xib | 235 +++++++++++++++++++-- 4 files changed, 228 insertions(+), 13 deletions(-) diff --git a/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m b/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m index 92585ffb..557653f7 100644 --- a/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m +++ b/example/ios/iOS UI Test/iOS UI Test/AppDelegate.m @@ -13,7 +13,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. - [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"FetchFullMessageEnabled"]; return YES; } diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h index 2172b4d4..e5f5da48 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h @@ -11,6 +11,7 @@ extern NSString * const UsernameKey; extern NSString * const PasswordKey; extern NSString * const HostnameKey; +extern NSString * const FetchFullMessageKey; @protocol SettingsViewControllerDelegate; @@ -19,6 +20,7 @@ extern NSString * const HostnameKey; @property (weak, nonatomic) IBOutlet UITextField *emailTextField; @property (weak, nonatomic) IBOutlet UITextField *passwordTextField; @property (weak, nonatomic) IBOutlet UITextField *hostnameTextField; +@property (weak, nonatomic) IBOutlet UISwitch *fetchFullMessageSwitch; @property (nonatomic, weak) id delegate; - (IBAction)done:(id)sender; diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m index 6fbd6db2..f897b0d5 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m @@ -12,6 +12,7 @@ NSString * const UsernameKey = @"username"; NSString * const PasswordKey = @"password"; NSString * const HostnameKey = @"hostname"; +NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled"; @implementation SettingsViewController @@ -19,6 +20,7 @@ NSString * const HostnameKey = @"hostname"; [[NSUserDefaults standardUserDefaults] setObject:self.emailTextField.text ?: @"" forKey:UsernameKey]; [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey]; [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey]; + [[NSUserDefaults standardUserDefaults] setBool:[self.fetchFullMessageSwitch isOn] forKey:FetchFullMessageKey]; [self.delegate settingsViewControllerFinished:self]; } @@ -30,6 +32,7 @@ NSString * const HostnameKey = @"hostname"; self.emailTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:UsernameKey]; self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey]; self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey]; + self.fetchFullMessageSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:FetchFullMessageKey]; } @end diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib index 00041150..3de561bd 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib @@ -2,9 +2,9 @@ 1552 - 12D78 + 12E55 3084 - 1187.37 + 1187.39 626.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -14,8 +14,10 @@ IBNSLayoutConstraint IBProxyObject IBUIBarButtonItem + IBUILabel IBUINavigationBar IBUINavigationItem + IBUISwitch IBUITextField IBUIView @@ -136,7 +138,7 @@ {{20, 142}, {280, 30}} - + _NS:9 NO YES @@ -159,6 +161,44 @@ + + + 292 + {{208, 180}, {94, 27}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + + + + 292 + {{20, 183}, {143, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Fetch full message + + 1 + MCAwIDAAA + darkTextColor + + + 0 + + + NO + {{0, 20}, {320, 548}} @@ -191,14 +231,6 @@ - - - view - - - - 3 - emailTextField @@ -223,6 +255,22 @@ 55 + + + fetchFullMessageSwitch + + + + 68 + + + + view + + + + 69 + done: @@ -244,6 +292,70 @@ 1 + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + 6 @@ -440,6 +552,8 @@ + + @@ -551,6 +665,80 @@ + + 56 + + + + + 57 + + + + + 58 + + + + + 59 + + + + + 8 + 0 + + 0 + 1 + + 21 + + 1000 + + 3 + 9 + 1 + + + + 7 + 0 + + 0 + 1 + + 143 + + 1000 + + 3 + 9 + 1 + + + + + + 60 + + + + + 61 + + + + + 70 + + + + + 71 + + + @@ -572,6 +760,10 @@ + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -594,13 +786,27 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 55 + 71 @@ -628,6 +834,7 @@ UITextField + UISwitch UITextField UITextField @@ -636,6 +843,10 @@ emailTextField UITextField + + fetchFullMessageSwitch + UISwitch + hostnameTextField UITextField -- cgit v1.2.3 From f844fb0f0523fc8f4b331d9c88abf71ae8971089 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 22 Jun 2013 14:04:27 -0700 Subject: Automatic disconnection of IMAP. Fixed #95. --- build-mac/mailcore2.xcodeproj/project.pbxproj | 8 + src/async/imap/MCIMAPAsyncConnection.cc | 44 ++++- src/async/imap/MCIMAPAsyncConnection.h | 6 +- src/async/imap/MCIMAPAsyncSession.cc | 1 + src/async/imap/MCIMAPAsyncSession.h | 8 +- src/async/imap/MCIMAPDisconnectOperation.cc | 28 +++ src/async/imap/MCIMAPDisconnectOperation.h | 32 +++ src/async/smtp/MCSMTPAsyncSession.cc | 3 +- src/async/smtp/MCSMTPDisconnectOperation.cc | 1 - src/core/imap/MCIMAPSession.cc | 6 + src/core/imap/MCIMAPSession.h | 269 +++++++++++++------------- 11 files changed, 263 insertions(+), 143 deletions(-) create mode 100644 src/async/imap/MCIMAPDisconnectOperation.cc create mode 100644 src/async/imap/MCIMAPDisconnectOperation.h diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 54e21f12..41df2d15 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -31,6 +31,8 @@ C07ADC28B83E7959BF114D46 /* MCOIMAPSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */; }; C608167517759967001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; }; C608167617759968001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; }; + C608167B177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */; }; + C608167C177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */; }; C623C58616FD6A50001BBEFC /* MCOConstants.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB26D16FD63F6000DB34C /* MCOConstants.h */; }; C623C58716FD6A61001BBEFC /* MCOOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25716FD3BC2000DB34C /* MCOOperation.h */; }; C623C58816FD6DF6001BBEFC /* NSValue+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25016FC2846000DB34C /* NSValue+MCO.h */; }; @@ -1077,6 +1079,8 @@ C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCSMTPDisconnectOperation.cc; sourceTree = ""; }; C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCSMTPDisconnectOperation.h; sourceTree = ""; }; C6081678177625AD001F1018 /* MCOperationQueueCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOperationQueueCallback.h; sourceTree = ""; }; + C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPDisconnectOperation.cc; sourceTree = ""; }; + C608167A177635D2001F1018 /* MCIMAPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPDisconnectOperation.h; sourceTree = ""; }; C623C58A16FD8C22001BBEFC /* MCOAbstractMessage+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOAbstractMessage+Private.h"; sourceTree = ""; }; C623C58B16FE52C0001BBEFC /* MCOHTMLRendererDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOHTMLRendererDelegate.h; sourceTree = ""; }; C623C58D16FE6B45001BBEFC /* MCOIMAPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPOperation.h; sourceTree = ""; }; @@ -1674,6 +1678,8 @@ C64BB22A16E5C0A3000DB34C /* MCIMAPCapabilityOperation.h */, 9EF9AB10175F319A0027FA3B /* MCIMAPFolderStatusOperation.cc */, 9EF9AB0E175F30C20027FA3B /* MCIMAPFolderStatusOperation.h */, + C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */, + C608167A177635D2001F1018 /* MCIMAPDisconnectOperation.h */, ); path = imap; sourceTree = ""; @@ -2433,6 +2439,7 @@ C6A81BC717068EB000882C15 /* MCOSMTPOperation.mm in Sources */, C6A81BD61706903500882C15 /* MCOPOPSession.mm in Sources */, C6A81BDA1706903E00882C15 /* MCOPOPFetchHeaderOperation.mm in Sources */, + C608167B177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */, C6A81BDE1706904800882C15 /* MCOPOPFetchMessageOperation.mm in Sources */, C6A81BE21706905600882C15 /* MCOPOPOperation.mm in Sources */, C6A81BE61706906D00882C15 /* MCOPOPFetchMessagesOperation.mm in Sources */, @@ -2612,6 +2619,7 @@ C6A81BC817068EB000882C15 /* MCOSMTPOperation.mm in Sources */, C6A81BD71706903500882C15 /* MCOPOPSession.mm in Sources */, C6A81BDB1706903E00882C15 /* MCOPOPFetchHeaderOperation.mm in Sources */, + C608167C177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */, C6A81BDF1706904800882C15 /* MCOPOPFetchMessageOperation.mm in Sources */, C6A81BE31706905600882C15 /* MCOPOPOperation.mm in Sources */, C6A81BE71706906D00882C15 /* MCOPOPFetchMessagesOperation.mm in Sources */, diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 5b1269da..02320b3a 100644 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -30,9 +30,30 @@ #include "MCIMAPIdleOperation.h" #include "MCIMAPIdentityOperation.h" #include "MCIMAPCapabilityOperation.h" +#include "MCOperationQueueCallback.h" +#include "MCIMAPDisconnectOperation.h" using namespace mailcore; +namespace mailcore { + class IMAPOperationQueueCallback : public Object, public OperationQueueCallback { + public: + IMAPOperationQueueCallback(IMAPAsyncConnection * connection) { + mConnection = connection; + } + + virtual ~IMAPOperationQueueCallback() { + } + + virtual void queueIdle() { + mConnection->tryAutomaticDisconnect(); + } + + private: + IMAPAsyncConnection * mConnection; + }; +} + IMAPAsyncConnection::IMAPAsyncConnection() { mSession = new IMAPSession(); @@ -40,10 +61,13 @@ IMAPAsyncConnection::IMAPAsyncConnection() mDefaultNamespace = NULL; mDelimiter = 0; mLastFolder = NULL; + mQueueCallback = new IMAPOperationQueueCallback(this); + mQueue->setCallback(mQueueCallback); } IMAPAsyncConnection::~IMAPAsyncConnection() { + MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mLastFolder); MC_SAFE_RELEASE(mDefaultNamespace); MC_SAFE_RELEASE(mQueue); @@ -439,10 +463,28 @@ unsigned int IMAPAsyncConnection::operationsCount() void IMAPAsyncConnection::runOperation(IMAPOperation * operation) { -#warning disconnect after delay + cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL); mQueue->addOperation(operation); } +void IMAPAsyncConnection::tryAutomaticDisconnect() +{ + // It's safe since no thread is running when this function is called. + if (mSession->isDisconnected()) { + return; + } + + performMethodAfterDelay((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL, 30); +} + +void IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay(void * context) +{ + IMAPDisconnectOperation * op = new IMAPDisconnectOperation(); + op->setSession(this); + op->autorelease(); + op->start(); +} + void IMAPAsyncConnection::setLastFolder(String * folder) { MC_SAFE_REPLACE_COPY(String, mLastFolder, folder); diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 4843702b..7869644c 100644 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -25,6 +25,7 @@ namespace mailcore { class IMAPFetchNamespaceOperation; class IMAPIdentityOperation; class IMAPCapabilityOperation; + class IMAPOperationQueueCallback; class IMAPAsyncConnection : public Object { public: @@ -116,8 +117,9 @@ namespace mailcore { char mDelimiter; IMAPNamespace * mDefaultNamespace; String * mLastFolder; + IMAPOperationQueueCallback * mQueueCallback; - void queue(IMAPOperation * op); + virtual void tryAutomaticDisconnectAfterDelay(void * context); public: // private virtual void runOperation(IMAPOperation * operation); @@ -127,6 +129,8 @@ namespace mailcore { virtual void setLastFolder(String * folder); virtual String * lastFolder(); + + virtual void tryAutomaticDisconnect(); }; } diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 766b6fe6..3fbd5470 100644 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -10,6 +10,7 @@ #include "MCIMAPAsyncConnection.h" #include "MCIMAPNamespace.h" +#include "MCOperationQueueCallback.h" #define DEFAULT_MAX_CONNECTIONS 3 diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index a2bc05f8..390fdab8 100644 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -142,10 +142,10 @@ namespace mailcore { bool mAllowsFolderConcurrentAccessEnabled; unsigned int mMaximumConnections; - IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); - IMAPAsyncConnection * session(); - IMAPAsyncConnection * matchingSessionForFolder(String * folder); - IMAPAsyncConnection * availableSession(); + virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); + virtual IMAPAsyncConnection * session(); + virtual IMAPAsyncConnection * matchingSessionForFolder(String * folder); + virtual IMAPAsyncConnection * availableSession(); }; } diff --git a/src/async/imap/MCIMAPDisconnectOperation.cc b/src/async/imap/MCIMAPDisconnectOperation.cc new file mode 100644 index 00000000..070eeaae --- /dev/null +++ b/src/async/imap/MCIMAPDisconnectOperation.cc @@ -0,0 +1,28 @@ +// +// MCIMAPDisconnectOperation.cc +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include "MCIMAPDisconnectOperation.h" + +#include "MCIMAPAsyncConnection.h" +#include "MCIMAPSession.h" + +using namespace mailcore; + +IMAPDisconnectOperation::IMAPDisconnectOperation() +{ +} + +IMAPDisconnectOperation::~IMAPDisconnectOperation() +{ +} + +void IMAPDisconnectOperation::main() +{ + session()->session()->disconnect(); + setError(ErrorCode::ErrorNone); +} diff --git a/src/async/imap/MCIMAPDisconnectOperation.h b/src/async/imap/MCIMAPDisconnectOperation.h new file mode 100644 index 00000000..5d572def --- /dev/null +++ b/src/async/imap/MCIMAPDisconnectOperation.h @@ -0,0 +1,32 @@ +// +// MCIMAPDisconnectOperation.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCIMAPDISCONNECTOPERATION_H_ +#define __MAILCORE_MCIMAPDISCONNECTOPERATION_H_ + +#include +#include +#include + +#ifdef __cplusplus + +namespace mailcore { + + class IMAPDisconnectOperation : public IMAPOperation { + public: + IMAPDisconnectOperation(); + virtual ~IMAPDisconnectOperation(); + + public: // subclass behavior + virtual void main(); + }; +} + +#endif + +#endif \ No newline at end of file diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc index 776587e6..cf028ced 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cc +++ b/src/async/smtp/MCSMTPAsyncSession.cc @@ -10,7 +10,7 @@ using namespace mailcore; namespace mailcore { - class SMTPOperationQueueCallback : public OperationQueueCallback { + class SMTPOperationQueueCallback : public Object, public OperationQueueCallback { public: SMTPOperationQueueCallback(SMTPAsyncSession * session) { mSession = session; @@ -38,6 +38,7 @@ SMTPAsyncSession::SMTPAsyncSession() SMTPAsyncSession::~SMTPAsyncSession() { + MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mQueue); MC_SAFE_RELEASE(mSession); } diff --git a/src/async/smtp/MCSMTPDisconnectOperation.cc b/src/async/smtp/MCSMTPDisconnectOperation.cc index 8a5b100a..592ceb48 100644 --- a/src/async/smtp/MCSMTPDisconnectOperation.cc +++ b/src/async/smtp/MCSMTPDisconnectOperation.cc @@ -25,5 +25,4 @@ void SMTPDisconnectOperation::main() { session()->session()->disconnect(); setError(ErrorCode::ErrorNone); - fprintf(stderr, "smtp disconnect\n"); } diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 52e819d9..4481f086 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -514,6 +514,8 @@ void IMAPSession::unsetup() mailimap_free(imap); imap = NULL; } + + mState = STATE_DISCONNECTED; } void IMAPSession::connect(ErrorCode * pError) @@ -2912,3 +2914,7 @@ bool IMAPSession::isIdentityEnabled() return mIdentityEnabled; } +bool IMAPSession::isDisconnected() +{ + return mState == STATE_DISCONNECTED; +} diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 8531b050..c21c36cd 100644 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -5,92 +5,90 @@ #include #include - - #ifdef __cplusplus namespace mailcore { - extern String * IMAPNamespacePersonal; - extern String * IMAPNamespaceOther; - extern String * IMAPNamespaceShared; + extern String * IMAPNamespacePersonal; + extern String * IMAPNamespaceOther; + extern String * IMAPNamespaceShared; - class IMAPNamespace; - class IMAPSearchExpression; - class IMAPFolder; - class IMAPProgressCallback; + class IMAPNamespace; + class IMAPSearchExpression; + class IMAPFolder; + class IMAPProgressCallback; class IMAPSyncResult; class IMAPFolderStatus; - - class IMAPSession : public Object { - public: - IMAPSession(); - virtual ~IMAPSession(); - - virtual void setHostname(String * hostname); - virtual String * hostname(); + + class IMAPSession : public Object { + public: + IMAPSession(); + virtual ~IMAPSession(); + + virtual void setHostname(String * hostname); + virtual String * hostname(); - virtual void setPort(unsigned int port); - virtual unsigned int port(); + virtual void setPort(unsigned int port); + virtual unsigned int port(); - virtual void setUsername(String * username); - virtual String * username(); + virtual void setUsername(String * username); + virtual String * username(); - virtual void setPassword(String * password); - virtual String * password(); + virtual void setPassword(String * password); + virtual String * password(); - virtual void setAuthType(AuthType authType); - virtual AuthType authType(); + virtual void setAuthType(AuthType authType); + virtual AuthType authType(); - virtual void setConnectionType(ConnectionType connectionType); - virtual ConnectionType connectionType(); + virtual void setConnectionType(ConnectionType connectionType); + virtual ConnectionType connectionType(); - virtual void setTimeout(time_t timeout); - virtual time_t timeout(); - - virtual void setCheckCertificateEnabled(bool enabled); - virtual bool isCheckCertificateEnabled(); + virtual void setTimeout(time_t timeout); + virtual time_t timeout(); - virtual void setVoIPEnabled(bool enabled); - virtual bool isVoIPEnabled(); + virtual void setCheckCertificateEnabled(bool enabled); + virtual bool isCheckCertificateEnabled(); + + virtual void setVoIPEnabled(bool enabled); + virtual bool isVoIPEnabled(); // Needed for fetchSubscribedFolders() and fetchAllFolders(). - virtual void setDelimiter(char delimiter); - virtual char delimiter(); + virtual void setDelimiter(char delimiter); + virtual char delimiter(); // Needed for fetchSubscribedFolders() and fetchAllFolders(). - virtual void setDefaultNamespace(IMAPNamespace * ns); - virtual IMAPNamespace * defaultNamespace(); + virtual void setDefaultNamespace(IMAPNamespace * ns); + virtual IMAPNamespace * defaultNamespace(); - virtual void select(String * folder, ErrorCode * pError); + virtual void select(String * folder, ErrorCode * pError); virtual IMAPFolderStatus * folderStatus(String * folder, ErrorCode * pError); - - virtual Array * /* IMAPFolder */ fetchSubscribedFolders(ErrorCode * pError); - virtual Array * /* IMAPFolder */ fetchAllFolders(ErrorCode * pError); // will use xlist if available - virtual void renameFolder(String * folder, String * otherName, ErrorCode * pError); - virtual void deleteFolder(String * folder, ErrorCode * pError); - virtual void createFolder(String * folder, ErrorCode * pError); + virtual Array * /* IMAPFolder */ fetchSubscribedFolders(ErrorCode * pError); + virtual Array * /* IMAPFolder */ fetchAllFolders(ErrorCode * pError); // will use xlist if available + + virtual void renameFolder(String * folder, String * otherName, ErrorCode * pError); + virtual void deleteFolder(String * folder, ErrorCode * pError); + virtual void createFolder(String * folder, ErrorCode * pError); - virtual void subscribeFolder(String * folder, ErrorCode * pError); - virtual void unsubscribeFolder(String * folder, ErrorCode * pError); + virtual void subscribeFolder(String * folder, ErrorCode * pError); + virtual void unsubscribeFolder(String * folder, ErrorCode * pError); - virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags, + virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); - - virtual void copyMessages(String * folder, IndexSet * uidSet, String * destFolder, + + virtual void copyMessages(String * folder, IndexSet * uidSet, String * destFolder, IndexSet ** pDestUIDs, ErrorCode * pError); - - virtual void expunge(String * folder, ErrorCode * pError); - - virtual Array * /* IMAPMessage */ fetchMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind, + + virtual void expunge(String * folder, ErrorCode * pError); + + virtual Array * /* IMAPMessage */ fetchMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind, IndexSet * uids, IMAPProgressCallback * progressCallback, ErrorCode * pError); - virtual Array * /* IMAPMessage */ fetchMessagesByNumber(String * folder, IMAPMessagesRequestKind requestKind, + virtual Array * /* IMAPMessage */ fetchMessagesByNumber(String * folder, IMAPMessagesRequestKind requestKind, IndexSet * numbers, IMAPProgressCallback * progressCallback, ErrorCode * pError); - virtual Data * fetchMessageByUID(String * folder, uint32_t uid, + virtual Data * fetchMessageByUID(String * folder, uint32_t uid, IMAPProgressCallback * progressCallback, ErrorCode * pError); - virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID, + virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID, Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError); virtual HashMap * fetchMessageNumberUIDMapping(String * folder, uint32_t fromUID, uint32_t toUID, ErrorCode * pError); @@ -100,94 +98,95 @@ namespace mailcore { IndexSet * uids, uint64_t modseq, IMAPProgressCallback * progressCallback, ErrorCode * pError); - virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); - virtual void storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); - - virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError); - virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError); - - virtual bool setupIdle(); - virtual void idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError); - virtual void interruptIdle(); - virtual void unsetupIdle(); - - virtual void connect(ErrorCode * pError); - virtual void disconnect(); - - virtual HashMap * fetchNamespace(ErrorCode * pError); - - virtual void login(ErrorCode * pError); - - virtual HashMap * identity(String * vendor, String * name, String * version, ErrorCode * pError); + virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); + virtual void storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); + + virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError); + virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError); + + virtual bool setupIdle(); + virtual void idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError); + virtual void interruptIdle(); + virtual void unsetupIdle(); + + virtual void connect(ErrorCode * pError); + virtual void disconnect(); + + virtual HashMap * fetchNamespace(ErrorCode * pError); + + virtual void login(ErrorCode * pError); + + virtual HashMap * identity(String * vendor, String * name, String * version, ErrorCode * pError); virtual IndexSet * capability(ErrorCode * pError); - virtual uint32_t uidValidity(); - virtual uint32_t uidNext(); + virtual uint32_t uidValidity(); + virtual uint32_t uidNext(); virtual uint64_t modSequenceValue(); - virtual unsigned int lastFolderMessageCount(); + virtual unsigned int lastFolderMessageCount(); virtual uint32_t firstUnseenUid(); - virtual bool isIdleEnabled(); - virtual bool isXListEnabled(); - virtual bool isCondstoreEnabled(); - virtual bool isQResyncEnabled(); - virtual bool isIdentityEnabled(); + virtual bool isIdleEnabled(); + virtual bool isXListEnabled(); + virtual bool isCondstoreEnabled(); + virtual bool isQResyncEnabled(); + virtual bool isIdentityEnabled(); public: // private - virtual void loginIfNeeded(ErrorCode * pError); - virtual void connectIfNeeded(ErrorCode * pError); - - private: - String * mHostname; - unsigned int mPort; - String * mUsername; - String * mPassword; - AuthType mAuthType; - ConnectionType mConnectionType; - bool mCheckCertificateEnabled; - bool mVoIPEnabled; - char mDelimiter; - IMAPNamespace * mDefaultNamespace; - time_t mTimeout; - - bool mBodyProgressEnabled; - bool mIdleEnabled; - bool mXListEnabled; - bool mCondstoreEnabled; - bool mQResyncEnabled; - bool mIdentityEnabled; - String * mWelcomeString; - bool mNeedsMboxMailWorkaround; - uint32_t mUIDValidity; - uint32_t mUIDNext; - uint64_t mModSequenceValue; - unsigned int mFolderMsgCount; - uint32_t mFirstUnseenUid; - - unsigned int mLastFetchedSequenceNumber; - String * mCurrentFolder; - pthread_mutex_t mIdleLock; - bool mCanIdle; - int mState; - mailimap * mImap; - IMAPProgressCallback * mProgressCallback; - unsigned int mProgressItemsCount; - - void init(); - void bodyProgress(unsigned int current, unsigned int maximum); - void itemsProgress(unsigned int current, unsigned int maximum); - bool checkCertificate(); - static void body_progress(size_t current, size_t maximum, void * context); - static void items_progress(size_t current, size_t maximum, void * context); - void setup(); - void unsetup(); - void selectIfNeeded(String * folder, ErrorCode * pError); - char fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError); - IMAPSyncResult * fetchMessages(String * folder, IMAPMessagesRequestKind requestKind, bool fetchByUID, + virtual void loginIfNeeded(ErrorCode * pError); + virtual void connectIfNeeded(ErrorCode * pError); + virtual bool isDisconnected(); + + private: + String * mHostname; + unsigned int mPort; + String * mUsername; + String * mPassword; + AuthType mAuthType; + ConnectionType mConnectionType; + bool mCheckCertificateEnabled; + bool mVoIPEnabled; + char mDelimiter; + IMAPNamespace * mDefaultNamespace; + time_t mTimeout; + + bool mBodyProgressEnabled; + bool mIdleEnabled; + bool mXListEnabled; + bool mCondstoreEnabled; + bool mQResyncEnabled; + bool mIdentityEnabled; + String * mWelcomeString; + bool mNeedsMboxMailWorkaround; + uint32_t mUIDValidity; + uint32_t mUIDNext; + uint64_t mModSequenceValue; + unsigned int mFolderMsgCount; + uint32_t mFirstUnseenUid; + + unsigned int mLastFetchedSequenceNumber; + String * mCurrentFolder; + pthread_mutex_t mIdleLock; + bool mCanIdle; + int mState; + mailimap * mImap; + IMAPProgressCallback * mProgressCallback; + unsigned int mProgressItemsCount; + + void init(); + void bodyProgress(unsigned int current, unsigned int maximum); + void itemsProgress(unsigned int current, unsigned int maximum); + bool checkCertificate(); + static void body_progress(size_t current, size_t maximum, void * context); + static void items_progress(size_t current, size_t maximum, void * context); + void setup(); + void unsetup(); + void selectIfNeeded(String * folder, ErrorCode * pError); + char fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError); + IMAPSyncResult * fetchMessages(String * folder, IMAPMessagesRequestKind requestKind, bool fetchByUID, struct mailimap_set * imapset, uint64_t modseq, HashMap * mapping, uint32_t startUid, IMAPProgressCallback * progressCallback, ErrorCode * pError); - }; + }; } #endif -- cgit v1.2.3 From 23935690c4ba954eef4e55ab8143f5b8547ab98d Mon Sep 17 00:00:00 2001 From: Paul Young Date: Sat, 22 Jun 2013 17:05:41 -0400 Subject: Fixed indentation. * Consistently using spaces instead of tabs. * Tab width is set to 4 spaces. --- .../iOS UI Test/iOS UI Test/SettingsViewController.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m index f897b0d5..e2f0d2c5 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m @@ -17,21 +17,21 @@ NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled"; @implementation SettingsViewController - (void)done:(id)sender { - [[NSUserDefaults standardUserDefaults] setObject:self.emailTextField.text ?: @"" forKey:UsernameKey]; - [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey]; - [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey]; + [[NSUserDefaults standardUserDefaults] setObject:self.emailTextField.text ?: @"" forKey:UsernameKey]; + [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey]; + [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey]; [[NSUserDefaults standardUserDefaults] setBool:[self.fetchFullMessageSwitch isOn] forKey:FetchFullMessageKey]; - - [self.delegate settingsViewControllerFinished:self]; + + [self.delegate settingsViewControllerFinished:self]; } - (void)viewDidLoad { [super viewDidLoad]; - - self.view.backgroundColor = [UIColor underPageBackgroundColor]; - self.emailTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:UsernameKey]; - self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey]; - self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey]; + + self.view.backgroundColor = [UIColor underPageBackgroundColor]; + self.emailTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:UsernameKey]; + self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey]; + self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey]; self.fetchFullMessageSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:FetchFullMessageKey]; } -- cgit v1.2.3 From b0a968ba727c703528efbfa803267fa67aec37d1 Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sat, 22 Jun 2013 22:04:03 -0600 Subject: Implement Gmail Thread ID --- src/core/imap/MCIMAPMessage.cc | 11 +++++++++++ src/core/imap/MCIMAPMessage.h | 4 ++++ src/core/imap/MCIMAPSession.cc | 31 +++++++++++++++++++++++++++---- src/objc/abstract/MCOConstants.h | 2 ++ src/objc/imap/MCOIMAPMessage.h | 3 +++ src/objc/imap/MCOIMAPMessage.mm | 1 + 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 6f8a0dbb..5e55ddcc 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -35,6 +35,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other) setOriginalFlags(other->originalFlags()); setMainPart((AbstractPart *) other->mainPart()->copy()->autorelease()); setGmailLabels(other->gmailLabels()); + setGmailThreadID(other->gmailThreadID()); } IMAPMessage::~IMAPMessage() @@ -121,6 +122,16 @@ Array * IMAPMessage::gmailLabels() return mLabels; } +void IMAPMessage::setGmailThreadID(String * threadID) +{ + MC_SAFE_REPLACE_COPY(String, mThreadID, threadID); +} + +String * IMAPMessage::gmailThreadID() +{ + return mThreadID; +} + AbstractPart * IMAPMessage::partForPartID(String * partID) { return partForPartIDInPart(mainPart(), partID); diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index 5a9cadcb..dd3edb89 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -38,6 +38,9 @@ namespace mailcore { virtual void setGmailLabels(Array * /* String */ labels); virtual Array * /* String */ gmailLabels(); + virtual void setGmailThreadID(String * threadID); + virtual String * /* String */ gmailThreadID(); + virtual AbstractPart * partForPartID(String * partID); virtual AbstractPart * partForContentID(String * contentID); @@ -59,6 +62,7 @@ namespace mailcore { MessageFlag mOriginalFlags; AbstractPart * mMainPart; Array * /* String */ mLabels; + String * mThreadID; void init(); }; diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 52e819d9..e0c00d39 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -1582,6 +1582,7 @@ struct msg_att_handler_data { bool needsBody; bool needsFlags; bool needsGmailLabels; + bool needsGmailThreadID; uint32_t startUid; }; @@ -1594,6 +1595,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) bool hasBody; bool hasFlags; bool hasGmailLabels; + bool hasGmailThreadID; struct msg_att_handler_data * msg_att_context; // struct IMAPSession * self; @@ -1607,6 +1609,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) bool needsBody; bool needsFlags; bool needsGmailLabels; + bool needsGmailThreadID; uint32_t startUid; msg_att_context = (struct msg_att_handler_data *) context; @@ -1621,13 +1624,15 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) needsBody = msg_att_context->needsBody; needsFlags = msg_att_context->needsFlags; needsGmailLabels = msg_att_context->needsGmailLabels; + needsGmailThreadID = msg_att_context->needsGmailThreadID; startUid = msg_att_context->startUid; hasHeader = false; hasBody = false; hasFlags = false; hasGmailLabels = false; - + hasGmailThreadID = false; + msg = new IMAPMessage(); uid = 0; @@ -1718,6 +1723,13 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) } labels->release(); } + if (ext_data->ext_extension == &mailimap_extension_xgmthrid) { + String * threadID; + + threadID = String::stringWithUTF8Characters((char *) ext_data->ext_data); + msg->setGmailThreadID(threadID); + hasGmailThreadID = true; + } } } for(item_iter = clist_begin(msg_att->att_list) ; item_iter != NULL ; item_iter = clist_next(item_iter)) { @@ -1752,7 +1764,10 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) msg->release(); return; } - + if (needsGmailThreadID && !hasGmailThreadID) { + msg->release(); + return; + } if (uid != 0) { msg->setUid(uid); } @@ -1780,6 +1795,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest bool needsBody; bool needsFlags; bool needsGmailLabels; + bool needsGmailThreadID; Array * messages; IndexSet * vanishedMessages; @@ -1803,7 +1819,8 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest needsBody = false; needsFlags = false; needsGmailLabels = false; - + needsGmailThreadID = false; + fetch_type = mailimap_fetch_type_new_fetch_att_list_empty(); fetch_att = mailimap_fetch_att_new_uid(); mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); @@ -1819,6 +1836,12 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); needsGmailLabels = true; } + if ((requestKind & IMAPMessagesRequestKindGmailThreadID) != 0) { + MCLog("request flags"); + fetch_att = mailimap_fetch_att_new_xgmthrid(); + mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); + needsGmailThreadID = true; + } if ((requestKind & IMAPMessagesRequestKindFullHeaders) != 0) { clist * hdrlist; char * header; @@ -1908,7 +1931,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest msg_att_data.needsFlags = needsFlags; msg_att_data.needsGmailLabels = needsGmailLabels; msg_att_data.startUid = startUid; - + msg_att_data.needsGmailThreadID = needsGmailThreadID; mailimap_set_msg_att_handler(mImap, msg_att_handler, &msg_att_data); mBodyProgressEnabled = false; diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 6f9dd446..3ef785ab 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -134,6 +134,8 @@ typedef enum { MCOIMAPMessagesRequestKindHeaderSubject = 1 << 5, /** Gmail Labels.*/ MCOIMAPMessagesRequestKindGmailLabels = 1 << 6, + /** Gmail Thread ID.*/ + MCOIMAPMessagesRequestKindGmailThreadID = 1 << 7, } MCOIMAPMessagesRequestKind; /** It defines the behavior of the STORE flags request.*/ diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index c6d8595b..f8acd25b 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -49,6 +49,9 @@ /** All Gmail labels of the message */ @property (nonatomic, copy) NSArray * /* NSString */ gmailLabels; +/** Gmail thread iD of the message */ +@property (nonatomic, copy) NSString * /* NSString */ gmailThreadID; + /** Returns the part with the given part identifier. @param partID A part identifier looks like 1.2.1 diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm index 9984443e..5b8f7cdc 100644 --- a/src/objc/imap/MCOIMAPMessage.mm +++ b/src/objc/imap/MCOIMAPMessage.mm @@ -47,6 +47,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFla MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setModSeqValue, modSeqValue) MCO_OBJC_SYNTHESIZE(AbstractPart, setMainPart, mainPart) MCO_OBJC_SYNTHESIZE_ARRAY(setGmailLabels, gmailLabels) +MCO_OBJC_SYNTHESIZE_STRING(setGmailThreadID, gmailThreadID) - (MCOAbstractPart *) partForPartID:(NSString *)partID { -- cgit v1.2.3 From d8117be520bd873c87bbcd278b7f5c59ff9301ff Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sat, 22 Jun 2013 22:11:37 -0600 Subject: Whitespace --- src/core/imap/MCIMAPMessage.h | 64 +++++++++++++++++++++--------------------- src/core/imap/MCIMAPSession.cc | 34 +++++++++++----------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index dd3edb89..8f54ebfc 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -17,30 +17,30 @@ namespace mailcore { class IMAPMessage : public AbstractMessage { public: - IMAPMessage(); - ~IMAPMessage(); - - virtual uint32_t uid(); - virtual void setUid(uint32_t uid); - - virtual void setFlags(MessageFlag flags); - virtual MessageFlag flags(); - - virtual void setOriginalFlags(MessageFlag flags); - virtual MessageFlag originalFlags(); - - virtual uint64_t modSeqValue(); - virtual void setModSeqValue(uint64_t uid); + IMAPMessage(); + ~IMAPMessage(); - virtual void setMainPart(AbstractPart * mainPart); - virtual AbstractPart * mainPart(); - - virtual void setGmailLabels(Array * /* String */ labels); - virtual Array * /* String */ gmailLabels(); + virtual uint32_t uid(); + virtual void setUid(uint32_t uid); + + virtual void setFlags(MessageFlag flags); + virtual MessageFlag flags(); + + virtual void setOriginalFlags(MessageFlag flags); + virtual MessageFlag originalFlags(); + + virtual uint64_t modSeqValue(); + virtual void setModSeqValue(uint64_t uid); + + virtual void setMainPart(AbstractPart * mainPart); + virtual AbstractPart * mainPart(); + + virtual void setGmailLabels(Array * /* String */ labels); + virtual Array * /* String */ gmailLabels(); + + virtual void setGmailThreadID(String * threadID); + virtual String * /* String */ gmailThreadID(); - virtual void setGmailThreadID(String * threadID); - virtual String * /* String */ gmailThreadID(); - virtual AbstractPart * partForPartID(String * partID); virtual AbstractPart * partForContentID(String * contentID); @@ -51,19 +51,19 @@ namespace mailcore { HTMLRendererTemplateCallback * htmlCallback = NULL); public: // subclass behavior - IMAPMessage(IMAPMessage * other); - virtual Object * copy(); - virtual String * description(); + IMAPMessage(IMAPMessage * other); + virtual Object * copy(); + virtual String * description(); private: uint64_t mModSeqValue; - uint32_t mUid; - MessageFlag mFlags; - MessageFlag mOriginalFlags; - AbstractPart * mMainPart; - Array * /* String */ mLabels; - String * mThreadID; - void init(); + uint32_t mUid; + MessageFlag mFlags; + MessageFlag mOriginalFlags; + AbstractPart * mMainPart; + Array * /* String */ mLabels; + String * mThreadID; + void init(); }; } diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index e0c00d39..11e063ae 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -1582,7 +1582,7 @@ struct msg_att_handler_data { bool needsBody; bool needsFlags; bool needsGmailLabels; - bool needsGmailThreadID; + bool needsGmailThreadID; uint32_t startUid; }; @@ -1609,7 +1609,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) bool needsBody; bool needsFlags; bool needsGmailLabels; - bool needsGmailThreadID; + bool needsGmailThreadID; uint32_t startUid; msg_att_context = (struct msg_att_handler_data *) context; @@ -1624,7 +1624,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) needsBody = msg_att_context->needsBody; needsFlags = msg_att_context->needsFlags; needsGmailLabels = msg_att_context->needsGmailLabels; - needsGmailThreadID = msg_att_context->needsGmailThreadID; + needsGmailThreadID = msg_att_context->needsGmailThreadID; startUid = msg_att_context->startUid; hasHeader = false; @@ -1723,13 +1723,13 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) } labels->release(); } - if (ext_data->ext_extension == &mailimap_extension_xgmthrid) { - String * threadID; - - threadID = String::stringWithUTF8Characters((char *) ext_data->ext_data); - msg->setGmailThreadID(threadID); - hasGmailThreadID = true; - } + else if (ext_data->ext_extension == &mailimap_extension_xgmthrid) { + String * threadID; + + threadID = String::stringWithUTF8Characters((char *) ext_data->ext_data); + msg->setGmailThreadID(threadID); + hasGmailThreadID = true; + } } } for(item_iter = clist_begin(msg_att->att_list) ; item_iter != NULL ; item_iter = clist_next(item_iter)) { @@ -1765,9 +1765,9 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) return; } if (needsGmailThreadID && !hasGmailThreadID) { - msg->release(); - return; - } + msg->release(); + return; + } if (uid != 0) { msg->setUid(uid); } @@ -1795,7 +1795,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest bool needsBody; bool needsFlags; bool needsGmailLabels; - bool needsGmailThreadID; + bool needsGmailThreadID; Array * messages; IndexSet * vanishedMessages; @@ -1819,7 +1819,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest needsBody = false; needsFlags = false; needsGmailLabels = false; - needsGmailThreadID = false; + needsGmailThreadID = false; fetch_type = mailimap_fetch_type_new_fetch_att_list_empty(); fetch_att = mailimap_fetch_att_new_uid(); @@ -1836,12 +1836,12 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); needsGmailLabels = true; } - if ((requestKind & IMAPMessagesRequestKindGmailThreadID) != 0) { + if ((requestKind & IMAPMessagesRequestKindGmailThreadID) != 0) { MCLog("request flags"); fetch_att = mailimap_fetch_att_new_xgmthrid(); mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); needsGmailThreadID = true; - } + } if ((requestKind & IMAPMessagesRequestKindFullHeaders) != 0) { clist * hdrlist; char * header; -- cgit v1.2.3 From d6dc425316501ca90351192ff2ce8616d752dc31 Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sat, 22 Jun 2013 22:15:16 -0600 Subject: Moar whitespace --- src/objc/abstract/MCOConstants.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 3ef785ab..8b73aeaf 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -134,8 +134,8 @@ typedef enum { MCOIMAPMessagesRequestKindHeaderSubject = 1 << 5, /** Gmail Labels.*/ MCOIMAPMessagesRequestKindGmailLabels = 1 << 6, - /** Gmail Thread ID.*/ - MCOIMAPMessagesRequestKindGmailThreadID = 1 << 7, + /** Gmail Thread ID.*/ + MCOIMAPMessagesRequestKindGmailThreadID = 1 << 7, } MCOIMAPMessagesRequestKind; /** It defines the behavior of the STORE flags request.*/ -- cgit v1.2.3 From 6b86d88d43e58a5c9ca7274aa417030120a65c27 Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sat, 22 Jun 2013 22:57:30 -0600 Subject: Removed spurious comments --- src/core/imap/MCIMAPMessage.h | 2 +- src/objc/imap/MCOIMAPMessage.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index 8f54ebfc..3a54f4f5 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -39,7 +39,7 @@ namespace mailcore { virtual Array * /* String */ gmailLabels(); virtual void setGmailThreadID(String * threadID); - virtual String * /* String */ gmailThreadID(); + virtual String * gmailThreadID(); virtual AbstractPart * partForPartID(String * partID); diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index f8acd25b..c228eb41 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -50,7 +50,7 @@ @property (nonatomic, copy) NSArray * /* NSString */ gmailLabels; /** Gmail thread iD of the message */ -@property (nonatomic, copy) NSString * /* NSString */ gmailThreadID; +@property (nonatomic, copy) NSString * gmailThreadID; /** Returns the part with the given part identifier. -- cgit v1.2.3 From 9682845dd6a6985f396a93ff95adc1dcdeae8861 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 22 Jun 2013 22:28:41 -0700 Subject: Retain session when IMAP and SMTP operations are running. Fixed #127, fixed #128. --- build-mac/mailcore2.xcodeproj/project.pbxproj | 4 ++ src/async/imap/MCIMAPAsyncConnection.cc | 33 ++++++++++++- src/async/imap/MCIMAPAsyncConnection.h | 9 +++- src/async/imap/MCIMAPAsyncSession.cc | 1 + src/async/smtp/MCSMTPAsyncSession.cc | 8 ++- src/async/smtp/MCSMTPSendWithDataOperation.cc | 2 - src/core/basetypes/MCOperationQueue.cc | 6 ++- src/core/basetypes/MCOperationQueueCallback.h | 3 +- src/objc/imap/MCOIMAPBaseOperation+Private.h | 20 ++++++++ src/objc/imap/MCOIMAPBaseOperation.mm | 15 ++++++ src/objc/imap/MCOIMAPOperation.h | 4 +- src/objc/imap/MCOIMAPSession.mm | 70 +++++++++++++++++---------- src/objc/smtp/MCOSMTPOperation+Private.h | 20 ++++++++ src/objc/smtp/MCOSMTPOperation.mm | 14 ++++++ src/objc/smtp/MCOSMTPSession.mm | 9 +++- 15 files changed, 181 insertions(+), 37 deletions(-) create mode 100644 src/objc/imap/MCOIMAPBaseOperation+Private.h create mode 100644 src/objc/smtp/MCOSMTPOperation+Private.h diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 41df2d15..a53e93ad 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -1076,11 +1076,13 @@ C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPSession.mm; sourceTree = ""; }; C07AD44B013BB42A240B4F04 /* NSError+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MCO.h"; sourceTree = ""; }; C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+MCO.mm"; sourceTree = ""; }; + C60136941776B96600A5AF45 /* MCOSMTPOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOSMTPOperation+Private.h"; sourceTree = ""; }; C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCSMTPDisconnectOperation.cc; sourceTree = ""; }; C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCSMTPDisconnectOperation.h; sourceTree = ""; }; C6081678177625AD001F1018 /* MCOperationQueueCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOperationQueueCallback.h; sourceTree = ""; }; C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPDisconnectOperation.cc; sourceTree = ""; }; C608167A177635D2001F1018 /* MCIMAPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPDisconnectOperation.h; sourceTree = ""; }; + C608167F17766FC5001F1018 /* MCOIMAPBaseOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOIMAPBaseOperation+Private.h"; sourceTree = ""; }; C623C58A16FD8C22001BBEFC /* MCOAbstractMessage+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOAbstractMessage+Private.h"; sourceTree = ""; }; C623C58B16FE52C0001BBEFC /* MCOHTMLRendererDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOHTMLRendererDelegate.h; sourceTree = ""; }; C623C58D16FE6B45001BBEFC /* MCOIMAPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPOperation.h; sourceTree = ""; }; @@ -2029,6 +2031,7 @@ C6A81BC117068E9500882C15 /* MCOSMTPSendOperation.h */, C6A81BC217068E9500882C15 /* MCOSMTPSendOperation.mm */, C6A81BC517068EB000882C15 /* MCOSMTPOperation.h */, + C60136941776B96600A5AF45 /* MCOSMTPOperation+Private.h */, C6A81BC617068EB000882C15 /* MCOSMTPOperation.mm */, ); path = smtp; @@ -2063,6 +2066,7 @@ C6F61F79170169EE0073032E /* MCOIMAPFolderInfoOperation.h */, C6F61F7A170169EE0073032E /* MCOIMAPFolderInfoOperation.mm */, C6F61FB31702AB2A0073032E /* MCOIMAPBaseOperation.h */, + C608167F17766FC5001F1018 /* MCOIMAPBaseOperation+Private.h */, C6F61FB41702AB2F0073032E /* MCOIMAPBaseOperation.mm */, C6F61F7C170169FB0073032E /* MCOIMAPAppendMessageOperation.h */, C6F61F7D170169FB0073032E /* MCOIMAPAppendMessageOperation.mm */, diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 02320b3a..ed40932c 100644 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -32,6 +32,7 @@ #include "MCIMAPCapabilityOperation.h" #include "MCOperationQueueCallback.h" #include "MCIMAPDisconnectOperation.h" +#include "MCIMAPAsyncSession.h" using namespace mailcore; @@ -45,8 +46,13 @@ namespace mailcore { virtual ~IMAPOperationQueueCallback() { } - virtual void queueIdle() { + virtual void queueStartRunning() { + mConnection->queueStartRunning(); + } + + virtual void queueStoppedRunning() { mConnection->tryAutomaticDisconnect(); + mConnection->queueStoppedRunning(); } private: @@ -63,10 +69,12 @@ IMAPAsyncConnection::IMAPAsyncConnection() mLastFolder = NULL; mQueueCallback = new IMAPOperationQueueCallback(this); mQueue->setCallback(mQueueCallback); + mOwner = NULL; } IMAPAsyncConnection::~IMAPAsyncConnection() { + cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL); MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mLastFolder); MC_SAFE_RELEASE(mDefaultNamespace); @@ -485,6 +493,18 @@ void IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay(void * context) op->start(); } +void IMAPAsyncConnection::queueStartRunning() +{ + this->retain(); + mOwner->retain(); +} + +void IMAPAsyncConnection::queueStoppedRunning() +{ + mOwner->release(); + this->release(); +} + void IMAPAsyncConnection::setLastFolder(String * folder) { MC_SAFE_REPLACE_COPY(String, mLastFolder, folder); @@ -495,3 +515,14 @@ String * IMAPAsyncConnection::lastFolder() return mLastFolder; } +void IMAPAsyncConnection::setOwner(IMAPAsyncSession * owner) +{ + mOwner = owner; +} + +IMAPAsyncSession * IMAPAsyncConnection::owner() +{ + return mOwner; +} + + diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 7869644c..d6ef6a91 100644 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -26,6 +26,7 @@ namespace mailcore { class IMAPIdentityOperation; class IMAPCapabilityOperation; class IMAPOperationQueueCallback; + class IMAPAsyncSession; class IMAPAsyncConnection : public Object { public: @@ -118,7 +119,8 @@ namespace mailcore { IMAPNamespace * mDefaultNamespace; String * mLastFolder; IMAPOperationQueueCallback * mQueueCallback; - + IMAPAsyncSession * mOwner; + virtual void tryAutomaticDisconnectAfterDelay(void * context); public: // private @@ -131,6 +133,11 @@ namespace mailcore { virtual String * lastFolder(); virtual void tryAutomaticDisconnect(); + virtual void queueStartRunning(); + virtual void queueStoppedRunning(); + + virtual void setOwner(IMAPAsyncSession * owner); + virtual IMAPAsyncSession * owner(); }; } diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 3fbd5470..7c085e4a 100644 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -174,6 +174,7 @@ unsigned int IMAPAsyncSession::maximumConnections() IMAPAsyncConnection * IMAPAsyncSession::session() { IMAPAsyncConnection * session = new IMAPAsyncConnection(); + session->setOwner(this); session->autorelease(); session->setHostname(mHostname); diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc index cf028ced..73bc2a54 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cc +++ b/src/async/smtp/MCSMTPAsyncSession.cc @@ -19,8 +19,13 @@ namespace mailcore { virtual ~SMTPOperationQueueCallback() { } - virtual void queueIdle() { + virtual void queueStartRunning() { + mSession->retain(); + } + + virtual void queueStoppedRunning() { mSession->tryAutomaticDisconnect(); + mSession->release(); } private: @@ -38,6 +43,7 @@ SMTPAsyncSession::SMTPAsyncSession() SMTPAsyncSession::~SMTPAsyncSession() { + cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL); MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mQueue); MC_SAFE_RELEASE(mSession); diff --git a/src/async/smtp/MCSMTPSendWithDataOperation.cc b/src/async/smtp/MCSMTPSendWithDataOperation.cc index b64f835b..bb2c5ea9 100644 --- a/src/async/smtp/MCSMTPSendWithDataOperation.cc +++ b/src/async/smtp/MCSMTPSendWithDataOperation.cc @@ -38,6 +38,4 @@ void SMTPSendWithDataOperation::main() ErrorCode error; session()->session()->sendMessage(mMessageData, this, &error); setError(error); - - //tryAutomaticDisconnect(); } diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index f13c9cde..e448c237 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -158,7 +158,7 @@ void OperationQueue::stoppedOnMainThread(void * context) mStarted = false; if (mCallback) { - mCallback->queueIdle(); + mCallback->queueStoppedRunning(); } release(); // (2) @@ -171,6 +171,10 @@ void OperationQueue::startThread() if (mStarted) return; + if (mCallback) { + mCallback->queueStartRunning(); + } + retain(); // (3) mQuitting = false; mStarted = true; diff --git a/src/core/basetypes/MCOperationQueueCallback.h b/src/core/basetypes/MCOperationQueueCallback.h index bf7868ae..367888bb 100644 --- a/src/core/basetypes/MCOperationQueueCallback.h +++ b/src/core/basetypes/MCOperationQueueCallback.h @@ -15,7 +15,8 @@ namespace mailcore { class OperationQueueCallback { public: - virtual void queueIdle() {} + virtual void queueStartRunning() {} + virtual void queueStoppedRunning() {} }; } diff --git a/src/objc/imap/MCOIMAPBaseOperation+Private.h b/src/objc/imap/MCOIMAPBaseOperation+Private.h new file mode 100644 index 00000000..e744355a --- /dev/null +++ b/src/objc/imap/MCOIMAPBaseOperation+Private.h @@ -0,0 +1,20 @@ +// +// Header.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCOIMAPBASEOPERATION_PRIVATE_H_ +#define __MAILCORE_MCOIMAPBASEOPERATION_PRIVATE_H_ + +@class MCOIMAPSession; + +@interface MCOIMAPBaseOperation (Private) + +@property (nonatomic, retain) MCOIMAPSession * session; + +@end + +#endif diff --git a/src/objc/imap/MCOIMAPBaseOperation.mm b/src/objc/imap/MCOIMAPBaseOperation.mm index be398ece..ed67e34e 100644 --- a/src/objc/imap/MCOIMAPBaseOperation.mm +++ b/src/objc/imap/MCOIMAPBaseOperation.mm @@ -7,10 +7,12 @@ // #import "MCOIMAPBaseOperation.h" +#import "MCOIMAPBaseOperation+Private.h" #import "MCOOperation+Private.h" #import "MCAsyncIMAP.h" +#import "MCOIMAPSession.h" class MCOIMAPBaseOperationIMAPCallback : public mailcore::IMAPOperationCallback { public: @@ -33,6 +35,7 @@ private: @implementation MCOIMAPBaseOperation { MCOIMAPBaseOperationIMAPCallback * _imapCallback; + MCOIMAPSession * _session; } - (id) initWithMCOperation:(mailcore::Operation *)op @@ -47,10 +50,22 @@ private: - (void) dealloc { + [_session release]; delete _imapCallback; [super dealloc]; } +- (void) setSession:(MCOIMAPSession *)session +{ + [_session release]; + _session = [session retain]; +} + +- (MCOIMAPSession *) session +{ + return _session; +} + - (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum { } diff --git a/src/objc/imap/MCOIMAPOperation.h b/src/objc/imap/MCOIMAPOperation.h index b8ee37e4..6f286596 100644 --- a/src/objc/imap/MCOIMAPOperation.h +++ b/src/objc/imap/MCOIMAPOperation.h @@ -12,9 +12,9 @@ /** This class implements a generic IMAP operation */ -#import +#import -@interface MCOIMAPOperation : MCOOperation +@interface MCOIMAPOperation : MCOIMAPBaseOperation /** Starts the asynchronous append operation. diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index a13724ae..a8df8aed 100644 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -13,6 +13,7 @@ #import "MCOObjectWrapper.h" #import "MCOIMAPOperation.h" #import "MCOIMAPFetchFoldersOperation.h" +#import "MCOIMAPBaseOperation+Private.h" #import "MCOUtils.h" @@ -60,57 +61,74 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma #pragma mark - Operations +#define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op]; +#define OPAQUE_OPERATION(op) [self _objcOpaqueOperationFromNativeOp:op] + +- (id) _objcOperationFromNativeOp:(IMAPOperation *)op +{ + MCOIMAPBaseOperation * result = MCO_TO_OBJC(op); + [result setSession:self]; + return result; +} + +- (id) _objcOpaqueOperationFromNativeOp:(IMAPOperation *)op +{ + MCOIMAPOperation * result = [[[MCOIMAPOperation alloc] initWithMCOperation:op] autorelease]; + [result setSession:self]; + return result; +} + - (MCOIMAPFolderInfoOperation *) folderInfoOperation:(NSString *)folder { IMAPFolderInfoOperation * coreOp = MCO_NATIVE_INSTANCE->folderInfoOperation([folder mco_mcString]); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFolderStatusOperation *) folderStatusOperation:(NSString *)folder { IMAPFolderStatusOperation * coreOp = MCO_NATIVE_INSTANCE->folderStatusOperation([folder mco_mcString]); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchFoldersOperation *) fetchSubscribedFoldersOperation { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->fetchSubscribedFoldersOperation(); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchFoldersOperation *)fetchAllFoldersOperation { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->fetchAllFoldersOperation(); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPOperation *) renameFolderOperation:(NSString *)folder otherName:(NSString *)otherName { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->renameFolderOperation([folder mco_mcString], [otherName mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPOperation *) deleteFolderOperation:(NSString *)folder { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->deleteFolderOperation([folder mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPOperation *) createFolderOperation:(NSString *)folder { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->createFolderOperation([folder mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPOperation *) subscribeFolderOperation:(NSString *)folder { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->subscribeFolderOperation([folder mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPOperation *) unsubscribeFolderOperation:(NSString *)folder { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->unsubscribeFolderOperation([folder mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder @@ -120,7 +138,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPAppendMessageOperation * coreOp = MCO_NATIVE_INSTANCE->appendMessageOperation([folder mco_mcString], [messageData mco_mcData], (MessageFlag) flags); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPCopyMessagesOperation *)copyMessagesOperationWithFolder:(NSString *)folder @@ -130,14 +148,14 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPCopyMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->copyMessagesOperation([folder mco_mcString], MCO_FROM_OBJC(IndexSet, uids), [destFolder mco_mcString]); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPOperation *) expungeOperation:(NSString *)folder { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->expungeOperation([folder mco_mcString]); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPFetchMessagesOperation *) fetchMessagesByUIDOperationWithFolder:(NSString *)folder @@ -147,7 +165,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesByUIDOperation([folder mco_mcString], (IMAPMessagesRequestKind) requestKind, MCO_FROM_OBJC(IndexSet, uids)); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchMessagesOperation *) fetchMessagesByNumberOperationWithFolder:(NSString *)folder @@ -157,7 +175,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesByNumberOperation([folder mco_mcString], (IMAPMessagesRequestKind) requestKind, MCO_FROM_OBJC(IndexSet, numbers)); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchMessagesOperation *) syncMessagesByUIDWithFolder:(NSString *)folder @@ -169,7 +187,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma (IMAPMessagesRequestKind) requestKind, MCO_FROM_OBJC(IndexSet, uids), modSeq); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder @@ -177,7 +195,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma urgent:(BOOL)urgent { IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageByUIDOperation([folder mco_mcString], uid, urgent); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder @@ -197,7 +215,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma [partID mco_mcString], (Encoding) encoding, urgent); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder @@ -217,7 +235,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma MCO_FROM_OBJC(IndexSet, uids), (IMAPStoreFlagsRequestKind) kind, (MessageFlag) flags); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPOperation *) storeLabelsOperationWithFolder:(NSString *)folder @@ -229,7 +247,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma MCO_FROM_OBJC(IndexSet, uids), (IMAPStoreFlagsRequestKind) kind, MCO_FROM_OBJC(Array, labels)); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPSearchOperation *) searchOperationWithFolder:(NSString *)folder @@ -239,7 +257,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPSearchOperation * coreOp = MCO_NATIVE_INSTANCE->searchOperation([folder mco_mcString], (IMAPSearchKind) kind, [searchString mco_mcString]); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPSearchOperation *) searchExpressionOperationWithFolder:(NSString *)folder @@ -247,20 +265,20 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma { IMAPSearchOperation * coreOp = MCO_NATIVE_INSTANCE->searchOperation([folder mco_mcString], MCO_FROM_OBJC(IMAPSearchExpression, expression)); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPIdleOperation *) idleOperationWithFolder:(NSString *)folder lastKnownUID:(uint32_t)lastKnownUID { IMAPIdleOperation * coreOp = MCO_NATIVE_INSTANCE->idleOperation([folder mco_mcString], lastKnownUID); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPFetchNamespaceOperation *) fetchNamespaceOperation { IMAPFetchNamespaceOperation * coreOp = MCO_NATIVE_INSTANCE->fetchNamespaceOperation(); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPIdentityOperation *) identityOperationWithVendor:(NSString *)vendor @@ -270,19 +288,19 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma IMAPIdentityOperation * coreOp = MCO_NATIVE_INSTANCE->identityOperation([vendor mco_mcString], [name mco_mcString], [version mco_mcString]); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOIMAPOperation *)checkAccountOperation { IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(); - return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOIMAPCapabilityOperation *) capabilityOperation { IMAPCapabilityOperation * coreOp = MCO_NATIVE_INSTANCE->capabilityOperation(); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } @end diff --git a/src/objc/smtp/MCOSMTPOperation+Private.h b/src/objc/smtp/MCOSMTPOperation+Private.h new file mode 100644 index 00000000..5b9b5ee9 --- /dev/null +++ b/src/objc/smtp/MCOSMTPOperation+Private.h @@ -0,0 +1,20 @@ +// +// MCOSMTPOperation+Private.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCOSMTPOPERATION_PRIVATE_H_ +#define __MAILCORE_MCOSMTPOPERATION_PRIVATE_H_ + +@class MCOSMTPSession; + +@interface MCOSMTPOperation (Private) + +@property (nonatomic, retain) MCOSMTPSession * session; + +@end + +#endif diff --git a/src/objc/smtp/MCOSMTPOperation.mm b/src/objc/smtp/MCOSMTPOperation.mm index d95c434d..cd52ad13 100644 --- a/src/objc/smtp/MCOSMTPOperation.mm +++ b/src/objc/smtp/MCOSMTPOperation.mm @@ -12,17 +12,20 @@ #import "MCOUtils.h" #import "MCOOperation+Private.h" +#import "MCOSMTPSession.h" typedef void (^CompletionType)(NSError *error); @implementation MCOSMTPOperation { CompletionType _completionBlock; + MCOSMTPSession * _session; } #define nativeType mailcore::SMTPOperation - (void) dealloc { + [_session release]; [_completionBlock release]; [super dealloc]; } @@ -40,4 +43,15 @@ typedef void (^CompletionType)(NSError *error); _completionBlock(error); } +- (void) setSession:(MCOSMTPSession *)session +{ + [_session release]; + _session = [session retain]; +} + +- (MCOSMTPSession *) session +{ + return _session; +} + @end diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index ad8f212e..de6b54cd 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -15,6 +15,7 @@ #import "MCOSMTPOperation.h" #import "MCOOperation+Private.h" #import "MCOAddress.h" +#import "MCOSMTPOperation+Private.h" @implementation MCOSMTPSession { mailcore::SMTPAsyncSession * _session; @@ -55,13 +56,17 @@ MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled) - (MCOSMTPSendOperation *) sendOperationWithData:(NSData *)messageData { mailcore::SMTPOperation * coreOp = MCO_NATIVE_INSTANCE->sendMessageOperation([messageData mco_mcData]); - return [[[MCOSMTPSendOperation alloc] initWithMCOperation:coreOp] autorelease]; + MCOSMTPSendOperation * result = [[[MCOSMTPSendOperation alloc] initWithMCOperation:coreOp] autorelease]; + [result setSession:self]; + return result; } - (MCOOperation *) checkAccountOperationWithFrom:(MCOAddress *)from { mailcore::SMTPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(MCO_FROM_OBJC(mailcore::Address, from)); - return [[[MCOSMTPOperation alloc] initWithMCOperation:coreOp] autorelease]; + MCOSMTPOperation * result = [[[MCOSMTPOperation alloc] initWithMCOperation:coreOp] autorelease]; + [result setSession:self]; + return result; } @end -- cgit v1.2.3 From b203675deaaf0049b7093587ce8fb30bb6ab3d9a Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 22 Jun 2013 23:04:01 -0700 Subject: POP operations retain the session. Fixed #129 --- build-mac/mailcore2.xcodeproj/project.pbxproj | 2 ++ src/async/pop/MCPOPAsyncSession.cc | 28 +++++++++++++++++++++++- src/async/pop/MCPOPAsyncSession.h | 4 +++- src/core/smtp/MCSMTPSession.cc | 2 -- src/objc/pop/MCOPOPOperation+Private.h | 20 +++++++++++++++++ src/objc/pop/MCOPOPOperation.mm | 13 +++++++++++ src/objc/pop/MCOPOPSession.mm | 31 +++++++++++++++++++++------ 7 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 src/objc/pop/MCOPOPOperation+Private.h diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index a53e93ad..0f932f5c 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -1077,6 +1077,7 @@ C07AD44B013BB42A240B4F04 /* NSError+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MCO.h"; sourceTree = ""; }; C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+MCO.mm"; sourceTree = ""; }; C60136941776B96600A5AF45 /* MCOSMTPOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOSMTPOperation+Private.h"; sourceTree = ""; }; + C60136951776C31000A5AF45 /* MCOPOPOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOPOPOperation+Private.h"; sourceTree = ""; }; C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCSMTPDisconnectOperation.cc; sourceTree = ""; }; C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCSMTPDisconnectOperation.h; sourceTree = ""; }; C6081678177625AD001F1018 /* MCOperationQueueCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOperationQueueCallback.h; sourceTree = ""; }; @@ -2009,6 +2010,7 @@ C6A81BD41706903500882C15 /* MCOPOPSession.h */, C6A81BD51706903500882C15 /* MCOPOPSession.mm */, C6A81BE01706905600882C15 /* MCOPOPOperation.h */, + C60136951776C31000A5AF45 /* MCOPOPOperation+Private.h */, C6A81BE11706905600882C15 /* MCOPOPOperation.mm */, C6A81BD81706903E00882C15 /* MCOPOPFetchHeaderOperation.h */, C6A81BD91706903E00882C15 /* MCOPOPFetchHeaderOperation.mm */, diff --git a/src/async/pop/MCPOPAsyncSession.cc b/src/async/pop/MCPOPAsyncSession.cc index 39f356db..1269a34b 100644 --- a/src/async/pop/MCPOPAsyncSession.cc +++ b/src/async/pop/MCPOPAsyncSession.cc @@ -14,17 +14,44 @@ #include "MCPOPDeleteMessagesOperation.h" #include "MCPOPFetchMessagesOperation.h" #include "MCPOPCheckAccountOperation.h" +#include "MCOperationQueueCallback.h" using namespace mailcore; +namespace mailcore { + class POPOperationQueueCallback : public Object, public OperationQueueCallback { + public: + POPOperationQueueCallback(POPAsyncSession * session) { + mSession = session; + } + + virtual ~POPOperationQueueCallback() { + } + + virtual void queueStartRunning() { + mSession->retain(); + } + + virtual void queueStoppedRunning() { + mSession->release(); + } + + private: + POPAsyncSession * mSession; + }; +} + POPAsyncSession::POPAsyncSession() { mSession = new POPSession(); mQueue = new OperationQueue(); + mQueueCallback = new POPOperationQueueCallback(this); + mQueue->setCallback(mQueueCallback); } POPAsyncSession::~POPAsyncSession() { + MC_SAFE_RELEASE(mQueueCallback); MC_SAFE_RELEASE(mSession); MC_SAFE_RELEASE(mQueue); } @@ -164,6 +191,5 @@ POPSession * POPAsyncSession::session() void POPAsyncSession::runOperation(POPOperation * operation) { -#warning disconnect after delay mQueue->addOperation(operation); } diff --git a/src/async/pop/MCPOPAsyncSession.h b/src/async/pop/MCPOPAsyncSession.h index 166675e0..452d4d75 100644 --- a/src/async/pop/MCPOPAsyncSession.h +++ b/src/async/pop/MCPOPAsyncSession.h @@ -22,7 +22,8 @@ namespace mailcore { class POPFetchMessageOperation; class POPDeleteMessagesOperation; class POPFetchMessagesOperation; - + class POPOperationQueueCallback; + class POPAsyncSession : public Object { public: POPAsyncSession(); @@ -68,6 +69,7 @@ namespace mailcore { private: POPSession * mSession; OperationQueue * mQueue; + POPOperationQueueCallback * mQueueCallback; public: // private virtual void runOperation(POPOperation * operation); diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index 3e49ea5f..ee225b16 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -44,12 +44,10 @@ SMTPSession::SMTPSession() SMTPSession::~SMTPSession() { - MCLog("dealloc"); MC_SAFE_RELEASE(mLastSMTPResponse); MC_SAFE_RELEASE(mHostname); MC_SAFE_RELEASE(mUsername); MC_SAFE_RELEASE(mPassword); - MCLog("dealloc4"); } void SMTPSession::setHostname(String * hostname) diff --git a/src/objc/pop/MCOPOPOperation+Private.h b/src/objc/pop/MCOPOPOperation+Private.h new file mode 100644 index 00000000..1d888f08 --- /dev/null +++ b/src/objc/pop/MCOPOPOperation+Private.h @@ -0,0 +1,20 @@ +// +// MCOPOPOperation+Private.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 6/22/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCOPOPOPERATION_PRIVATE_H_ +#define __MAILCORE_MCOPOPOPERATION_PRIVATE_H_ + +@class MCOPOPSession; + +@interface MCOPOPOperation (Private) + +@property (nonatomic, retain) MCOPOPSession * session; + +@end + +#endif diff --git a/src/objc/pop/MCOPOPOperation.mm b/src/objc/pop/MCOPOPOperation.mm index 7bb17bb8..9b58f84d 100644 --- a/src/objc/pop/MCOPOPOperation.mm +++ b/src/objc/pop/MCOPOPOperation.mm @@ -12,17 +12,20 @@ #import "MCOUtils.h" #import "MCOOperation+Private.h" +#import "MCOPOPSession.h" typedef void (^CompletionType)(NSError *error); @implementation MCOPOPOperation { CompletionType _completionBlock; + MCOPOPSession * _session; } #define nativeType mailcore::POPOperation - (void) dealloc { + [_session release]; [_completionBlock release]; [super dealloc]; } @@ -40,5 +43,15 @@ typedef void (^CompletionType)(NSError *error); _completionBlock(error); } +- (void) setSession:(MCOPOPSession *)session +{ + [_session release]; + _session = [session retain]; +} + +- (MCOPOPSession *) session +{ + return _session; +} @end diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm index 10806937..11f7cad6 100644 --- a/src/objc/pop/MCOPOPSession.mm +++ b/src/objc/pop/MCOPOPSession.mm @@ -14,6 +14,7 @@ #import "MCOPOPOperation.h" #import "MCOOperation+Private.h" #import "MCOPOPFetchMessagesOperation.h" +#import "MCOPOPOperation+Private.h" @implementation MCOPOPSession { mailcore::POPAsyncSession * _session; @@ -55,41 +56,59 @@ MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) #pragma mark - Operations + +#define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op]; +#define OPAQUE_OPERATION(op) [self _objcOpaqueOperationFromNativeOp:op] + +- (id) _objcOperationFromNativeOp:(mailcore::POPOperation *)op +{ + MCOPOPOperation * result = MCO_TO_OBJC(op); + [result setSession:self]; + return result; +} + +- (id) _objcOpaqueOperationFromNativeOp:(mailcore::POPOperation *)op +{ + MCOPOPOperation * result = [[[MCOPOPOperation alloc] initWithMCOperation:op] autorelease]; + [result setSession:self]; + return result; +} + - (MCOPOPFetchMessagesOperation *) fetchMessagesOperation { mailcore::POPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesOperation(); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOPOPFetchHeaderOperation *) fetchHeaderOperationWithIndex:(unsigned int)index { mailcore::POPFetchHeaderOperation * coreOp = MCO_NATIVE_INSTANCE->fetchHeaderOperation(index); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } - (MCOPOPFetchMessageOperation *) fetchMessageOperationWithIndex:(unsigned int)index; { mailcore::POPFetchMessageOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageOperation(index); - return MCO_TO_OBJC(coreOp); + return MCO_TO_OBJC_OP(coreOp); } // Will disconnect. - (MCOPOPOperation *) deleteMessagesOperationWithIndexes:(MCOIndexSet *)indexes { mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->deleteMessagesOperation(MCO_FROM_OBJC(mailcore::IndexSet, indexes)); - return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOPOPOperation *) disconnectOperation { mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->disconnectOperation(); - return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } - (MCOPOPOperation *) checkAccountOperation { mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(); - return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease]; + return OPAQUE_OPERATION(coreOp); } @end -- cgit v1.2.3 From 87eb9cde23d513460ddd42ed252a6ec49ac6c38f Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sun, 23 Jun 2013 11:53:56 -0600 Subject: Fixed threadID types --- .../macExample/macExample/MCTMsgListViewController.m | 4 ++-- src/core/abstract/MCMessageConstants.h | 1 + src/core/imap/MCIMAPMessage.cc | 6 +++--- src/core/imap/MCIMAPMessage.h | 18 +++++++++--------- src/core/imap/MCIMAPSession.cc | 7 +++---- src/objc/imap/MCOIMAPMessage.h | 2 +- src/objc/imap/MCOIMAPMessage.mm | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/example/mac/macExample/macExample/MCTMsgListViewController.m b/example/mac/macExample/macExample/MCTMsgListViewController.m index 498c66d1..441ebf9e 100644 --- a/example/mac/macExample/macExample/MCTMsgListViewController.m +++ b/example/mac/macExample/macExample/MCTMsgListViewController.m @@ -40,7 +40,7 @@ MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind) (MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure | MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject | - MCOIMAPMessagesRequestKindFlags); + MCOIMAPMessagesRequestKindFlags | MCOIMAPMessagesRequestKindGmailThreadID); _op = [_session fetchMessagesByUIDOperationWithFolder:FOLDER requestKind:requestKind uids:[MCOIndexSet indexSetWithRange:MCORangeMake(1, UINT64_MAX)]]; [_op setProgress:^(unsigned int current){ @@ -54,7 +54,7 @@ _messages = [[messages sortedArrayUsingDescriptors:@[sort]] retain]; NSLog(@"%i messages", (int) [_messages count]); - //NSLog(@"%@", _messages); + NSLog(@"%llu", [[_messages objectAtIndex:0]gmailThreadID]); [_tableView reloadData]; self.loading = NO; }]; diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index c06acd06..eb9e80f4 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -65,6 +65,7 @@ namespace mailcore { IMAPMessagesRequestKindFullHeaders = 1 << 4, IMAPMessagesRequestKindHeaderSubject = 1 << 5, IMAPMessagesRequestKindGmailLabels = 1 << 6, + IMAPMessagesRequestKindGmailThreadID = 1 << 7, }; enum IMAPFetchRequestType { diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 5e55ddcc..f8b9f4e6 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -122,12 +122,12 @@ Array * IMAPMessage::gmailLabels() return mLabels; } -void IMAPMessage::setGmailThreadID(String * threadID) +void IMAPMessage::setGmailThreadID(uint64_t threadID) { - MC_SAFE_REPLACE_COPY(String, mThreadID, threadID); + mThreadID = threadID; } -String * IMAPMessage::gmailThreadID() +uint64_t IMAPMessage::gmailThreadID() { return mThreadID; } diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index 3a54f4f5..3c2ee9c0 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -10,13 +10,13 @@ #ifdef __cplusplus namespace mailcore { - + class IMAPPart; class HTMLRendererIMAPCallback; class HTMLRendererTemplateCallback; - class IMAPMessage : public AbstractMessage { - public: + class IMAPMessage : public AbstractMessage { + public: IMAPMessage(); ~IMAPMessage(); @@ -38,8 +38,8 @@ namespace mailcore { virtual void setGmailLabels(Array * /* String */ labels); virtual Array * /* String */ gmailLabels(); - virtual void setGmailThreadID(String * threadID); - virtual String * gmailThreadID(); + virtual void setGmailThreadID(uint64_t threadID); + virtual uint64_t gmailThreadID(); virtual AbstractPart * partForPartID(String * partID); @@ -55,17 +55,17 @@ namespace mailcore { virtual Object * copy(); virtual String * description(); - private: + private: uint64_t mModSeqValue; uint32_t mUid; MessageFlag mFlags; MessageFlag mOriginalFlags; AbstractPart * mMainPart; Array * /* String */ mLabels; - String * mThreadID; + uint64_t mThreadID; void init(); - }; - + }; + } #endif diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 11e063ae..bad04a81 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -1724,10 +1724,10 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) labels->release(); } else if (ext_data->ext_extension == &mailimap_extension_xgmthrid) { - String * threadID; + uint64_t * threadID; - threadID = String::stringWithUTF8Characters((char *) ext_data->ext_data); - msg->setGmailThreadID(threadID); + threadID = (uint64_t *) ext_data->ext_data; + msg->setGmailThreadID(*threadID); hasGmailThreadID = true; } } @@ -1837,7 +1837,6 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest needsGmailLabels = true; } if ((requestKind & IMAPMessagesRequestKindGmailThreadID) != 0) { - MCLog("request flags"); fetch_att = mailimap_fetch_att_new_xgmthrid(); mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att); needsGmailThreadID = true; diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index c228eb41..ab9771ca 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -50,7 +50,7 @@ @property (nonatomic, copy) NSArray * /* NSString */ gmailLabels; /** Gmail thread iD of the message */ -@property (nonatomic, copy) NSString * gmailThreadID; +@property (nonatomic, assign) uint64_t gmailThreadID; /** Returns the part with the given part identifier. diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm index 5b8f7cdc..b5845bc2 100644 --- a/src/objc/imap/MCOIMAPMessage.mm +++ b/src/objc/imap/MCOIMAPMessage.mm @@ -47,7 +47,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFla MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setModSeqValue, modSeqValue) MCO_OBJC_SYNTHESIZE(AbstractPart, setMainPart, mainPart) MCO_OBJC_SYNTHESIZE_ARRAY(setGmailLabels, gmailLabels) -MCO_OBJC_SYNTHESIZE_STRING(setGmailThreadID, gmailThreadID) +MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setGmailThreadID, gmailThreadID) - (MCOAbstractPart *) partForPartID:(NSString *)partID { -- cgit v1.2.3 From 769d993d19604ac9b8b93733a6b6f488a44e0618 Mon Sep 17 00:00:00 2001 From: CodaFi Date: Sun, 23 Jun 2013 11:55:33 -0600 Subject: Remove log --- example/mac/macExample/macExample/MCTMsgListViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/mac/macExample/macExample/MCTMsgListViewController.m b/example/mac/macExample/macExample/MCTMsgListViewController.m index 441ebf9e..498c66d1 100644 --- a/example/mac/macExample/macExample/MCTMsgListViewController.m +++ b/example/mac/macExample/macExample/MCTMsgListViewController.m @@ -40,7 +40,7 @@ MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind) (MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure | MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject | - MCOIMAPMessagesRequestKindFlags | MCOIMAPMessagesRequestKindGmailThreadID); + MCOIMAPMessagesRequestKindFlags); _op = [_session fetchMessagesByUIDOperationWithFolder:FOLDER requestKind:requestKind uids:[MCOIndexSet indexSetWithRange:MCORangeMake(1, UINT64_MAX)]]; [_op setProgress:^(unsigned int current){ @@ -54,7 +54,7 @@ _messages = [[messages sortedArrayUsingDescriptors:@[sort]] retain]; NSLog(@"%i messages", (int) [_messages count]); - NSLog(@"%llu", [[_messages objectAtIndex:0]gmailThreadID]); + //NSLog(@"%@", _messages); [_tableView reloadData]; self.loading = NO; }]; -- cgit v1.2.3