From 3c9a9fdab616c7ba331d93da474a5bc551b352ec Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Wed, 15 Jan 2014 22:01:11 -0800 Subject: Fixed documentation of copyMessages --- src/objc/imap/MCOIMAPSession.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 867cfb6d..c04621b1 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -268,8 +268,8 @@ MCOIMAPCopyMessagesOperation * op = [session copyMessagesOperationWithFolder:@"INBOX" uids:[MCIndexSet indexSetWithIndex:456] destFolder:@"Cocoa"]; - [op start:^(NSError * error, MCOIndexSet * destUids) { - NSLog(@"copied to folder with UID %@", destUids); + [op start:^(NSError * error, NSDictionary * uidMapping) { + NSLog(@"copied to folder with UID mapping %@", uidMapping); }]; */ - (MCOIMAPCopyMessagesOperation *)copyMessagesOperationWithFolder:(NSString *)folder -- cgit v1.2.3 From 5fc6d09983b41fc02e3601565b0f925e2ae70bc8 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Thu, 16 Jan 2014 21:36:08 -0800 Subject: Revert "Use ICU of the system (fixed #533)" This reverts commit 46d412f1f057cfc0d138f3c16b5033310fe694af. --- README.md | 4 ++-- build-mac/mailcore2.xcodeproj/project.pbxproj | 24 ++++++++++++++-------- .../iOS UI Test.xcodeproj/project.pbxproj | 8 ++++++-- src/core/basetypes/MCData.cc | 1 - src/core/basetypes/MCString.cc | 1 - src/core/renderer/MCDateFormatter.cc | 1 - 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0f4cb271..b997a47c 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,14 @@ MailCore 2 provides a simple and asynchronous Objective-C API to work with the e - Click the `+` icon and select `MailCore.framework`. * Mac static library - Go to Build Phases from your build target, and under 'Link Binary With Libraries', add `libMailCore.a` and `Security.framework`. - - Set 'Other Linker Flags' under Build Settings: `-lctemplate -letpan -licucore -lxml2 -lsasl2 -liconv -ltidy -lz` `-lc++ -stdlib=libc++ -ObjC` + - Set 'Other Linker Flags' under Build Settings: `-lctemplate -letpan -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-lc++ -stdlib=libc++ -ObjC` - Make sure to use LLVM C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libc++`. - In Build Phases, add a Target Dependency of `static mailcore2 osx`. 5. **For iOS** - If you're targeting iOS, you have to link against MailCore 2 as a static library: * Add `libMailCore-ios.a` * Add `CFNetwork.framework` * Add `Security.framework` - * Set 'Other Linker Flags': `-lctemplate-ios -letpan-ios -licucore -lxml2 -lsasl2 -liconv -ltidy -lz` `-lstdc++ -stdlib=libstdc++ -ObjC` + * Set 'Other Linker Flags': `-lctemplate-ios -letpan-ios -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lz` `-lstdc++ -stdlib=libstdc++ -ObjC` * Make sure to use GNU C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libstdc++`. * In Build Phases, add a Target Dependency of `static mailcore2 ios`. 6. Profit. diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index 91159176..b75a25b0 100755 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -3000,7 +3000,7 @@ "HEADER_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(IOS_HEADERS_SEARCH_PATHS)"; "HEADER_SEARCH_PATHS[sdk=macosx*]" = "$(OSX_HEADERS_SEARCH_PATHS)"; IOS_HEADERS_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/include\" \"$(SRCROOT)/../Externals/icu4c-ios/include\" \"$(SRCROOT)/../Externals/ctemplate-ios/include\" \"$(SRCROOT)/../Externals/tidy-html5-ios/include/tidy\" /usr/include/libxml2"; - IOS_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/lib\" \"$(SRCROOT)/../Externals/ctemplate-ios/lib\" \"$(SRCROOT)/../Externals/libsasl-ios/lib\" \"$(SRCROOT)/../Externals/tidy-html5-ios/lib\""; + IOS_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/lib\" \"$(SRCROOT)/../Externals/icu4c-ios/lib\" \"$(SRCROOT)/../Externals/ctemplate-ios/lib\" \"$(SRCROOT)/../Externals/libsasl-ios/lib\" \"$(SRCROOT)/../Externals/tidy-html5-ios/lib\""; LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/../Externals/libetpan/lib\"", "\"$(SRCROOT)/../Externals/icu4c/lib\"", @@ -3012,7 +3012,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; OSX_HEADERS_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/include\" \"$(SRCROOT)/../Externals/icu4c/include\" \"$(SRCROOT)/../Externals/ctemplate/include\" /usr/include/tidy /usr/include/libxml2"; - OSX_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/lib\" \"$(SRCROOT)/../Externals/ctemplate/lib\""; + OSX_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/lib\" \"$(SRCROOT)/../Externals/icu4c/lib\" \"$(SRCROOT)/../Externals/ctemplate/lib\""; }; name = Debug; }; @@ -3048,7 +3048,7 @@ "HEADER_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(IOS_HEADERS_SEARCH_PATHS)"; "HEADER_SEARCH_PATHS[sdk=macosx*]" = "$(OSX_HEADERS_SEARCH_PATHS)"; IOS_HEADERS_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/include\" \"$(SRCROOT)/../Externals/icu4c-ios/include\" \"$(SRCROOT)/../Externals/ctemplate-ios/include\" \"$(SRCROOT)/../Externals/tidy-html5-ios/include/tidy\" /usr/include/libxml2"; - IOS_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/lib\" \"$(SRCROOT)/../Externals/ctemplate-ios/lib\" \"$(SRCROOT)/../Externals/libsasl-ios/lib\" \"$(SRCROOT)/../Externals/tidy-html5-ios/lib\""; + IOS_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan-ios/lib\" \"$(SRCROOT)/../Externals/icu4c-ios/lib\" \"$(SRCROOT)/../Externals/ctemplate-ios/lib\" \"$(SRCROOT)/../Externals/libsasl-ios/lib\" \"$(SRCROOT)/../Externals/tidy-html5-ios/lib\""; LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/../Externals/libetpan/lib\"", "\"$(SRCROOT)/../Externals/icu4c/lib\"", @@ -3059,7 +3059,7 @@ "LIBRARY_SEARCH_PATHS[sdk=macosx*]" = "$(OSX_LIBRARY_SEARCH_PATHS)"; MACOSX_DEPLOYMENT_TARGET = 10.8; OSX_HEADERS_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/include\" \"$(SRCROOT)/../Externals/icu4c/include\" \"$(SRCROOT)/../Externals/ctemplate/include\" /usr/include/tidy /usr/include/libxml2"; - OSX_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/lib\" \"$(SRCROOT)/../Externals/ctemplate/lib\""; + OSX_LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../Externals/libetpan/lib\" \"$(SRCROOT)/../Externals/icu4c/lib\" \"$(SRCROOT)/../Externals/ctemplate/lib\""; }; name = Release; }; @@ -3121,7 +3121,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", @@ -3155,7 +3157,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", @@ -3216,7 +3220,9 @@ OTHER_LDFLAGS = ( "-lctemplate", "-letpan", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lssl", "-lcrypto", @@ -3246,7 +3252,9 @@ OTHER_LDFLAGS = ( "-lctemplate", "-letpan", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lssl", "-lcrypto", diff --git a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj index f3a94272..37556fc4 100644 --- a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj +++ b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj @@ -532,7 +532,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", @@ -556,7 +558,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", diff --git a/src/core/basetypes/MCData.cc b/src/core/basetypes/MCData.cc index c92c1122..4cd38839 100644 --- a/src/core/basetypes/MCData.cc +++ b/src/core/basetypes/MCData.cc @@ -3,7 +3,6 @@ #include #include #include -#define U_DISABLE_RENAMING 1 #include #include #include diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 3862cd4f..26e2f931 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -2,7 +2,6 @@ #include #include -#define U_DISABLE_RENAMING 1 #include #include #include diff --git a/src/core/renderer/MCDateFormatter.cc b/src/core/renderer/MCDateFormatter.cc index fc6ce215..2882977d 100644 --- a/src/core/renderer/MCDateFormatter.cc +++ b/src/core/renderer/MCDateFormatter.cc @@ -8,7 +8,6 @@ #include "MCDateFormatter.h" #include -#define U_DISABLE_RENAMING 1 #include #if defined(__APPLE__) -- cgit v1.2.3 From c6a69e24a0be5216e2bfcceaa69f6037cea41b4a Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Thu, 16 Jan 2014 21:48:43 -0800 Subject: Revert "Fixed build" This reverts commit a14de1c4ef5906f68e890635ae56aa4db2c0cde1. --- src/CMakeLists.txt | 38 ++++++-------------------------------- tests/CMakeLists.txt | 7 +------ 2 files changed, 7 insertions(+), 38 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a4bd029..3c368309 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,23 +1,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) IF(APPLE) - set(dir "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk") - IF(EXISTS "${dir}" AND IS_DIRECTORY "${dir}") - set(SDKROOT "${dir}") - ELSE() - set(dir "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk") - IF(EXISTS "${dir}" AND IS_DIRECTORY "${dir}") - set(SDKROOT "${dir}") - ENDIF() - ENDIF() - - IF(NOT SDKROOT) - message(FATAL_ERROR "ERROR: Could not find Mac OSX SDK 10.8 or 10.9") - ELSE() - message(STATUS "Found Mac OSX SDK: ${SDKROOT}") - ENDIF() - - set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -isysroot ${SDKROOT}") - set(CMAKE_C_FLAGS "-isysroot ${SDKROOT}") + set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++") ELSE() set(CMAKE_CXX_FLAGS "-std=gnu++0x") ENDIF() @@ -36,13 +19,11 @@ IF(APPLE) ${CMAKE_CURRENT_SOURCE_DIR}/../Externals/libetpan/include /usr/include/tidy /usr/include/libxml2 - ${SDKROOT}/usr/include - ${SDKROOT}/usr/include/tidy - ${SDKROOT}/usr/include/libxml2 ) set(additional_lib_searchpath ${CMAKE_CURRENT_SOURCE_DIR}/../Externals/ctemplate/lib + ${CMAKE_CURRENT_SOURCE_DIR}/../Externals/icu4c/lib ${CMAKE_CURRENT_SOURCE_DIR}/../Externals/libetpan/lib ) @@ -73,17 +54,10 @@ find_path(ICU4C_INCLUDE_DIR NAMES unicode/utf8.h PATHS ${additional_includes} ) -if(APPLE) - find_library(ICU4C_LIBRARY - NAMES icucore - PATHS ${additional_lib_searchpath} - ) -else() - find_library(ICU4C_LIBRARY - NAMES icuuc - PATHS ${additional_lib_searchpath} - ) -endif() +find_library(ICU4C_LIBRARY + NAMES icuuc + PATHS ${additional_lib_searchpath} +) if(NOT ICU4C_INCLUDE_DIR OR NOT ICU4C_LIBRARY) message(FATAL_ERROR "ERROR: Could not find icu4c") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index feee7d2c..61fa7120 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,10 +10,5 @@ find_library(SECURITYFRAMEWORK NAMES Security) find_library(CORESERVICESFRAMEWORK NAMES CoreServices) add_executable (tests main.mm test-all.mm) -if(APPLE) - set(ICU_LIBRARIES icucore) -else() - set(ICU_LIBRARIES icudata icui18n icuuc) -endif() -target_link_libraries (tests MailCore z etpan xml2 sasl2 iconv tidy ctemplate ssl crypto ${ICU_LIBRARIES} +target_link_libraries (tests MailCore z etpan xml2 icudata icui18n icuuc sasl2 iconv tidy ctemplate ssl crypto ${FOUNDATIONFRAMEWORK} ${SECURITYFRAMEWORK} ${CORESERVICESFRAMEWORK}) -- cgit v1.2.3 From a183284be1d02f427cea579119c060bc1af51401 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 18 Jan 2014 15:51:54 -0800 Subject: Fixed example memory management --- example/mac/macExample/macExample/AppDelegate.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/example/mac/macExample/macExample/AppDelegate.m b/example/mac/macExample/macExample/AppDelegate.m index 7be4bfc2..b5f07f85 100644 --- a/example/mac/macExample/macExample/AppDelegate.m +++ b/example/mac/macExample/macExample/AppDelegate.m @@ -156,10 +156,8 @@ finishedRefreshWithFetcher:(GTMHTTPFetcher *)fetcher [self willChangeValueForKey:@"loggingIn"]; - [self.checkOp release]; - _checkOp = nil; - [self.session release]; - _session = nil; + self.checkOp = nil; + self.session = nil; [self didChangeValueForKey:@"loggingIn"]; -- cgit v1.2.3 From 73de12e926af32038bb5c0b508289f9db51ebfc2 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 18 Jan 2014 15:52:57 -0800 Subject: Implemented Object::performMethodOnDispatchQueueAfterDelay() and fixed MCIMAPAsyncSession termination. --- src/async/imap/MCIMAPAsyncConnection.cc | 17 +++- src/async/imap/MCIMAPAsyncConnection.h | 1 + src/core/basetypes/MCObject.cc | 170 +++++++++++++++++++++++++------- src/core/basetypes/MCObject.h | 4 +- 4 files changed, 156 insertions(+), 36 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 8403b3ed..64f95dfb 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -105,6 +105,7 @@ IMAPAsyncConnection::IMAPAsyncConnection() mInternalLogger = new IMAPConnectionLogger(this); mAutomaticConfigurationEnabled = true; mQueueRunning = false; + mScheduledAutomaticDisconnect = false; } IMAPAsyncConnection::~IMAPAsyncConnection() @@ -562,14 +563,28 @@ void IMAPAsyncConnection::tryAutomaticDisconnect() return; } - cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL); + bool scheduledAutomaticDisconnect = mScheduledAutomaticDisconnect; + if (scheduledAutomaticDisconnect) { + cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL); + } + + mOwner->retain(); + mScheduledAutomaticDisconnect = true; performMethodAfterDelay((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL, 30); + + if (scheduledAutomaticDisconnect) { + mOwner->release(); + } } void IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay(void * context) { + mScheduledAutomaticDisconnect = false; + IMAPOperation * op = disconnectOperation(); op->start(); + + mOwner->release(); } void IMAPAsyncConnection::queueStartRunning() diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index ef6893c8..2c2ee505 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -151,6 +151,7 @@ namespace mailcore { pthread_mutex_t mConnectionLoggerLock; bool mAutomaticConfigurationEnabled; bool mQueueRunning; + bool mScheduledAutomaticDisconnect; virtual void tryAutomaticDisconnectAfterDelay(void * context); virtual IMAPMessageRenderingOperation * renderingOperation(IMAPMessage * message, diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 874e802d..9dcec15a 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include "MCAutoreleasePool.h" #include "MCString.h" @@ -139,11 +140,89 @@ static void initDelayedPerform() } struct mainThreadCallKeyData { + Object * dispatchQueueIdentifier; Object * obj; void * context; Object::Method method; }; +static void removeFromPerformHash(Object * obj, Object::Method method, void * context, void * targetDispatchQueue) +{ + chashdatum key; + struct mainThreadCallKeyData keyData; + Object * queueIdentifier = NULL; +#if __APPLE__ + queueIdentifier = (String *) dispatch_queue_get_specific((dispatch_queue_t) targetDispatchQueue, "MCDispatchQueueID"); +#endif + keyData.dispatchQueueIdentifier = queueIdentifier; + keyData.obj = obj; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + + chash_delete(delayedPerformHash, (chashdatum *) &key, NULL); +} + +static void queueIdentifierDestructor(void * identifier) +{ + Object * obj = (Object *) identifier; + MC_SAFE_RELEASE(obj); +} + +static void addToPerformHash(Object * obj, Object::Method method, void * context, void * targetDispatchQueue, + void * performValue) +{ + chashdatum key; + chashdatum value; + struct mainThreadCallKeyData keyData; + Object * queueIdentifier = NULL; +#if __APPLE__ + queueIdentifier = (String *) dispatch_queue_get_specific((dispatch_queue_t) targetDispatchQueue, "MCDispatchQueueID"); + if (queueIdentifier == NULL) { + queueIdentifier = new Object(); + dispatch_queue_set_specific((dispatch_queue_t) targetDispatchQueue, "MCDispatchQueueID", queueIdentifier, queueIdentifierDestructor); + } +#endif + keyData.dispatchQueueIdentifier = queueIdentifier; + keyData.obj = obj; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + value.data = performValue; + value.len = 0; + chash_set(delayedPerformHash, &key, &value, NULL); +} + +static void * getFromPerformHash(Object * obj, Object::Method method, void * context, void * targetDispatchQueue) +{ + chashdatum key; + chashdatum value; + struct mainThreadCallKeyData keyData; + int r; + + Object * queueIdentifier = NULL; +#if __APPLE__ + MCAssert(targetDispatchQueue != NULL); + queueIdentifier = (String *) dispatch_queue_get_specific((dispatch_queue_t) targetDispatchQueue, "MCDispatchQueueID"); + if (queueIdentifier == NULL) + return NULL; +#endif + keyData.dispatchQueueIdentifier = queueIdentifier; + keyData.obj = obj; + keyData.context = context; + keyData.method = method; + key.data = &keyData; + key.len = sizeof(keyData); + + r = chash_get(delayedPerformHash, &key, &value); + if (r < 0) + return NULL; + + return value.data; +} + static void performOnMainThread(void * info) { struct mainThreadCallData * data; @@ -173,15 +252,7 @@ static void performAfterDelay(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); - + removeFromPerformHash(obj, method, context, NULL); (obj->*method)(context); free(data); @@ -219,10 +290,57 @@ void Object::performMethodOnDispatchQueue(Method method, void * context, void * }); } } + +struct cancellableBlock { + void (^block)(void); + bool cancelled; +}; + +void Object::performMethodOnDispatchQueueAfterDelay(Method method, void * context, void * targetDispatchQueue, bool delay) +{ + initDelayedPerform(); + + __block bool cancelled = false; + + void (^cancelableBlock)(bool cancel) = ^(bool cancel) { + if (cancel) { + cancelled = true; + return; + } + if (!cancelled) { + (this->*method)(context); + } + }; + + void (^dupCancelableBlock)(bool cancel) = Block_copy(cancelableBlock); + + retain(); + addToPerformHash(this, method, context, targetDispatchQueue, (void *) dupCancelableBlock); + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)); + dispatch_after(popTime, (dispatch_queue_t) targetDispatchQueue, ^(void) { + removeFromPerformHash(this, method, context, targetDispatchQueue); + dupCancelableBlock(false); + Block_release(dupCancelableBlock); + release(); + }); +} + +void Object::cancelDelayedPerformMethodOnDispatchQueue(Method method, void * context, void * targetDispatchQueue) +{ + initDelayedPerform(); + void (^dupCancelableBlock)(bool cancel) = (void (^)(bool)) getFromPerformHash(this, method, context, targetDispatchQueue); + if (dupCancelableBlock == NULL) + return; + removeFromPerformHash(this, method, context, targetDispatchQueue); + dupCancelableBlock(true); +} #endif void Object::performMethodAfterDelay(Method method, void * context, double delay) { +#if __APPLE__ + performMethodOnDispatchQueueAfterDelay(method, context, dispatch_get_main_queue(), delay); +#else initDelayedPerform(); struct mainThreadCallData * data; @@ -232,41 +350,25 @@ void Object::performMethodAfterDelay(Method method, void * context, double delay 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); + addToPerformHash(this, method, context, NULL, data); +#endif } void Object::cancelDelayedPerformMethod(Method method, void * context) { +#if __APPLE__ + cancelDelayedPerformMethodOnDispatchQueue(method, context, dispatch_get_main_queue()); +#else initDelayedPerform(); - 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) + struct mainThreadCallData * data = getFromPerformHash(this, method, context, NULL); + if (data == NULL) return; - chash_delete(delayedPerformHash, &key, NULL); - struct mainThreadCallData * data = (struct mainThreadCallData *) value.data; + removeFromPerformHash(this, method, context, NULL); cancelDelayedCall(data->caller); free(data); +#endif } HashMap * Object::serializable() diff --git a/src/core/basetypes/MCObject.h b/src/core/basetypes/MCObject.h index 0f3a769b..e3d74f52 100644 --- a/src/core/basetypes/MCObject.h +++ b/src/core/basetypes/MCObject.h @@ -43,10 +43,12 @@ namespace mailcore { typedef void (Object::*Method) (void *); 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); #if __APPLE__ virtual void performMethodOnDispatchQueue(Method method, void * context, void * targetDispatchQueue, bool waitUntilDone = false); + virtual void performMethodOnDispatchQueueAfterDelay(Method method, void * context, void * targetDispatchQueue, bool delay); + virtual void cancelDelayedPerformMethodOnDispatchQueue(Method method, void * context, void * targetDispatchQueue); #endif - virtual void performMethodAfterDelay(Method method, void * context, double delay); virtual void cancelDelayedPerformMethod(Method method, void * context); // serialization utils -- cgit v1.2.3 From 5b151becd1f950254ab9b7a5effd66210792247a Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 18 Jan 2014 16:28:12 -0800 Subject: Implemented dispatchQueue property on MCOIMAPSession --- src/async/imap/MCIMAPAsyncConnection.cc | 12 ++++++++++++ src/async/imap/MCIMAPAsyncConnection.h | 8 ++++++++ src/async/imap/MCIMAPAsyncSession.cc | 18 +++++++++++++++++- src/async/imap/MCIMAPAsyncSession.h | 11 +++++++++++ src/async/imap/MCIMAPOperation.cc | 6 +++--- src/core/basetypes/MCOperationQueue.cc | 23 +++++++++++++++++++++++ src/core/basetypes/MCOperationQueue.h | 8 ++++++++ src/objc/imap/MCOIMAPSession.h | 6 ++++++ src/objc/imap/MCOIMAPSession.mm | 1 + 9 files changed, 89 insertions(+), 4 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 64f95dfb..5e3dc21b 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -712,3 +712,15 @@ void IMAPAsyncConnection::setQueueRunning(bool running) { mQueueRunning = running; } + +#if __APPLE__ +void IMAPAsyncConnection::setDispatchQueue(dispatch_queue_t dispatchQueue) +{ + mQueue->setDispatchQueue(dispatchQueue); +} + +dispatch_queue_t IMAPAsyncConnection::dispatchQueue() +{ + return mQueue->dispatchQueue(); +} +#endif diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 2c2ee505..a93441d0 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -4,6 +4,9 @@ #include #include +#if __APPLE__ +#include +#endif #ifdef __cplusplus @@ -81,6 +84,11 @@ namespace mailcore { virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); +#ifdef __APPLE__ + virtual void setDispatchQueue(dispatch_queue_t dispatchQueue); + virtual dispatch_queue_t dispatchQueue(); +#endif + virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder); diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 573e7e42..1aa44f1d 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -42,6 +42,9 @@ IMAPAsyncSession::IMAPAsyncSession() mServerIdentity = new IMAPIdentity(); mClientIdentity = new IMAPIdentity(); mOperationQueueCallback = NULL; +#if __APPLE__ + mDispatchQueue = dispatch_get_main_queue(); +#endif } IMAPAsyncSession::~IMAPAsyncSession() @@ -215,6 +218,7 @@ IMAPAsyncConnection * IMAPAsyncSession::session() session->setVoIPEnabled(mVoIPEnabled); session->setDefaultNamespace(mDefaultNamespace); session->setClientIdentity(mClientIdentity); + session->setDispatchQueue(mDispatchQueue); #if 0 // should be implemented properly if (mAutomaticConfigurationDone) { session->setAutomaticConfigurationEnabled(false); @@ -577,4 +581,16 @@ void IMAPAsyncSession::operationRunningStateChanged() mOperationQueueCallback->queueStoppedRunning(); } } -} \ No newline at end of file +} + +#if __APPLE__ +void IMAPAsyncSession::setDispatchQueue(dispatch_queue_t dispatchQueue) +{ + mDispatchQueue = dispatchQueue; +} + +dispatch_queue_t IMAPAsyncSession::dispatchQueue() +{ + return mDispatchQueue; +} +#endif diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 6870d739..53416435 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -12,6 +12,9 @@ #include #include +#if __APPLE__ +#include +#endif #ifdef __cplusplus @@ -89,6 +92,11 @@ namespace mailcore { virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); +#ifdef __APPLE__ + virtual void setDispatchQueue(dispatch_queue_t dispatchQueue); + virtual dispatch_queue_t dispatchQueue(); +#endif + virtual void setOperationQueueCallback(OperationQueueCallback * callback); virtual OperationQueueCallback * operationQueueCallback(); virtual bool isOperationQueueRunning(); @@ -178,6 +186,9 @@ namespace mailcore { IMAPIdentity * mClientIdentity; bool mQueueRunning; OperationQueueCallback * mOperationQueueCallback; +#if __APPLE__ + dispatch_queue_t mDispatchQueue; +#endif virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); virtual IMAPAsyncConnection * session(); diff --git a/src/async/imap/MCIMAPOperation.cc b/src/async/imap/MCIMAPOperation.cc index da3ae6dd..519ba246 100644 --- a/src/async/imap/MCIMAPOperation.cc +++ b/src/async/imap/MCIMAPOperation.cc @@ -9,9 +9,6 @@ #include "MCIMAPOperation.h" #include -#if __APPLE__ -#include -#endif #include "MCIMAPAsyncSession.h" #include "MCIMAPSession.h" @@ -37,6 +34,9 @@ IMAPOperation::~IMAPOperation() void IMAPOperation::setSession(IMAPAsyncConnection * session) { MC_SAFE_REPLACE_RETAIN(IMAPAsyncConnection, mSession, session); +#if __APPLE__ + setCallbackDispatchQueue(session->dispatchQueue()); +#endif } IMAPAsyncConnection * IMAPOperation::session() diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 50b2416c..76a76bc7 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -25,6 +25,9 @@ OperationQueue::OperationQueue() mWaitingFinishedSem = mailsem_new(); mQuitting = false; mCallback = NULL; +#if __APPLE__ + mDispatchQueue = dispatch_get_main_queue(); +#endif } OperationQueue::~OperationQueue() @@ -78,7 +81,11 @@ void OperationQueue::runOperations() mailsem_up(mStopSem); retain(); // (2) +#if __APPLE__ + performMethodOnDispatchQueue((Object::Method) &OperationQueue::stoppedOnMainThread, NULL, mDispatchQueue, true); +#else performMethodOnMainThread((Object::Method) &OperationQueue::stoppedOnMainThread, NULL, true); +#endif pool->release(); break; @@ -107,7 +114,11 @@ void OperationQueue::runOperations() if (needsCheckRunning) { retain(); // (1) MCLog("check running %p", this); +#if __APPLE__ + performMethodOnDispatchQueue((Object::Method) &OperationQueue::checkRunningOnMainThread, this, mDispatchQueue); +#else performMethodOnMainThread((Object::Method) &OperationQueue::checkRunningOnMainThread, this); +#endif } pool->release(); @@ -239,3 +250,15 @@ void OperationQueue::waitUntilAllOperationsAreFinished() mWaiting = false; } #endif + +#if __APPLE__ +void OperationQueue::setDispatchQueue(dispatch_queue_t dispatchQueue) +{ + mDispatchQueue = dispatchQueue; +} + +dispatch_queue_t OperationQueue::dispatchQueue() +{ + return mDispatchQueue; +} +#endif diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index cd61b249..f343c603 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -27,6 +27,11 @@ namespace mailcore { virtual void setCallback(OperationQueueCallback * callback); virtual OperationQueueCallback * callback(); +#ifdef __APPLE__ + virtual void setDispatchQueue(dispatch_queue_t dispatchQueue); + virtual dispatch_queue_t dispatchQueue(); +#endif + private: Array * mOperations; pthread_t mThreadID; @@ -39,6 +44,9 @@ namespace mailcore { struct mailsem * mWaitingFinishedSem; bool mQuitting; OperationQueueCallback * mCallback; +#if __APPLE__ + dispatch_queue_t mDispatchQueue; +#endif void startThread(); static void runOperationsOnThread(OperationQueue * queue); diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index c04621b1..cbe39b50 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -110,6 +110,12 @@ */ @property (nonatomic, copy) MCOConnectionLogger connectionLogger; +/** This property give some hints to MCOIMAPSession about where it's called from. + It will make MCOIMAPSession safe. It will also set all the callbacks of operations to run on this given queue. + Defaults to the main queue. + This property should be used only if there's performance issue using MCOIMAPSession in the main thread. */ +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; + /** The value will be YES when asynchronous operations are running, else it will return NO. */ diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index a53456ae..6e788a36 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -105,6 +105,7 @@ MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) MCO_OBJC_SYNTHESIZE_BOOL(setVoIPEnabled, isVoIPEnabled) MCO_OBJC_SYNTHESIZE_SCALAR(BOOL, BOOL, setAllowsFolderConcurrentAccessEnabled, allowsFolderConcurrentAccessEnabled) MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, maximumConnections) +MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, dispatchQueue); - (void) setDefaultNamespace:(MCOIMAPNamespace *)defaultNamespace { -- cgit v1.2.3 From 19019c91102037413b763381a907ba5fbb3a350b Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sat, 18 Jan 2014 20:29:02 -0800 Subject: Fixed #567: dispatch queue for POP and SMTP --- src/async/imap/MCIMAPAsyncConnection.h | 3 --- src/async/imap/MCIMAPAsyncSession.h | 3 --- src/async/imap/MCIMAPOperation.cc | 9 ++++++++- src/async/pop/MCPOPAsyncSession.cc | 12 ++++++++++++ src/async/pop/MCPOPAsyncSession.h | 5 +++++ src/async/pop/MCPOPOperation.cc | 10 ++++++++++ src/async/smtp/MCSMTPAsyncSession.cc | 12 ++++++++++++ src/async/smtp/MCSMTPAsyncSession.h | 5 +++++ src/async/smtp/MCSMTPOperation.cc | 10 ++++++++++ src/core/basetypes/MCOperation.h | 4 ---- src/objc/imap/MCOIMAPSession.h | 2 +- src/objc/pop/MCOPOPSession.h | 6 ++++++ src/objc/pop/MCOPOPSession.mm | 1 + src/objc/smtp/MCOSMTPSession.h | 6 ++++++ src/objc/smtp/MCOSMTPSession.mm | 1 + 15 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index a93441d0..1f4014da 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -4,9 +4,6 @@ #include #include -#if __APPLE__ -#include -#endif #ifdef __cplusplus diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 53416435..3b1f2ccc 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -12,9 +12,6 @@ #include #include -#if __APPLE__ -#include -#endif #ifdef __cplusplus diff --git a/src/async/imap/MCIMAPOperation.cc b/src/async/imap/MCIMAPOperation.cc index 519ba246..e4b3529b 100644 --- a/src/async/imap/MCIMAPOperation.cc +++ b/src/async/imap/MCIMAPOperation.cc @@ -35,7 +35,14 @@ void IMAPOperation::setSession(IMAPAsyncConnection * session) { MC_SAFE_REPLACE_RETAIN(IMAPAsyncConnection, mSession, session); #if __APPLE__ - setCallbackDispatchQueue(session->dispatchQueue()); + dispatch_queue_t queue; + if (session != NULL) { + queue = session->dispatchQueue(); + } + else { + queue = dispatch_get_main_queue(); + } + setCallbackDispatchQueue(queue); #endif } diff --git a/src/async/pop/MCPOPAsyncSession.cc b/src/async/pop/MCPOPAsyncSession.cc index 07420c0c..2a6bd3b0 100644 --- a/src/async/pop/MCPOPAsyncSession.cc +++ b/src/async/pop/MCPOPAsyncSession.cc @@ -261,3 +261,15 @@ void POPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer) } pthread_mutex_unlock(&mConnectionLoggerLock); } + +#if __APPLE__ +void POPAsyncSession::setDispatchQueue(dispatch_queue_t dispatchQueue) +{ + mQueue->setDispatchQueue(dispatchQueue); +} + +dispatch_queue_t POPAsyncSession::dispatchQueue() +{ + return mQueue->dispatchQueue(); +} +#endif diff --git a/src/async/pop/MCPOPAsyncSession.h b/src/async/pop/MCPOPAsyncSession.h index b863be11..ff8df853 100644 --- a/src/async/pop/MCPOPAsyncSession.h +++ b/src/async/pop/MCPOPAsyncSession.h @@ -57,6 +57,11 @@ namespace mailcore { virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); +#ifdef __APPLE__ + virtual void setDispatchQueue(dispatch_queue_t dispatchQueue); + virtual dispatch_queue_t dispatchQueue(); +#endif + virtual POPFetchMessagesOperation * fetchMessagesOperation(); virtual POPFetchHeaderOperation * fetchHeaderOperation(unsigned int index); diff --git a/src/async/pop/MCPOPOperation.cc b/src/async/pop/MCPOPOperation.cc index 27bfc2ec..479876b6 100644 --- a/src/async/pop/MCPOPOperation.cc +++ b/src/async/pop/MCPOPOperation.cc @@ -31,6 +31,16 @@ POPOperation::~POPOperation() void POPOperation::setSession(POPAsyncSession * session) { MC_SAFE_REPLACE_RETAIN(POPAsyncSession, mSession, session); +#if __APPLE__ + dispatch_queue_t queue; + if (session != NULL) { + queue = session->dispatchQueue(); + } + else { + queue = dispatch_get_main_queue(); + } + setCallbackDispatchQueue(queue); +#endif } POPAsyncSession * POPOperation::session() diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc index e24efc09..1964c944 100644 --- a/src/async/smtp/MCSMTPAsyncSession.cc +++ b/src/async/smtp/MCSMTPAsyncSession.cc @@ -272,3 +272,15 @@ void SMTPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer) } pthread_mutex_unlock(&mConnectionLoggerLock); } + +#if __APPLE__ +void SMTPAsyncSession::setDispatchQueue(dispatch_queue_t dispatchQueue) +{ + mQueue->setDispatchQueue(dispatchQueue); +} + +dispatch_queue_t SMTPAsyncSession::dispatchQueue() +{ + return mQueue->dispatchQueue(); +} +#endif diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h index 63630b77..b3ef4455 100644 --- a/src/async/smtp/MCSMTPAsyncSession.h +++ b/src/async/smtp/MCSMTPAsyncSession.h @@ -54,6 +54,11 @@ namespace mailcore { virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); +#ifdef __APPLE__ + virtual void setDispatchQueue(dispatch_queue_t dispatchQueue); + virtual dispatch_queue_t dispatchQueue(); +#endif + virtual SMTPOperation * sendMessageOperation(Data * messageData); virtual SMTPOperation * sendMessageOperation(Address * from, Array * recipients, Data * messageData); diff --git a/src/async/smtp/MCSMTPOperation.cc b/src/async/smtp/MCSMTPOperation.cc index 0b180c5f..9ddcede2 100644 --- a/src/async/smtp/MCSMTPOperation.cc +++ b/src/async/smtp/MCSMTPOperation.cc @@ -29,6 +29,16 @@ SMTPOperation::~SMTPOperation() void SMTPOperation::setSession(SMTPAsyncSession * session) { MC_SAFE_REPLACE_RETAIN(SMTPAsyncSession, mSession, session); +#if __APPLE__ + dispatch_queue_t queue; + if (session != NULL) { + queue = session->dispatchQueue(); + } + else { + queue = dispatch_get_main_queue(); + } + setCallbackDispatchQueue(queue); +#endif } SMTPAsyncSession * SMTPOperation::session() diff --git a/src/core/basetypes/MCOperation.h b/src/core/basetypes/MCOperation.h index cf4976a9..9e59b11e 100644 --- a/src/core/basetypes/MCOperation.h +++ b/src/core/basetypes/MCOperation.h @@ -5,10 +5,6 @@ #include #include -#if __APPLE__ -#include -#endif - #ifdef __cplusplus namespace mailcore { diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index cbe39b50..abfcc8da 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -110,7 +110,7 @@ */ @property (nonatomic, copy) MCOConnectionLogger connectionLogger; -/** This property give some hints to MCOIMAPSession about where it's called from. +/** This property provides some hints to MCOIMAPSession about where it's called from. It will make MCOIMAPSession safe. It will also set all the callbacks of operations to run on this given queue. Defaults to the main queue. This property should be used only if there's performance issue using MCOIMAPSession in the main thread. */ diff --git a/src/objc/pop/MCOPOPSession.h b/src/objc/pop/MCOPOPSession.h index aa381a62..6941aa13 100644 --- a/src/objc/pop/MCOPOPSession.h +++ b/src/objc/pop/MCOPOPSession.h @@ -62,6 +62,12 @@ See MCOConnectionType for more information.*/ */ @property (nonatomic, copy) MCOConnectionLogger connectionLogger; +/** This property provides some hints to MCOPOPSession about where it's called from. + It will make MCOPOPSession safe. It will also set all the callbacks of operations to run on this given queue. + Defaults to the main queue. + This property should be used only if there's performance issue using MCOPOPSession in the main thread. */ +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; + /** @name Operations */ /** diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm index 1037f951..893995a5 100644 --- a/src/objc/pop/MCOPOPSession.mm +++ b/src/objc/pop/MCOPOPSession.mm @@ -82,6 +82,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOAuthType, mailcore::AuthType, setAuthType, authTyp MCO_OBJC_SYNTHESIZE_SCALAR(MCOConnectionType, mailcore::ConnectionType, setConnectionType, connectionType) MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout) MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) +MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, dispatchQueue); - (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger { diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h index 90351551..09116508 100644 --- a/src/objc/smtp/MCOSMTPSession.h +++ b/src/objc/smtp/MCOSMTPSession.h @@ -76,6 +76,12 @@ */ @property (nonatomic, copy) MCOConnectionLogger connectionLogger; +/** This property provides some hints to MCOSMTPSession about where it's called from. + It will make MCOSMTPSession safe. It will also set all the callbacks of operations to run on this given queue. + Defaults to the main queue. + This property should be used only if there's performance issue using MCOSMTPSession in the main thread. */ +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; + /** @name Operations */ /** diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index 29211118..b6ae6a4f 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -81,6 +81,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOConnectionType, mailcore::ConnectionType, setConne MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout) MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled) +MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, dispatchQueue); - (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger { -- cgit v1.2.3 From a0b960cb74975d8bb71b1ccd9cede4207a7d57e3 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sun, 19 Jan 2014 20:17:01 -0800 Subject: Added more indexSet helpers --- src/core/basetypes/MCIndexSet.cc | 28 ++++++++++++++++++++++++++++ src/core/basetypes/MCIndexSet.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/src/core/basetypes/MCIndexSet.cc b/src/core/basetypes/MCIndexSet.cc index db25f5eb..fe755038 100644 --- a/src/core/basetypes/MCIndexSet.cc +++ b/src/core/basetypes/MCIndexSet.cc @@ -396,6 +396,34 @@ void IndexSet::importSerializable(HashMap * serializable) } } +void IndexSet::addIndexSet(IndexSet * indexSet) +{ + for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + addRange(indexSet->allRanges()[i]); + } +} + +void IndexSet::removeIndexSet(IndexSet * indexSet) +{ + for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + removeRange(indexSet->allRanges()[i]); + } +} + +void IndexSet::intersectsIndexSet(IndexSet * indexSet) +{ + IndexSet * result = new IndexSet(); + for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + IndexSet * rangeIntersect = (IndexSet *) copy(); + rangeIntersect->intersectsRange(indexSet->allRanges()[i]); + result->addIndexSet(rangeIntersect); + rangeIntersect->release(); + } + removeAllIndexes(); + addIndexSet(result); + result->release(); +} + static void * createObject() { return new IndexSet(); diff --git a/src/core/basetypes/MCIndexSet.h b/src/core/basetypes/MCIndexSet.h index b1605b90..57fcd538 100644 --- a/src/core/basetypes/MCIndexSet.h +++ b/src/core/basetypes/MCIndexSet.h @@ -36,6 +36,10 @@ namespace mailcore { virtual void removeRange(Range range); virtual void intersectsRange(Range range); + virtual void addIndexSet(IndexSet * indexSet); + virtual void removeIndexSet(IndexSet * indexSet); + virtual void intersectsIndexSet(IndexSet * indexSet); + virtual Range * allRanges(); virtual unsigned int rangesCount(); virtual void removeAllIndexes(); -- cgit v1.2.3 From 3bd0c195538417acdb062198da84dedc350d13b5 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Sun, 19 Jan 2014 20:30:30 -0800 Subject: ObjC API for indexset helpers --- src/objc/utils/MCOIndexSet.h | 9 +++++++++ src/objc/utils/MCOIndexSet.mm | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/objc/utils/MCOIndexSet.h b/src/objc/utils/MCOIndexSet.h index 2bb2684e..38ec3834 100644 --- a/src/objc/utils/MCOIndexSet.h +++ b/src/objc/utils/MCOIndexSet.h @@ -48,6 +48,15 @@ /** Removes all integers that are not in the given range.*/ - (void) intersectsRange:(MCORange)range; +/** Adds all indexes from an other index set to the index set.*/ +- (void) addIndexSet:(MCOIndexSet *)indexSet; + +/** Remove all indexes from an other index set from the index set.*/ +- (void) removeIndexSet:(MCOIndexSet *)indexSet; + +/** Removes all integers that are not in the given index set.*/ +- (void) intersectsIndexSet:(MCOIndexSet *)indexSet; + /** Returns all the ranges of ths index set.*/ - (MCORange *) allRanges; diff --git a/src/objc/utils/MCOIndexSet.mm b/src/objc/utils/MCOIndexSet.mm index 9d75900f..b944b38b 100644 --- a/src/objc/utils/MCOIndexSet.mm +++ b/src/objc/utils/MCOIndexSet.mm @@ -127,6 +127,21 @@ MCO_SYNTHESIZE_NSCODING _indexSet->intersectsRange(MCORangeToMCRange(range)); } +- (void) addIndexSet:(MCOIndexSet *)indexSet +{ + _indexSet->addIndexSet(indexSet->_indexSet); +} + +- (void) removeIndexSet:(MCOIndexSet *)indexSet +{ + _indexSet->removeIndexSet(indexSet->_indexSet); +} + +- (void) intersectsIndexSet:(MCOIndexSet *)indexSet +{ + _indexSet->intersectsIndexSet(indexSet->_indexSet); +} + - (MCORange *) allRanges { return (MCORange *) _indexSet->allRanges(); -- cgit v1.2.3 From 80654fce9123ec6a585df2860efd132542a87738 Mon Sep 17 00:00:00 2001 From: David Hearst Date: Mon, 20 Jan 2014 14:39:48 -0700 Subject: Make sure that the "size" property is propagated into the object during fetch I noticed that UID and index were being stored in the object based on fetch results, but size was always left as 0. --- src/core/pop/MCPOPSession.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc index 12b0b032..0d26682e 100644 --- a/src/core/pop/MCPOPSession.cc +++ b/src/core/pop/MCPOPSession.cc @@ -439,6 +439,7 @@ Array * POPSession::fetchMessages(ErrorCode * pError) POPMessageInfo * info = new POPMessageInfo(); info->setUid(uid); + info->setSize(msg_info->msg_size); info->setIndex(msg_info->msg_index); result->addObject(info); info->release(); -- cgit v1.2.3 From d6899960904a0713b193855d4f1b81afc3473097 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Tue, 21 Jan 2014 20:56:53 -0800 Subject: Retrieve Gmail user display name --- src/async/imap/MCIMAPAsyncSession.cc | 8 ++++++++ src/async/imap/MCIMAPAsyncSession.h | 2 ++ src/core/abstract/MCMessageConstants.h | 3 +++ src/core/imap/MCIMAPSession.cc | 28 ++++++++++++++++++++++++++++ src/core/imap/MCIMAPSession.h | 6 ++++++ src/objc/abstract/MCOConstants.h | 3 +++ src/objc/imap/MCOIMAPSession.h | 3 +++ src/objc/imap/MCOIMAPSession.mm | 5 +++++ 8 files changed, 58 insertions(+) diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 1aa44f1d..8c3678e1 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -45,10 +45,12 @@ IMAPAsyncSession::IMAPAsyncSession() #if __APPLE__ mDispatchQueue = dispatch_get_main_queue(); #endif + mGmailUserDisplayName = NULL; } IMAPAsyncSession::~IMAPAsyncSession() { + MC_SAFE_RELEASE(mGmailUserDisplayName); MC_SAFE_RELEASE(mServerIdentity); MC_SAFE_RELEASE(mClientIdentity); MC_SAFE_RELEASE(mSessions); @@ -199,6 +201,11 @@ IMAPIdentity * IMAPAsyncSession::clientIdentity() return mClientIdentity; } +String * IMAPAsyncSession::gmailUserDisplayName() +{ + return mGmailUserDisplayName; +} + IMAPAsyncConnection * IMAPAsyncSession::session() { IMAPAsyncConnection * session = new IMAPAsyncConnection(); @@ -540,6 +547,7 @@ IMAPMessageRenderingOperation * IMAPAsyncSession::plainTextBodyRenderingOperatio void IMAPAsyncSession::automaticConfigurationDone(IMAPSession * session) { MC_SAFE_REPLACE_COPY(IMAPIdentity, mServerIdentity, session->serverIdentity()); + MC_SAFE_REPLACE_COPY(String, mGmailUserDisplayName, session->gmailUserDisplayName()); setDefaultNamespace(session->defaultNamespace()); mAutomaticConfigurationDone = true; } diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 3b1f2ccc..24fb6f91 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -100,6 +100,7 @@ namespace mailcore { virtual IMAPIdentity * serverIdentity(); virtual IMAPIdentity * clientIdentity(); + virtual String * gmailUserDisplayName(); virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder); @@ -186,6 +187,7 @@ namespace mailcore { #if __APPLE__ dispatch_queue_t mDispatchQueue; #endif + String * mGmailUserDisplayName; virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); virtual IMAPAsyncConnection * session(); diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index f5d7f259..95bf1201 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -42,6 +42,9 @@ namespace mailcore { IMAPFolderFlagAll = IMAPFolderFlagAllMail, IMAPFolderFlagJunk = IMAPFolderFlagSpam, IMAPFolderFlagFlagged = IMAPFolderFlagStarred, + IMAPFolderFlagFolderTypeMask = IMAPFolderFlagInbox | IMAPFolderFlagSentMail | IMAPFolderFlagStarred | IMAPFolderFlagAllMail | + IMAPFolderFlagTrash| IMAPFolderFlagDrafts | IMAPFolderFlagSpam | IMAPFolderFlagImportant | IMAPFolderFlagArchive; + }; enum MessageFlag { diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 32cd4ebd..50ab4f70 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -320,6 +320,7 @@ void IMAPSession::init() mIdentityEnabled = false; mNamespaceEnabled = false; mCompressionEnabled = false; + mIsGmail = false; mWelcomeString = NULL; mNeedsMboxMailWorkaround = false; mDefaultNamespace = NULL; @@ -344,6 +345,8 @@ void IMAPSession::init() mAutomaticConfigurationEnabled = true; mAutomaticConfigurationDone = false; mShouldDisconnect = false; + mLoginResponse = NULL; + mGmailUserDisplayName = NULL; } IMAPSession::IMAPSession() @@ -353,6 +356,8 @@ IMAPSession::IMAPSession() IMAPSession::~IMAPSession() { + MC_SAFE_RELEASE(mGmailUserDisplayName); + MC_SAFE_RELEASE(mLoginResponse); MC_SAFE_RELEASE(mClientIdentity); MC_SAFE_RELEASE(mServerIdentity); MC_SAFE_RELEASE(mHostname); @@ -819,6 +824,23 @@ void IMAPSession::login(ErrorCode * pError) return; } + String * loginResponse = MCSTR(""); + if (mIsGmail) { + if (mImap->imap_response != NULL) { + loginResponse = String::stringWithUTF8Characters(mImap->imap_response); + + int location = loginResponse->locationOfString(MCSTR(" authenticated (Success)")); + if (location != -1) { + String * emailAndName = loginResponse->substringToIndex(location); + location = emailAndName->locationOfString(MCSTR(" ")); + MC_SAFE_RELEASE(mGmailUserDisplayName); + mGmailUserDisplayName = emailAndName->substringFromIndex(location + 1); + mGmailUserDisplayName->retain(); + } + } + } + MC_SAFE_REPLACE_COPY(String, mLoginResponse, loginResponse); + mState = STATE_LOGGEDIN; if (isAutomaticConfigurationEnabled()) { @@ -3494,6 +3516,7 @@ void IMAPSession::applyCapabilities(IndexSet * capabilities) } if (capabilities->containsIndex(IMAPCapabilityGmail)) { mXListEnabled = false; + mIsGmail = true; } if (capabilities->containsIndex(IMAPCapabilityIdle)) { mIdleEnabled = true; @@ -3726,3 +3749,8 @@ void IMAPSession::resetAutomaticConfigurationDone() { mAutomaticConfigurationDone = false; } + +String * IMAPSession::gmailUserDisplayName() +{ + return mGmailUserDisplayName; +} diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 0cd91fcb..f185483f 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -163,6 +163,8 @@ namespace mailcore { virtual bool isNamespaceEnabled(); virtual bool isCompressionEnabled(); + virtual String * gmailUserDisplayName(); + virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); @@ -219,6 +221,7 @@ namespace mailcore { bool mXOauth2Enabled; bool mNamespaceEnabled; bool mCompressionEnabled; + bool mIsGmail; String * mWelcomeString; bool mNeedsMboxMailWorkaround; uint32_t mUIDValidity; @@ -241,6 +244,9 @@ namespace mailcore { bool mAutomaticConfigurationDone; bool mShouldDisconnect; + String * mLoginResponse; + String * mGmailUserDisplayName; + void init(); void bodyProgress(unsigned int current, unsigned int maximum); void itemsProgress(unsigned int current, unsigned int maximum); diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 17af29eb..534d118d 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -72,6 +72,9 @@ typedef enum { MCOIMAPFolderFlagJunk = MCOIMAPFolderFlagSpam, /** \Flagged: When the folder contains all the flagged emails.*/ MCOIMAPFolderFlagFlagged = MCOIMAPFolderFlagStarred, + /** Mask to identify the folder */ + MCOIMAPFolderFlagFolderTypeMask = MCOIMAPFolderFlagInbox | MCOIMAPFolderFlagSentMail | MCOIMAPFolderFlagStarred | MCOIMAPFolderFlagAllMail | + MCOIMAPFolderFlagTrash| MCOIMAPFolderFlagDrafts | MCOIMAPFolderFlagSpam | MCOIMAPFolderFlagImportant | MCOIMAPFolderFlagArchive, } MCOIMAPFolderFlag; /** It's the flags of a message.*/ diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index abfcc8da..8ddfa8cd 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -89,6 +89,9 @@ /** The identity of the IMAP server. */ @property (nonatomic, strong, readonly) MCOIMAPIdentity * serverIdentity; +/** Display name of the Gmail user. It will be nil if it's not a Gmail server. */ +@property (nonatomic, copy, readonly) NSString * gmailUserDisplayName; + /** When set to YES, the session is allowed open to open several connections to the same folder. @warning Some older IMAP servers don't like this diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index 6e788a36..762e594a 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -127,6 +127,11 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return MCO_OBJC_BRIDGE_GET(serverIdentity); } +- (NSString *) gmailUserDisplayName +{ + return MCO_TO_OBJC(_session->gmailUserDisplayName()); +} + - (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger { [_connectionLogger release]; -- cgit v1.2.3 From 4b4d98fbf824985c7dae63794989e916502862a1 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Tue, 21 Jan 2014 21:17:45 -0800 Subject: Fixed build --- src/core/abstract/MCMessageConstants.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index 95bf1201..1381b5e6 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -43,8 +43,7 @@ namespace mailcore { IMAPFolderFlagJunk = IMAPFolderFlagSpam, IMAPFolderFlagFlagged = IMAPFolderFlagStarred, IMAPFolderFlagFolderTypeMask = IMAPFolderFlagInbox | IMAPFolderFlagSentMail | IMAPFolderFlagStarred | IMAPFolderFlagAllMail | - IMAPFolderFlagTrash| IMAPFolderFlagDrafts | IMAPFolderFlagSpam | IMAPFolderFlagImportant | IMAPFolderFlagArchive; - + IMAPFolderFlagTrash| IMAPFolderFlagDrafts | IMAPFolderFlagSpam | IMAPFolderFlagImportant | IMAPFolderFlagArchive, }; enum MessageFlag { -- cgit v1.2.3 From 1abdb5e16f8275770efc278049ba473612a0d759 Mon Sep 17 00:00:00 2001 From: Michal Kalis Date: Thu, 23 Jan 2014 11:14:38 +0100 Subject: Method returning array of custom flags --- src/core/imap/MCIMAPMessage.cc | 17 +++++++++++++++++ src/core/imap/MCIMAPMessage.h | 4 ++++ src/core/imap/MCIMAPSession.cc | 37 +++++++++++++++++++++++++++++++++++++ src/objc/imap/MCOIMAPMessage.h | 3 +++ src/objc/imap/MCOIMAPMessage.mm | 1 + 5 files changed, 62 insertions(+) diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 59d67654..477113c5 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -17,6 +17,7 @@ void IMAPMessage::init() mUid = 0; mFlags = MessageFlagNone; mOriginalFlags = MessageFlagNone; + mCustomFlags = NULL; mMainPart = NULL; mGmailLabels = NULL; mModSeqValue = 0; @@ -35,6 +36,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other) : AbstractMessage(other) setUid(other->uid()); setFlags(other->flags()); setOriginalFlags(other->originalFlags()); + setCustomFlags(other->customFlags()); setMainPart((AbstractPart *) other->mainPart()->copy()->autorelease()); setGmailLabels(other->gmailLabels()); setGmailThreadID(other->gmailThreadID()); @@ -105,6 +107,16 @@ MessageFlag IMAPMessage::originalFlags() return mOriginalFlags; } +void IMAPMessage::setCustomFlags(Array * customFlags) +{ + MC_SAFE_REPLACE_COPY(Array, mCustomFlags, customFlags); +} + +Array * IMAPMessage::customFlags() +{ + return mCustomFlags; +} + void IMAPMessage::setModSeqValue(uint64_t uid) { mModSeqValue = uid; @@ -226,6 +238,7 @@ HashMap * IMAPMessage::serializable() result->setObjectForKey(MCSTR("size"), String::stringWithUTF8Format("%lu", (long unsigned) uid())); result->setObjectForKey(MCSTR("flags"), String::stringWithUTF8Format("%u", (unsigned) flags())); result->setObjectForKey(MCSTR("originalFlags"), String::stringWithUTF8Format("%u", (unsigned) originalFlags())); + result->setObjectForKey(MCSTR("customFlags"), customFlags()); result->setObjectForKey(MCSTR("mainPart"), mMainPart->serializable()); if (gmailLabels() != NULL) { result->setObjectForKey(MCSTR("gmailLabels"), gmailLabels()); @@ -262,6 +275,10 @@ void IMAPMessage::importSerializable(HashMap * serializable) if (originalFlags != NULL) { setFlags((MessageFlag) originalFlags->unsignedIntValue()); } + String * customFlags = (String *) serializable->objectForKey(MCSTR("customFlags")); + if (customFlags != NULL) { + setCustomFlags((Array *) serializable->objectForKey(MCSTR("customFlags"))); + } setMainPart((AbstractPart *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("mainPart")))); setGmailLabels((Array *) serializable->objectForKey(MCSTR("gmailLabels"))); String * gmailMessageID = (String *) serializable->objectForKey(MCSTR("gmailMessageID")); diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index ebcad889..e072d131 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -32,6 +32,9 @@ namespace mailcore { virtual void setOriginalFlags(MessageFlag flags); virtual MessageFlag originalFlags(); + virtual void setCustomFlags(Array * customFlags); + virtual Array * customFlags(); + virtual uint64_t modSeqValue(); virtual void setModSeqValue(uint64_t uid); @@ -70,6 +73,7 @@ namespace mailcore { MessageFlag mFlags; MessageFlag mOriginalFlags; + Array * /* String */ mCustomFlags; AbstractPart * mMainPart; Array * /* String */ mGmailLabels; uint64_t mGmailMessageID; diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 50ab4f70..78ec80da 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "MCIMAPSearchExpression.h" #include "MCIMAPFolder.h" @@ -156,6 +157,38 @@ static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * return flags; } +static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic) +{ + Array * result; + clistiter * iter; + + if (att_dynamic->att_list == NULL) + return NULL; + + result = Array::array(); + for(iter = clist_begin(att_dynamic->att_list) ;iter != NULL ; iter = clist_next(iter)) { + struct mailimap_flag_fetch * flag_fetch; + struct mailimap_flag * flag; + + flag_fetch = (struct mailimap_flag_fetch *) clist_content(iter); + if (flag_fetch->fl_type != MAILIMAP_FLAG_FETCH_OTHER) { + continue; + } + + flag = flag_fetch->fl_flag; + if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) { + String * customFlag; + std::cout << "Found a custom flag with keyword " << flag->fl_data.fl_keyword; + + customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword); + result->addObject(customFlag); + std::cout << "The custom flag string is " << customFlag; + } + } + + return result; +} + #pragma mark set conversion static Array * arrayFromSet(struct mailimap_set * imap_set) @@ -1898,6 +1931,10 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) msg->setFlags(flags); msg->setOriginalFlags(flags); hasFlags = true; + + Array * customFlags; + customFlags = custom_flags_from_lep_att_dynamic(att_item->att_data.att_dyn); + msg->setCustomFlags(customFlags); } else if (att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { struct mailimap_msg_att_static * att_static; diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index 7f28663e..80583d60 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -43,6 +43,9 @@ /** The contents of the message flags when it was fetched from the server */ @property (nonatomic, assign) MCOMessageFlag originalFlags; +/** Flag keywords of the message, mostly custom flags */ +@property (nonatomic, assign) NSArray * /* NSString */ customFlags; + /** It's the last modification sequence value of the message synced from the server. See RFC4551 */ @property (nonatomic, assign) uint64_t modSeqValue; diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm index 8667b542..f663d8bd 100644 --- a/src/objc/imap/MCOIMAPMessage.mm +++ b/src/objc/imap/MCOIMAPMessage.mm @@ -45,6 +45,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setUid, uid) MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setSize, size) MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setFlags, flags) MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFlags, originalFlags) +MCO_OBJC_SYNTHESIZE_ARRAY(setCustomFlags, customFlags) MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setModSeqValue, modSeqValue) MCO_OBJC_SYNTHESIZE(AbstractPart, setMainPart, mainPart) MCO_OBJC_SYNTHESIZE_ARRAY(setGmailLabels, gmailLabels) -- cgit v1.2.3 From 686187b5d35e912d47a1fee710782396ff626bdc Mon Sep 17 00:00:00 2001 From: Michal Kalis Date: Thu, 23 Jan 2014 15:14:23 +0100 Subject: Method storeFlags supports custom flags --- src/async/imap/MCIMAPAsyncConnection.cc | 3 ++- src/async/imap/MCIMAPAsyncConnection.h | 2 +- src/async/imap/MCIMAPAsyncSession.cc | 4 ++-- src/async/imap/MCIMAPAsyncSession.h | 2 +- src/async/imap/MCIMAPStoreFlagsOperation.cc | 14 ++++++++++++- src/async/imap/MCIMAPStoreFlagsOperation.h | 4 ++++ src/core/imap/MCIMAPMessage.cc | 1 + src/core/imap/MCIMAPSession.cc | 31 ++++++----------------------- src/core/imap/MCIMAPSession.h | 2 +- src/objc/imap/MCOIMAPSession.h | 6 ++++-- src/objc/imap/MCOIMAPSession.mm | 4 +++- 11 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 5e3dc21b..aa94e3ee 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -420,7 +420,7 @@ IMAPFetchContentOperation * IMAPAsyncConnection::fetchMessageAttachmentByUIDOper return op; } -IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) +IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); op->setSession(this); @@ -428,6 +428,7 @@ IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexS op->setUids(uids); op->setKind(kind); op->setFlags(flags); + op->setCustomFlags(customFlags); op->autorelease(); return op; } diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 1f4014da..e380c5e1 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -116,7 +116,7 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 8c3678e1..d6556309 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -418,10 +418,10 @@ IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByUIDOperati return session->fetchMessageAttachmentByUIDOperation(folder, uid, partID, encoding); } -IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) +IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPAsyncConnection * session = sessionForFolder(folder); - return session->storeFlagsOperation(folder, uids, kind, flags); + return session->storeFlagsOperation(folder, uids, kind, flags, customFlags); } IMAPOperation * IMAPAsyncSession::storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels) diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 24fb6f91..38d14e0f 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -132,7 +132,7 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding, bool urgent = false); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.cc b/src/async/imap/MCIMAPStoreFlagsOperation.cc index e0464c8c..e2e2bfe9 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.cc +++ b/src/async/imap/MCIMAPStoreFlagsOperation.cc @@ -18,11 +18,13 @@ IMAPStoreFlagsOperation::IMAPStoreFlagsOperation() mUids = NULL; mKind = IMAPStoreFlagsRequestKindAdd; mFlags = MessageFlagNone; + mCustomFlags = NULL; } IMAPStoreFlagsOperation::~IMAPStoreFlagsOperation() { MC_SAFE_RELEASE(mUids); + MC_SAFE_RELEASE(mCustomFlags); } void IMAPStoreFlagsOperation::setUids(IndexSet * uids) @@ -55,9 +57,19 @@ MessageFlag IMAPStoreFlagsOperation::flags() return mFlags; } +void IMAPStoreFlagsOperation::setCustomFlags(Array * customFlags) +{ + MC_SAFE_REPLACE_RETAIN(Array, mCustomFlags, customFlags); +} + +Array * IMAPStoreFlagsOperation::customFlags() +{ + return mCustomFlags; +} + void IMAPStoreFlagsOperation::main() { ErrorCode error; - session()->session()->storeFlags(folder(), mUids, mKind, mFlags, &error); + session()->session()->storeFlags(folder(), mUids, mKind, mFlags, mCustomFlags, &error); setError(error); } diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.h b/src/async/imap/MCIMAPStoreFlagsOperation.h index 0048283c..d908baf5 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.h +++ b/src/async/imap/MCIMAPStoreFlagsOperation.h @@ -30,6 +30,9 @@ namespace mailcore { virtual void setFlags(MessageFlag flags); virtual MessageFlag flags(); + virtual void setCustomFlags(Array * customFlags); + virtual Array * customFlags(); + public: // subclass behavior virtual void main(); @@ -37,6 +40,7 @@ namespace mailcore { IndexSet * mUids; IMAPStoreFlagsRequestKind mKind; MessageFlag mFlags; + Array * mCustomFlags; }; diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 477113c5..150ddc3e 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -47,6 +47,7 @@ IMAPMessage::~IMAPMessage() { MC_SAFE_RELEASE(mMainPart); MC_SAFE_RELEASE(mGmailLabels); + MC_SAFE_RELEASE(mCustomFlags); } Object * IMAPMessage::copy() diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 78ec80da..54e8aea0 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -3,7 +3,6 @@ #include #include #include -#include #include "MCIMAPSearchExpression.h" #include "MCIMAPFolder.h" @@ -178,11 +177,9 @@ static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic flag = flag_fetch->fl_flag; if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) { String * customFlag; - std::cout << "Found a custom flag with keyword " << flag->fl_data.fl_keyword; customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword); result->addObject(customFlag); - std::cout << "The custom flag string is " << customFlag; } } @@ -3222,7 +3219,7 @@ HashMap * IMAPSession::fetchNamespace(ErrorCode * pError) return result; } -void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError) +void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) { struct mailimap_set * imap_set; struct mailimap_store_att_flags * store_att_flags; @@ -3272,28 +3269,12 @@ void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsReq f = mailimap_flag_new_draft(); mailimap_flag_list_add(flag_list, f); } - if ((flags & MessageFlagMDNSent) != 0) { - struct mailimap_flag * f; - - f = mailimap_flag_new_flag_keyword(strdup("$MDNSent")); - mailimap_flag_list_add(flag_list, f); - } - if ((flags & MessageFlagForwarded) != 0) { - struct mailimap_flag * f; - - f = mailimap_flag_new_flag_keyword(strdup("$Forwarded")); - mailimap_flag_list_add(flag_list, f); - } - if ((flags & MessageFlagSubmitPending) != 0) { - struct mailimap_flag * f; - - f = mailimap_flag_new_flag_keyword(strdup("$SubmitPending")); - mailimap_flag_list_add(flag_list, f); - } - if ((flags & MessageFlagSubmitted) != 0) { + + for (unsigned int i = 0 ; i < customFlags->count() ; i ++) { struct mailimap_flag * f; - - f = mailimap_flag_new_flag_keyword(strdup("$Submitted")); + String * customFlag = (String *) customFlags->objectAtIndex(i); + + f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters())); mailimap_flag_list_add(flag_list, f); } diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index f185483f..7a7c2ef0 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -121,7 +121,7 @@ namespace mailcore { IMAPProgressCallback * progressCallback, Array * extraHeaders, ErrorCode * pError); - virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); + virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, 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); diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 8ddfa8cd..5e27fba8 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -293,7 +293,8 @@ MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" uids:[MCOIndexSet indexSetWithIndex:456] kind:MCOIMAPStoreFlagsRequestKindAdd - flags:MCOMessageFlagSeen]; + flags:MCOMessageFlagSeen] + customFlags:@["$Forwarded"]; [op start:^(NSError * error) { ... }]; @@ -301,7 +302,8 @@ - (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind - flags:(MCOMessageFlag)flags; + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags; /** Returns an operation to change labels of messages. Intended for Gmail diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index 762e594a..94f86139 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -339,11 +339,13 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags { IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsOperation([folder mco_mcString], MCO_FROM_OBJC(IndexSet, uids), (IMAPStoreFlagsRequestKind) kind, - (MessageFlag) flags); + (MessageFlag) flags, + MCO_FROM_OBJC(Array, customFlags)); return OPAQUE_OPERATION(coreOp); } -- cgit v1.2.3 From f423bc80f79be265d30c18cfd5b68a05c5d5878d Mon Sep 17 00:00:00 2001 From: Michal Kalis Date: Fri, 24 Jan 2014 09:52:30 +0100 Subject: Method to store cusotm flags is separate from the original one --- src/async/imap/MCIMAPAsyncConnection.cc | 14 +++++++++++++- src/async/imap/MCIMAPAsyncConnection.h | 3 ++- src/async/imap/MCIMAPAsyncSession.cc | 10 ++++++++-- src/async/imap/MCIMAPAsyncSession.h | 3 ++- src/objc/imap/MCOIMAPSession.h | 21 +++++++++++++++++++-- src/objc/imap/MCOIMAPSession.mm | 14 +++++++++++++- 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index aa94e3ee..30d2f9be 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -420,7 +420,19 @@ IMAPFetchContentOperation * IMAPAsyncConnection::fetchMessageAttachmentByUIDOper return op; } -IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) +{ + IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); + op->setSession(this); + op->setFolder(folder); + op->setUids(uids); + op->setKind(kind); + op->setFlags(flags); + op->autorelease(); + return op; +} + +IMAPOperation * IMAPAsyncConnection::storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); op->setSession(this); diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index e380c5e1..c2734aff 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -116,7 +116,8 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); + virtual IMAPOperation * storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index d6556309..9cb7992a 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -418,10 +418,16 @@ IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByUIDOperati return session->fetchMessageAttachmentByUIDOperation(folder, uid, partID, encoding); } -IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) { IMAPAsyncConnection * session = sessionForFolder(folder); - return session->storeFlagsOperation(folder, uids, kind, flags, customFlags); + return session->storeFlagsOperation(folder, uids, kind, flags); +} + +IMAPOperation * IMAPAsyncSession::storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +{ + IMAPAsyncConnection * session = sessionForFolder(folder); + return session->storeAllFlagsOperation(folder, uids, kind, flags, customFlags); } IMAPOperation * IMAPAsyncSession::storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels) diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 38d14e0f..f81e6306 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -132,7 +132,8 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding, bool urgent = false); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); + virtual IMAPOperation * storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 5e27fba8..deacfe3d 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -293,8 +293,7 @@ MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" uids:[MCOIndexSet indexSetWithIndex:456] kind:MCOIMAPStoreFlagsRequestKindAdd - flags:MCOMessageFlagSeen] - customFlags:@["$Forwarded"]; + flags:MCOMessageFlagSeen]; [op start:^(NSError * error) { ... }]; @@ -302,6 +301,24 @@ - (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags; +/** + Returns an operation to change flags of messages. + + For example: Adds the seen flag to the message with UID 456. + + MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" + uids:[MCOIndexSet indexSetWithIndex:456] + kind:MCOIMAPStoreFlagsRequestKindAdd + flags:MCOMessageFlagSeen + customFlags:@["$Forwarded"]]; + [op start:^(NSError * error) { + ... + }]; + */ +- (MCOIMAPOperation *) storeAllFlagsOperationWithFolder:(NSString *)folder + uids:(MCOIndexSet *)uids + kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags customFlags:(NSArray *)customFlags; /** diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index 94f86139..f489acd7 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -339,9 +339,21 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags - customFlags:(NSArray *)customFlags { IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsOperation([folder mco_mcString], + MCO_FROM_OBJC(IndexSet, uids), + (IMAPStoreFlagsRequestKind) kind, + (MessageFlag) flags); + return OPAQUE_OPERATION(coreOp); +} + +- (MCOIMAPOperation *) storeAllFlagsOperationWithFolder:(NSString *)folder + uids:(MCOIndexSet *)uids + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags +{ + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeAllFlagsOperation([folder mco_mcString], MCO_FROM_OBJC(IndexSet, uids), (IMAPStoreFlagsRequestKind) kind, (MessageFlag) flags, -- cgit v1.2.3 From e9706ce0a2a405481e3968c06a9f10765d333071 Mon Sep 17 00:00:00 2001 From: Michal Kalis Date: Sun, 26 Jan 2014 18:08:28 +0100 Subject: Fixes in storing custom flags; possible to append new messages with custom flags --- src/async/imap/MCIMAPAppendMessageOperation.cc | 14 ++++- src/async/imap/MCIMAPAppendMessageOperation.h | 4 ++ src/async/imap/MCIMAPAsyncConnection.cc | 17 +----- src/async/imap/MCIMAPAsyncConnection.h | 5 +- src/async/imap/MCIMAPAsyncSession.cc | 14 ++--- src/async/imap/MCIMAPAsyncSession.h | 5 +- src/async/imap/MCIMAPStoreFlagsOperation.cc | 2 +- src/async/imap/MCIMAPStoreFlagsOperation.h | 1 - src/core/imap/MCIMAPMessage.cc | 4 +- src/core/imap/MCIMAPSession.cc | 79 ++++++++++++++++++++------ src/core/imap/MCIMAPSession.h | 7 ++- src/objc/imap/MCOIMAPMessage.h | 2 +- src/objc/imap/MCOIMAPSession.h | 23 ++++++-- src/objc/imap/MCOIMAPSession.mm | 21 ++++--- 14 files changed, 133 insertions(+), 65 deletions(-) diff --git a/src/async/imap/MCIMAPAppendMessageOperation.cc b/src/async/imap/MCIMAPAppendMessageOperation.cc index 0a205a2d..06a42b2d 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.cc +++ b/src/async/imap/MCIMAPAppendMessageOperation.cc @@ -17,12 +17,14 @@ IMAPAppendMessageOperation::IMAPAppendMessageOperation() { mMessageData = NULL; mFlags = MessageFlagNone; + mCustomFlags = NULL; mCreatedUID = 0; } IMAPAppendMessageOperation::~IMAPAppendMessageOperation() { MC_SAFE_RELEASE(mMessageData); + MC_SAFE_RELEASE(mCustomFlags); } void IMAPAppendMessageOperation::setMessageData(Data * messageData) @@ -45,6 +47,16 @@ MessageFlag IMAPAppendMessageOperation::flags() return mFlags; } +void IMAPAppendMessageOperation::setCustomFlags(Array * customFlags) +{ + MC_SAFE_REPLACE_COPY(Array, mCustomFlags, customFlags); +} + +Array * IMAPAppendMessageOperation::customFlags() +{ + return customFlags(); +} + uint32_t IMAPAppendMessageOperation::createdUID() { return mCreatedUID; @@ -53,7 +65,7 @@ uint32_t IMAPAppendMessageOperation::createdUID() void IMAPAppendMessageOperation::main() { ErrorCode error; - session()->session()->appendMessage(folder(), mMessageData, mFlags, this, &mCreatedUID, &error); + session()->session()->appendMessageWithCustomFlags(folder(), mMessageData, mFlags, mCustomFlags, this, &mCreatedUID, &error); setError(error); } diff --git a/src/async/imap/MCIMAPAppendMessageOperation.h b/src/async/imap/MCIMAPAppendMessageOperation.h index 4f210ac8..de6960de 100644 --- a/src/async/imap/MCIMAPAppendMessageOperation.h +++ b/src/async/imap/MCIMAPAppendMessageOperation.h @@ -28,6 +28,9 @@ namespace mailcore { virtual void setFlags(MessageFlag flags); virtual MessageFlag flags(); + virtual void setCustomFlags(Array * customFlags); + virtual Array * customFlags(); + virtual uint32_t createdUID(); public: // subclass behavior @@ -36,6 +39,7 @@ namespace mailcore { private: Data * mMessageData; MessageFlag mFlags; + Array * mCustomFlags; uint32_t mCreatedUID; }; diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 30d2f9be..738da0d1 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -327,13 +327,14 @@ IMAPOperation * IMAPAsyncConnection::unsubscribeFolderOperation(String * folder) return op; } -IMAPAppendMessageOperation * IMAPAsyncConnection::appendMessageOperation(String * folder, Data * messageData, MessageFlag flags) +IMAPAppendMessageOperation * IMAPAsyncConnection::appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags) { IMAPAppendMessageOperation * op = new IMAPAppendMessageOperation(); op->setSession(this); op->setFolder(folder); op->setMessageData(messageData); op->setFlags(flags); + op->setCustomFlags(customFlags); op->autorelease(); return op; } @@ -420,19 +421,7 @@ IMAPFetchContentOperation * IMAPAsyncConnection::fetchMessageAttachmentByUIDOper return op; } -IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) -{ - IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); - op->setSession(this); - op->setFolder(folder); - op->setUids(uids); - op->setKind(kind); - op->setFlags(flags); - op->autorelease(); - return op; -} - -IMAPOperation * IMAPAsyncConnection::storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); op->setSession(this); diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index c2734aff..0a117bea 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -99,7 +99,7 @@ namespace mailcore { virtual IMAPOperation * subscribeFolderOperation(String * folder); virtual IMAPOperation * unsubscribeFolderOperation(String * folder); - virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags); + virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags); virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); @@ -116,8 +116,7 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); - virtual IMAPOperation * storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 9cb7992a..44f753c9 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -366,10 +366,10 @@ IMAPOperation * IMAPAsyncSession::unsubscribeFolderOperation(String * folder) return session->unsubscribeFolderOperation(folder); } -IMAPAppendMessageOperation * IMAPAsyncSession::appendMessageOperation(String * folder, Data * messageData, MessageFlag flags) +IMAPAppendMessageOperation * IMAPAsyncSession::appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags) { IMAPAsyncConnection * session = sessionForFolder(folder); - return session->appendMessageOperation(folder, messageData, flags); + return session->appendMessageOperation(folder, messageData, flags, customFlags); } IMAPCopyMessagesOperation * IMAPAsyncSession::copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder) @@ -418,16 +418,10 @@ IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByUIDOperati return session->fetchMessageAttachmentByUIDOperation(folder, uid, partID, encoding); } -IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags) +IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPAsyncConnection * session = sessionForFolder(folder); - return session->storeFlagsOperation(folder, uids, kind, flags); -} - -IMAPOperation * IMAPAsyncSession::storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) -{ - IMAPAsyncConnection * session = sessionForFolder(folder); - return session->storeAllFlagsOperation(folder, uids, kind, flags, customFlags); + return session->storeFlagsOperation(folder, uids, kind, flags, customFlags); } IMAPOperation * IMAPAsyncSession::storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels) diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index f81e6306..bd06d6a3 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -115,7 +115,7 @@ namespace mailcore { virtual IMAPOperation * subscribeFolderOperation(String * folder); virtual IMAPOperation * unsubscribeFolderOperation(String * folder); - virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags); + virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags); virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); @@ -132,8 +132,7 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding, bool urgent = false); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags); - virtual IMAPOperation * storeAllFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.cc b/src/async/imap/MCIMAPStoreFlagsOperation.cc index e2e2bfe9..df68529a 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.cc +++ b/src/async/imap/MCIMAPStoreFlagsOperation.cc @@ -70,6 +70,6 @@ Array * IMAPStoreFlagsOperation::customFlags() void IMAPStoreFlagsOperation::main() { ErrorCode error; - session()->session()->storeFlags(folder(), mUids, mKind, mFlags, mCustomFlags, &error); + session()->session()->storeFlagsAndCustomFlags(folder(), mUids, mKind, mFlags, mCustomFlags, &error); setError(error); } diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.h b/src/async/imap/MCIMAPStoreFlagsOperation.h index d908baf5..c1b17db5 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.h +++ b/src/async/imap/MCIMAPStoreFlagsOperation.h @@ -41,7 +41,6 @@ namespace mailcore { IMAPStoreFlagsRequestKind mKind; MessageFlag mFlags; Array * mCustomFlags; - }; } diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 150ddc3e..6845d19a 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -239,7 +239,9 @@ HashMap * IMAPMessage::serializable() result->setObjectForKey(MCSTR("size"), String::stringWithUTF8Format("%lu", (long unsigned) uid())); result->setObjectForKey(MCSTR("flags"), String::stringWithUTF8Format("%u", (unsigned) flags())); result->setObjectForKey(MCSTR("originalFlags"), String::stringWithUTF8Format("%u", (unsigned) originalFlags())); - result->setObjectForKey(MCSTR("customFlags"), customFlags()); + if (customFlags() != NULL) { + result->setObjectForKey(MCSTR("customFlags"), customFlags()); + } result->setObjectForKey(MCSTR("mainPart"), mMainPart->serializable()); if (gmailLabels() != NULL) { result->setObjectForKey(MCSTR("gmailLabels"), gmailLabels()); diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 54e8aea0..58d7ba1d 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -133,12 +133,12 @@ static MessageFlag flag_from_lep(struct mailimap_flag * flag) static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic) { - MessageFlag flags; - clistiter * iter; - if (att_dynamic->att_list == NULL) return MessageFlagNone; + MessageFlag flags; + clistiter * iter; + flags = MessageFlagNone; for(iter = clist_begin(att_dynamic->att_list) ;iter != NULL ; iter = clist_next(iter)) { struct mailimap_flag_fetch * flag_fetch; @@ -158,14 +158,14 @@ static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic) { - Array * result; - clistiter * iter; - if (att_dynamic->att_list == NULL) return NULL; + Array * result; + clistiter * iter; + result = Array::array(); - for(iter = clist_begin(att_dynamic->att_list) ;iter != NULL ; iter = clist_next(iter)) { + for (iter = clist_begin(att_dynamic->att_list); iter != NULL; iter = clist_next(iter)) { struct mailimap_flag_fetch * flag_fetch; struct mailimap_flag * flag; @@ -176,10 +176,11 @@ static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic flag = flag_fetch->fl_flag; if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) { - String * customFlag; - - customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword); - result->addObject(customFlag); + if (strcmp(flag->fl_data.fl_keyword, "$MDNSent") != 0 && strcmp(flag->fl_data.fl_keyword, "$Forwarded") != 0 && strcmp(flag->fl_data.fl_keyword, "$SubmitPending") != 0 && strcmp(flag->fl_data.fl_keyword, "$Submitted") != 0) { + String * customFlag; + customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword); + result->addObject(customFlag); + } } } @@ -1551,6 +1552,12 @@ void IMAPSession::unsubscribeFolder(String * folder, ErrorCode * pError) void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag flags, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError) +{ + this->appendMessageWithCustomFlags(folder, messageData, flags, NULL, progressCallback, createdUID, pError); +} + +void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError) { int r; struct mailimap_flag_list * flag_list; @@ -1566,6 +1573,15 @@ void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag flag_list = NULL; flag_list = flags_to_lep(flags); + if (customFlags != NULL) { + for (unsigned int i = 0 ; i < customFlags->count() ; i ++) { + struct mailimap_flag * f; + String * customFlag = (String *) customFlags->objectAtIndex(i); + + f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters())); + mailimap_flag_list_add(flag_list, f); + } + } r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, NULL, messageData->bytes(), messageData->length(), &uidvalidity, &uidresult); mailimap_flag_list_free(flag_list); @@ -3219,7 +3235,12 @@ HashMap * IMAPSession::fetchNamespace(ErrorCode * pError) return result; } -void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) +void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError) +{ + this->storeFlagsAndCustomFlags(folder, uids, kind, flags, NULL, pError); +} + +void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) { struct mailimap_set * imap_set; struct mailimap_store_att_flags * store_att_flags; @@ -3269,14 +3290,40 @@ void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsReq f = mailimap_flag_new_draft(); mailimap_flag_list_add(flag_list, f); } - - for (unsigned int i = 0 ; i < customFlags->count() ; i ++) { + if ((flags & MessageFlagMDNSent) != 0) { + struct mailimap_flag * f; + + f = mailimap_flag_new_flag_keyword(strdup("$MDNSent")); + mailimap_flag_list_add(flag_list, f); + } + if ((flags & MessageFlagForwarded) != 0) { + struct mailimap_flag * f; + + f = mailimap_flag_new_flag_keyword(strdup("$Forwarded")); + mailimap_flag_list_add(flag_list, f); + } + if ((flags & MessageFlagSubmitPending) != 0) { + struct mailimap_flag * f; + + f = mailimap_flag_new_flag_keyword(strdup("$SubmitPending")); + mailimap_flag_list_add(flag_list, f); + } + if ((flags & MessageFlagSubmitted) != 0) { struct mailimap_flag * f; - String * customFlag = (String *) customFlags->objectAtIndex(i); - f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters())); + f = mailimap_flag_new_flag_keyword(strdup("$Submitted")); mailimap_flag_list_add(flag_list, f); } + + if (customFlags != NULL) { + for (unsigned int i = 0 ; i < customFlags->count() ; i ++) { + struct mailimap_flag * f; + String * customFlag = (String *) customFlags->objectAtIndex(i); + + f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters())); + mailimap_flag_list_add(flag_list, f); + } + } store_att_flags = NULL; for(clistiter * iter = clist_begin(setList) ; iter != NULL ; iter = clist_next(iter)) { diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 7a7c2ef0..39e1768f 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -81,6 +81,8 @@ namespace mailcore { virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags, IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); + virtual void appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, + IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError); void copyMessages(String * folder, IndexSet * uidSet, String * destFolder, HashMap ** pUidMapping, ErrorCode * pError); @@ -120,8 +122,9 @@ namespace mailcore { IndexSet * uids, uint64_t modseq, IMAPProgressCallback * progressCallback, Array * extraHeaders, ErrorCode * pError); - - virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError); + + virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); + virtual void storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, 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); diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index 80583d60..bcee7eaf 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -44,7 +44,7 @@ @property (nonatomic, assign) MCOMessageFlag originalFlags; /** Flag keywords of the message, mostly custom flags */ -@property (nonatomic, assign) NSArray * /* NSString */ customFlags; +@property (nonatomic, copy) NSArray * /* NSString */ customFlags; /** It's the last modification sequence value of the message synced from the server. See RFC4551 */ @property (nonatomic, assign) uint64_t modSeqValue; diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index deacfe3d..b013c9c0 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -271,6 +271,21 @@ messageData:(NSData *)messageData flags:(MCOMessageFlag)flags; +/** + Returns an operation to add a message with custom flags to a folder. + + MCOIMAPOperation * op = [session appendMessageOperationWithFolder:@"Sent Mail" messageData:rfc822Data flags:MCOMessageFlagNone customFlags:@[@"$CNS-Greeting-On"]]; + [op start:^(NSError * error, uint32_t createdUID) { + if (error == nil) { + NSLog(@"created message with UID %lu", (unsigned long) createdUID); + } + }]; + */ +- (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder + messageData:(NSData *)messageData + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags; + /** Returns an operation to copy messages to a folder. @@ -303,20 +318,20 @@ kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags; /** - Returns an operation to change flags of messages. + Returns an operation to change flags and custom flags of messages. - For example: Adds the seen flag to the message with UID 456. + For example: Adds the seen flag and $CNS-Greeting-On flag to the message with UID 456. MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" uids:[MCOIndexSet indexSetWithIndex:456] kind:MCOIMAPStoreFlagsRequestKindAdd flags:MCOMessageFlagSeen - customFlags:@["$Forwarded"]]; + customFlags:@["$CNS-Greeting-On"]]; [op start:^(NSError * error) { ... }]; */ -- (MCOIMAPOperation *) storeAllFlagsOperationWithFolder:(NSString *)folder +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index f489acd7..0b0c638a 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -243,10 +243,19 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, - (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder messageData:(NSData *)messageData flags:(MCOMessageFlag)flags +{ + return [self appendMessageOperationWithFolder:folder messageData:messageData flags:flags customFlags:NULL]; +} + +- (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder + messageData:(NSData *)messageData + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags { IMAPAppendMessageOperation * coreOp = MCO_NATIVE_INSTANCE->appendMessageOperation([folder mco_mcString], [messageData mco_mcData], - (MessageFlag) flags); + (MessageFlag) flags, + MCO_FROM_OBJC(Array, customFlags)); return MCO_TO_OBJC_OP(coreOp); } @@ -340,20 +349,16 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags { - IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsOperation([folder mco_mcString], - MCO_FROM_OBJC(IndexSet, uids), - (IMAPStoreFlagsRequestKind) kind, - (MessageFlag) flags); - return OPAQUE_OPERATION(coreOp); + return [self storeFlagsOperationWithFolder:folder uids:uids kind:kind flags:flags customFlags:NULL]; } -- (MCOIMAPOperation *) storeAllFlagsOperationWithFolder:(NSString *)folder +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags customFlags:(NSArray *)customFlags { - IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeAllFlagsOperation([folder mco_mcString], + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsOperation([folder mco_mcString], MCO_FROM_OBJC(IndexSet, uids), (IMAPStoreFlagsRequestKind) kind, (MessageFlag) flags, -- cgit v1.2.3 From 48d88f93aadd01a8fa32870b0d51090b7cd473ba Mon Sep 17 00:00:00 2001 From: Michal Kalis Date: Mon, 27 Jan 2014 20:46:03 +0100 Subject: Default NULL value for custom flags in append and storeFlags function arguments for backwards compatibility --- src/async/imap/MCIMAPAsyncSession.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index bd06d6a3..0d172bb6 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -115,7 +115,7 @@ namespace mailcore { virtual IMAPOperation * subscribeFolderOperation(String * folder); virtual IMAPOperation * unsubscribeFolderOperation(String * folder); - virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags); + virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags, Array * customFlags = NULL); virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); @@ -132,7 +132,7 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding, bool urgent = false); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags); + virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); -- cgit v1.2.3 From e04fb35b3818bfef239d4d0858652d8f49038173 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Mon, 27 Jan 2014 12:12:46 -0800 Subject: optimized custom flags --- src/core/imap/MCIMAPSession.cc | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 58d7ba1d..02e569dc 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -156,15 +156,19 @@ static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * return flags; } +static bool isKnownCustomFlag(const char * keyword) +{ + return !(strcmp(keyword, "$MDNSent") != 0 && strcmp(keyword, "$Forwarded") != 0 && strcmp(keyword, "$SubmitPending") != 0 && strcmp(keyword, "$Submitted") != 0); +} + static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic) { if (att_dynamic->att_list == NULL) return NULL; - Array * result; clistiter * iter; + bool hasCustomFlags = false; - result = Array::array(); for (iter = clist_begin(att_dynamic->att_list); iter != NULL; iter = clist_next(iter)) { struct mailimap_flag_fetch * flag_fetch; struct mailimap_flag * flag; @@ -176,7 +180,28 @@ static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic flag = flag_fetch->fl_flag; if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) { - if (strcmp(flag->fl_data.fl_keyword, "$MDNSent") != 0 && strcmp(flag->fl_data.fl_keyword, "$Forwarded") != 0 && strcmp(flag->fl_data.fl_keyword, "$SubmitPending") != 0 && strcmp(flag->fl_data.fl_keyword, "$Submitted") != 0) { + if (!isKnownCustomFlag(flag->fl_data.fl_keyword)) { + hasCustomFlags = true; + } + } + } + + if (!hasCustomFlags) + return NULL; + + Array * result = Array::array(); + for (iter = clist_begin(att_dynamic->att_list); iter != NULL; iter = clist_next(iter)) { + struct mailimap_flag_fetch * flag_fetch; + struct mailimap_flag * flag; + + flag_fetch = (struct mailimap_flag_fetch *) clist_content(iter); + if (flag_fetch->fl_type != MAILIMAP_FLAG_FETCH_OTHER) { + continue; + } + + flag = flag_fetch->fl_flag; + if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) { + if (!isKnownCustomFlag(flag->fl_data.fl_keyword)) { String * customFlag; customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword); result->addObject(customFlag); -- cgit v1.2.3 From 171be511175ad45073ce9656857c77bc4d05d7e0 Mon Sep 17 00:00:00 2001 From: lgarbo Date: Thu, 30 Jan 2014 11:27:25 +0100 Subject: Update MCOIMAPNamespace.mm --- src/objc/imap/MCOIMAPNamespace.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objc/imap/MCOIMAPNamespace.mm b/src/objc/imap/MCOIMAPNamespace.mm index 4615fc80..2489b06e 100644 --- a/src/objc/imap/MCOIMAPNamespace.mm +++ b/src/objc/imap/MCOIMAPNamespace.mm @@ -89,7 +89,7 @@ - (NSArray *) prefixes { - return MCO_OBJC_BRIDGE_GET(mainPrefix); + return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->prefixes()); } - (NSString *) pathForComponents:(NSArray *)components -- cgit v1.2.3 From 29e5daef6d0ba242c992b989eb7b608bd1b6a323 Mon Sep 17 00:00:00 2001 From: lgarbo Date: Thu, 30 Jan 2014 18:46:07 +0100 Subject: Update MCOIMAPNamespace.mm --- src/objc/imap/MCOIMAPNamespace.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objc/imap/MCOIMAPNamespace.mm b/src/objc/imap/MCOIMAPNamespace.mm index 2489b06e..e6181d87 100644 --- a/src/objc/imap/MCOIMAPNamespace.mm +++ b/src/objc/imap/MCOIMAPNamespace.mm @@ -89,7 +89,7 @@ - (NSArray *) prefixes { - return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->prefixes()); + return MCO_OBJC_BRIDGE_GET(prefixes); } - (NSString *) pathForComponents:(NSArray *)components -- cgit v1.2.3 From feb34ca2dee213eb430309ad2a770631f4fb4631 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Thu, 30 Jan 2014 23:37:30 -0800 Subject: Fixed base64 encoding --- src/core/basetypes/MCBase64.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/core/basetypes/MCBase64.c b/src/core/basetypes/MCBase64.c index 5ebe5bc9..d244805e 100644 --- a/src/core/basetypes/MCBase64.c +++ b/src/core/basetypes/MCBase64.c @@ -31,6 +31,7 @@ char * MCEncodeBase64(const char * in, int len) char * output, * tmp; unsigned char oval; int out_len; + const unsigned char * uin = (const unsigned char *) in; out_len = ((len + 2) / 3 * 4) + 1; @@ -43,19 +44,19 @@ char * MCEncodeBase64(const char * in, int len) tmp = output; while (len >= 3) { - *tmp++ = basis_64[in[0] >> 2]; - *tmp++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; - *tmp++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; - *tmp++ = basis_64[in[2] & 0x3f]; - in += 3; + *tmp++ = basis_64[uin[0] >> 2]; + *tmp++ = basis_64[((uin[0] << 4) & 0x30) | (uin[1] >> 4)]; + *tmp++ = basis_64[((uin[1] << 2) & 0x3c) | (uin[2] >> 6)]; + *tmp++ = basis_64[uin[2] & 0x3f]; + uin += 3; len -= 3; } if (len > 0) { - *tmp++ = basis_64[in[0] >> 2]; - oval = (in[0] << 4) & 0x30; - if (len > 1) oval |= in[1] >> 4; + *tmp++ = basis_64[uin[0] >> 2]; + oval = (uin[0] << 4) & 0x30; + if (len > 1) oval |= uin[1] >> 4; *tmp++ = basis_64[oval]; - *tmp++ = (len < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c]; + *tmp++ = (len < 2) ? '=' : basis_64[(uin[1] << 2) & 0x3c]; *tmp++ = '='; } -- cgit v1.2.3 From 0f09edb01731f9ed0a9c5b6946e261322ad808fe Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Thu, 30 Jan 2014 23:37:54 -0800 Subject: Added Set to Obj-C bridging --- build-mac/mailcore2.xcodeproj/project.pbxproj | 8 +++++ src/objc/utils/NSObject+MCO.mm | 7 +++++ src/objc/utils/NSSet+MCO.h | 25 +++++++++++++++ src/objc/utils/NSSet+MCO.mm | 45 +++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 src/objc/utils/NSSet+MCO.h create mode 100644 src/objc/utils/NSSet+MCO.mm diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index b75a25b0..0db54b8b 100755 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -124,6 +124,8 @@ C63D316317C92D8300A4D993 /* MCOIMAPIdentity.mm in Sources */ = {isa = PBXBuildFile; fileRef = C63D316117C92D8300A4D993 /* MCOIMAPIdentity.mm */; }; C63D316617C997B400A4D993 /* MCOIMAPIdentity.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C63D316017C92D8300A4D993 /* MCOIMAPIdentity.h */; }; C63D316717C997BA00A4D993 /* MCOIMAPIdentity.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C63D316017C92D8300A4D993 /* MCOIMAPIdentity.h */; }; + C643F492189A3D59007EA2F7 /* NSSet+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C643F491189A3D59007EA2F7 /* NSSet+MCO.mm */; }; + C643F493189A3D59007EA2F7 /* NSSet+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C643F491189A3D59007EA2F7 /* NSSet+MCO.mm */; }; C64BB22116E34DCB000DB34C /* MCIMAPSyncResult.cc in Sources */ = {isa = PBXBuildFile; fileRef = C64BB21F16E34DCA000DB34C /* MCIMAPSyncResult.cc */; }; C64BB22B16E5C0A4000DB34C /* MCIMAPCapabilityOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C64BB22916E5C0A3000DB34C /* MCIMAPCapabilityOperation.cc */; }; C64BB22E16E5C1EE000DB34C /* MCIndexSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = C64BB22C16E5C1EE000DB34C /* MCIndexSet.cc */; }; @@ -1250,6 +1252,8 @@ C63D315B17C9155C00A4D993 /* MCIMAPIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPIdentity.h; sourceTree = ""; }; C63D316017C92D8300A4D993 /* MCOIMAPIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPIdentity.h; sourceTree = ""; }; C63D316117C92D8300A4D993 /* MCOIMAPIdentity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPIdentity.mm; sourceTree = ""; }; + C643F490189A3D59007EA2F7 /* NSSet+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSSet+MCO.h"; sourceTree = ""; }; + C643F491189A3D59007EA2F7 /* NSSet+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSSet+MCO.mm"; sourceTree = ""; }; C64BB21F16E34DCA000DB34C /* MCIMAPSyncResult.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPSyncResult.cc; sourceTree = ""; }; C64BB22016E34DCB000DB34C /* MCIMAPSyncResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPSyncResult.h; sourceTree = ""; }; C64BB22916E5C0A3000DB34C /* MCIMAPCapabilityOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPCapabilityOperation.cc; sourceTree = ""; }; @@ -2195,6 +2199,8 @@ C6CCC5C816FFE54F0077A5FC /* MCORange.h */, C69BA85917DEFCCB00D601B7 /* NSIndexSet+MCO.h */, C69BA85A17DEFCCB00D601B7 /* NSIndexSet+MCO.m */, + C643F490189A3D59007EA2F7 /* NSSet+MCO.h */, + C643F491189A3D59007EA2F7 /* NSSet+MCO.mm */, ); path = utils; sourceTree = ""; @@ -2613,6 +2619,7 @@ C64EA81D16A29DC500778456 /* MCIMAPFetchContentOperation.cc in Sources */, C64EA82016A29E4100778456 /* MCIMAPStoreFlagsOperation.cc in Sources */, C64EA82316A29E5300778456 /* MCIMAPStoreLabelsOperation.cc in Sources */, + C643F492189A3D59007EA2F7 /* NSSet+MCO.mm in Sources */, C64EA82616A29EE500778456 /* MCIMAPSearchOperation.cc in Sources */, C6E665BD1796500C0063F2CF /* zip.c in Sources */, C64EA82916A29F2200778456 /* MCIMAPIdleOperation.cc in Sources */, @@ -2818,6 +2825,7 @@ C6BA2BCE1705F4E6003F0E9E /* MCIMAPFetchContentOperation.cc in Sources */, C6BA2BCF1705F4E6003F0E9E /* MCIMAPStoreFlagsOperation.cc in Sources */, C6BA2BD01705F4E6003F0E9E /* MCIMAPStoreLabelsOperation.cc in Sources */, + C643F493189A3D59007EA2F7 /* NSSet+MCO.mm in Sources */, C6BA2BD11705F4E6003F0E9E /* MCIMAPSearchOperation.cc in Sources */, C6E665BE1796500C0063F2CF /* zip.c in Sources */, C6BA2BD21705F4E6003F0E9E /* MCIMAPIdleOperation.cc in Sources */, diff --git a/src/objc/utils/NSObject+MCO.mm b/src/objc/utils/NSObject+MCO.mm index 9c6f4fa7..4887080f 100644 --- a/src/objc/utils/NSObject+MCO.mm +++ b/src/objc/utils/NSObject+MCO.mm @@ -15,6 +15,7 @@ #import "NSDictionary+MCO.h" #import "NSArray+MCO.h" #import "NSValue+MCO.h" +#import "NSSet+MCO.h" #include "MCBaseTypes.h" #include "MCUtils.h" @@ -95,6 +96,9 @@ static Class classWithTypeInfo(const std::type_info * info) else if (objectType == typeid(mailcore::Array).hash_code()) { return [NSArray mco_arrayWithMCArray:(mailcore::Array *) object]; } + else if (objectType == typeid(mailcore::Set).hash_code()) { + return [NSSet mco_setWithMCSet:(mailcore::Set *) object]; + } else { Class aClass = classWithTypeInfo(&typeid(* object)); MCAssert(aClass != nil); @@ -124,6 +128,9 @@ static Class classWithTypeInfo(const std::type_info * info) else if ([self isKindOfClass:[NSDictionary class]]) { return [(NSDictionary *) self mco_mcHashMap]; } + else if ([self isKindOfClass:[NSSet class]]) { + return [(NSSet *) self mco_mcSet]; + } else { MCAssert(0); return nil; diff --git a/src/objc/utils/NSSet+MCO.h b/src/objc/utils/NSSet+MCO.h new file mode 100644 index 00000000..17bd1bf4 --- /dev/null +++ b/src/objc/utils/NSSet+MCO.h @@ -0,0 +1,25 @@ +// +// NSSet+MCO.h +// mailcore2 +// +// Created by Hoa V. DINH on 1/29/14. +// Copyright (c) 2014 MailCore. All rights reserved. +// + +#import + +#ifdef __cplusplus +namespace mailcore { + class Set; +} +#endif + +@interface NSSet (MCO) + +#ifdef __cplusplus ++ (NSSet *) mco_setWithMCSet:(mailcore::Set *)cppSet; + +- (mailcore::Set *) mco_mcSet; +#endif + +@end diff --git a/src/objc/utils/NSSet+MCO.mm b/src/objc/utils/NSSet+MCO.mm new file mode 100644 index 00000000..690cfe77 --- /dev/null +++ b/src/objc/utils/NSSet+MCO.mm @@ -0,0 +1,45 @@ +// +// NSSet+MCO.m +// mailcore2 +// +// Created by Hoa V. DINH on 1/29/14. +// Copyright (c) 2014 MailCore. All rights reserved. +// + +#import "NSSet+MCO.h" + +#include "MCSet.h" +#include "MCArray.h" +#import "NSObject+MCO.h" + +@implementation NSSet (MCO) + ++ (id) mco_objectWithMCObject:(mailcore::Object *)object +{ + return [self mco_setWithMCSet:(mailcore::Set *) object]; +} + ++ (NSSet *) mco_setWithMCSet:(mailcore::Set *)cppSet +{ + if (cppSet == NULL) + return nil; + + NSMutableSet * result = [NSMutableSet set]; + mailcore::Array * array = cppSet->allObjects(); + for(unsigned int i = 0 ; i < array->count() ; i ++) { + [result addObject:[NSObject mco_objectWithMCObject:array->objectAtIndex(i)]]; + } + return result; +} + +- (mailcore::Set *) mco_mcSet +{ + mailcore::Set * result = mailcore::Set::set(); + NSArray * array = [self allObjects]; + for(unsigned int i = 0 ; i < [array count] ; i ++) { + result->addObject([[array objectAtIndex:i] mco_mcObject]); + } + return result; +} + +@end -- cgit v1.2.3 From 9ab4efb7bf021e4ba450e58ad4eaff5ccac3c4b5 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Fri, 31 Jan 2014 12:57:26 -0800 Subject: Fixed disconnect operation behavior when no connection is established --- src/async/imap/MCIMAPMultiDisconnectOperation.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/async/imap/MCIMAPMultiDisconnectOperation.cc b/src/async/imap/MCIMAPMultiDisconnectOperation.cc index 9b9d1a28..e58bfd92 100644 --- a/src/async/imap/MCIMAPMultiDisconnectOperation.cc +++ b/src/async/imap/MCIMAPMultiDisconnectOperation.cc @@ -28,6 +28,11 @@ void IMAPMultiDisconnectOperation::addOperation(IMAPOperation * op) void IMAPMultiDisconnectOperation::start() { + if (_operations->count() == 0) { + callback()->operationFinished(this); + return; + } + mc_foreacharray(IMAPOperation, op, _operations) { op->setCallback(this); op->start(); -- cgit v1.2.3 From 4903cbdf9ea21f10d5e6621e0d1f1c19c10005f0 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Fri, 31 Jan 2014 14:31:51 -0800 Subject: Fixed some IndexSet operations --- src/core/basetypes/MCIndexSet.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/basetypes/MCIndexSet.cc b/src/core/basetypes/MCIndexSet.cc index fe755038..ae54f8ff 100644 --- a/src/core/basetypes/MCIndexSet.cc +++ b/src/core/basetypes/MCIndexSet.cc @@ -398,14 +398,14 @@ void IndexSet::importSerializable(HashMap * serializable) void IndexSet::addIndexSet(IndexSet * indexSet) { - for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + for(unsigned int i = 0 ; i < indexSet->rangesCount() ; i ++) { addRange(indexSet->allRanges()[i]); } } void IndexSet::removeIndexSet(IndexSet * indexSet) { - for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + for(unsigned int i = 0 ; i < indexSet->rangesCount() ; i ++) { removeRange(indexSet->allRanges()[i]); } } @@ -413,7 +413,7 @@ void IndexSet::removeIndexSet(IndexSet * indexSet) void IndexSet::intersectsIndexSet(IndexSet * indexSet) { IndexSet * result = new IndexSet(); - for(unsigned int i = 0 ; i < indexSet->count() ; i ++) { + for(unsigned int i = 0 ; i < indexSet->rangesCount() ; i ++) { IndexSet * rangeIntersect = (IndexSet *) copy(); rangeIntersect->intersectsRange(indexSet->allRanges()[i]); result->addIndexSet(rangeIntersect); -- cgit v1.2.3 From 581b5879b12311de07779a75636ee6836719c01b Mon Sep 17 00:00:00 2001 From: Marco Pifferi Date: Mon, 3 Feb 2014 14:12:31 +0100 Subject: fixed MCOIMAPCapabilityOperation header guard macro --- src/objc/imap/MCOIMAPCapabilityOperation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objc/imap/MCOIMAPCapabilityOperation.h b/src/objc/imap/MCOIMAPCapabilityOperation.h index 29b0d3be..4e531160 100644 --- a/src/objc/imap/MCOIMAPCapabilityOperation.h +++ b/src/objc/imap/MCOIMAPCapabilityOperation.h @@ -8,7 +8,7 @@ #ifndef __MAILCORE_MCOIMAPCAPABILITYOPERATION_H_ -#define __MAILCORE_MCOIMAPCAPBILITYOPERATION_H_ +#define __MAILCORE_MCOIMAPCAPABILITYOPERATION_H_ /** This class implements an operation to query for IMAP capabilities, -- cgit v1.2.3 From 95f1b96ba86c610aeeb8b30c35d1254a962f5edd Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Wed, 5 Feb 2014 22:28:41 -0800 Subject: added removeLastObject() --- src/core/basetypes/MCArray.cc | 5 +++++ src/core/basetypes/MCArray.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc index c4c0fee1..804f796c 100644 --- a/src/core/basetypes/MCArray.cc +++ b/src/core/basetypes/MCArray.cc @@ -180,6 +180,11 @@ Object * Array::lastObject() return objectAtIndex(count() - 1); } +void Array::removeLastObject() +{ + removeObjectAtIndex(count() - 1); +} + bool Array::containsObject(Object * obj) { return (indexOfObject(obj) != -1); diff --git a/src/core/basetypes/MCArray.h b/src/core/basetypes/MCArray.h index cbf65b82..a26e34d8 100644 --- a/src/core/basetypes/MCArray.h +++ b/src/core/basetypes/MCArray.h @@ -32,6 +32,7 @@ namespace mailcore { virtual void addObjectsFromArray(Array * array); virtual Object * lastObject(); + virtual void removeLastObject(); virtual bool containsObject(Object * obj); virtual Array * sortedArray(int (* compare)(void * a, void * b, void * context), void * context); -- cgit v1.2.3 From 9edebd8221a3407704880de8d98226c24d88e6b1 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Wed, 5 Feb 2014 22:56:18 -0800 Subject: Render text as HTML --- src/core/basetypes/MCString.cc | 83 ++++++++++++++++++++++++++++++++++++- src/core/basetypes/MCString.h | 1 + src/core/renderer/MCHTMLRenderer.cc | 3 +- 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 26e2f931..054cbb80 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -26,6 +26,7 @@ #include "MCValue.h" #include "MCHTMLCleaner.h" #include "MCBase64.h" +#include "MCIterator.h" using namespace mailcore; @@ -1744,7 +1745,7 @@ String * String::flattenHTMLAndShowBlockquoteAndLink(bool showBlockquote, bool s String * result = String::string(); xmlSAXHandler handler; bzero(&handler, sizeof(xmlSAXHandler)); - handler.characters = &charactersParsed; + handler.characters = charactersParsed; handler.startElement = elementStarted; handler.endElement = elementEnded; handler.comment = commentParsed; @@ -2116,6 +2117,86 @@ String * String::cleanedHTMLString() return HTMLCleaner::cleanHTML(this); } +String * String::htmlMessageContent() +{ + String * str = this; + + Array * lines = str->componentsSeparatedByString(MCSTR("\n")); + + while (1) { + if (lines->count() == 0) { + break; + } + + if (((String *) lines->lastObject())->length() > 0) { + break; + } + + lines->removeLastObject(); + } + + String * localString; + int state; + localString = String::string(); + + String * quoted = NULL; + state = 0; + mc_foreacharray(String, line, lines) { + if (state == 0) { + if (line->hasPrefix(MCSTR(">"))) { + state = 1; + quoted = new String(); + int i = 1; + while (i < line->length()) { + if (line->characterAtIndex(i) != ' ') { + break; + } + i ++; + } + quoted->appendString(line->substringFromIndex(i)); + quoted->appendString(MCSTR("\n")); + } + else { + localString->appendString(line->htmlEncodedString()); + localString->appendString(MCSTR("
")); + } + } + else if (state == 1) { + if (line->hasPrefix(MCSTR(">"))) { + int i = 1; + while (i < line->length()) { + if (line->characterAtIndex(i) != ' ') { + break; + } + i ++; + } + quoted->appendString(line->substringFromIndex(i)); + quoted->appendString(MCSTR("\n")); + } + else { + if (quoted != NULL) { + localString->appendString(MCSTR("
")); + localString->appendString(quoted->htmlMessageContent()); + localString->appendString(MCSTR("
")); + MC_SAFE_RELEASE(quoted); + state = 0; + } + localString->appendString(line->htmlEncodedString()); + localString->appendString(MCSTR("
")); + } + } + } + + if (quoted != nil) { + localString->appendString(MCSTR("
")); + localString->appendString(quoted); + localString->appendString(MCSTR("
")); + MC_SAFE_RELEASE(quoted); + } + + return localString; +} + bool String::isEqualCaseInsensitive(String * otherString) { return caseInsensitiveCompare(otherString) == 0; diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h index 2afd0e7b..49e0a5ac 100644 --- a/src/core/basetypes/MCString.h +++ b/src/core/basetypes/MCString.h @@ -108,6 +108,7 @@ namespace mailcore { virtual String * htmlEncodedString(); virtual String * cleanedHTMLString(); + virtual String * htmlMessageContent(); virtual Data * decodedBase64Data(); diff --git a/src/core/renderer/MCHTMLRenderer.cc b/src/core/renderer/MCHTMLRenderer.cc index 071d7523..45c3a77a 100644 --- a/src/core/renderer/MCHTMLRenderer.cc +++ b/src/core/renderer/MCHTMLRenderer.cc @@ -266,8 +266,9 @@ static String * htmlForAbstractSinglePart(AbstractPart * part, htmlRendererConte return NULL; String * str = data->stringWithDetectedCharset(charset, false); + str = str->htmlMessageContent(); context->firstRendered = true; - return str->htmlEncodedString(); + return str; } else if (mimeType->isEqual(MCSTR("text/html"))) { String * charset = part->charset(); -- cgit v1.2.3 From 1180f5a8d4fdf97a0939ffa00b0380444fc84912 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Wed, 5 Feb 2014 23:07:49 -0800 Subject: Don't install cmake --- scripts/travis/before-script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/travis/before-script.sh b/scripts/travis/before-script.sh index b8753159..74a3fa31 100755 --- a/scripts/travis/before-script.sh +++ b/scripts/travis/before-script.sh @@ -3,4 +3,4 @@ set -e brew update #brew install xctool -brew install cmake +#brew install cmake -- cgit v1.2.3 From e451b9d5497f15c3234f1d2d72e4f4f81522cd48 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Thu, 6 Feb 2014 19:51:24 -0800 Subject: Fixed removeRange() implementation --- src/core/basetypes/MCIndexSet.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/basetypes/MCIndexSet.cc b/src/core/basetypes/MCIndexSet.cc index ae54f8ff..4306f5ff 100644 --- a/src/core/basetypes/MCIndexSet.cc +++ b/src/core/basetypes/MCIndexSet.cc @@ -277,6 +277,9 @@ void IndexSet::removeRange(Range range) int left = -1; int right = -1; int leftRangeIndex = leftRangeIndexForIndex(range.location); + if (leftRangeIndex >= mCount) { + leftRangeIndex = mCount - 1; + } for(int i = leftRangeIndex ; i < mCount ; i ++) { if (RangeHasIntersection(mRanges[i], range)) { IndexSet * indexSet = RangeRemoveRange(mRanges[i], range); -- cgit v1.2.3