diff options
author | CodaFi <devteam.codafi@gmail.com> | 2014-02-08 14:04:34 -0700 |
---|---|---|
committer | CodaFi <devteam.codafi@gmail.com> | 2014-02-08 14:04:34 -0700 |
commit | 662a300de7b1d32d90fd6bbd52ecd1bcb7e93b5d (patch) | |
tree | 766c294fb46f4057938fce526d1cde007feaacd6 | |
parent | 1d054727b1f37c5c2e5c591534a42bee798adff8 (diff) | |
parent | e451b9d5497f15c3234f1d2d72e4f4f81522cd48 (diff) |
Merge remote-tracking branch 'upstream/master'
60 files changed, 887 insertions, 137 deletions
@@ -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..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 = "<group>"; }; C63D316017C92D8300A4D993 /* MCOIMAPIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPIdentity.h; sourceTree = "<group>"; }; C63D316117C92D8300A4D993 /* MCOIMAPIdentity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPIdentity.mm; sourceTree = "<group>"; }; + C643F490189A3D59007EA2F7 /* NSSet+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSSet+MCO.h"; sourceTree = "<group>"; }; + C643F491189A3D59007EA2F7 /* NSSet+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSSet+MCO.mm"; sourceTree = "<group>"; }; C64BB21F16E34DCA000DB34C /* MCIMAPSyncResult.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPSyncResult.cc; sourceTree = "<group>"; }; C64BB22016E34DCB000DB34C /* MCIMAPSyncResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPSyncResult.h; sourceTree = "<group>"; }; C64BB22916E5C0A3000DB34C /* MCIMAPCapabilityOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPCapabilityOperation.cc; sourceTree = "<group>"; }; @@ -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 = "<group>"; @@ -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 */, @@ -3000,7 +3008,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 +3020,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 +3056,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 +3067,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 +3129,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", @@ -3155,7 +3165,9 @@ OTHER_LDFLAGS = ( "-lctemplate-ios", "-letpan-ios", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lsasl2", "-liconv", @@ -3216,7 +3228,9 @@ OTHER_LDFLAGS = ( "-lctemplate", "-letpan", - "-licucore", + "-licudata", + "-licui18n", + "-licuuc", "-lxml2", "-lssl", "-lcrypto", @@ -3246,7 +3260,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/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"]; 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 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/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 8403b3ed..738da0d1 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() @@ -326,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; } @@ -419,7 +421,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); @@ -427,6 +429,7 @@ IMAPOperation * IMAPAsyncConnection::storeFlagsOperation(String * folder, IndexS op->setUids(uids); op->setKind(kind); op->setFlags(flags); + op->setCustomFlags(customFlags); op->autorelease(); return op; } @@ -562,14 +565,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() @@ -697,3 +714,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 ef6893c8..0a117bea 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -81,6 +81,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); @@ -94,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); @@ -111,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); @@ -151,6 +156,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/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 573e7e42..44f753c9 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -42,10 +42,15 @@ IMAPAsyncSession::IMAPAsyncSession() mServerIdentity = new IMAPIdentity(); mClientIdentity = new IMAPIdentity(); mOperationQueueCallback = NULL; +#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); @@ -196,6 +201,11 @@ IMAPIdentity * IMAPAsyncSession::clientIdentity() return mClientIdentity; } +String * IMAPAsyncSession::gmailUserDisplayName() +{ + return mGmailUserDisplayName; +} + IMAPAsyncConnection * IMAPAsyncSession::session() { IMAPAsyncConnection * session = new IMAPAsyncConnection(); @@ -215,6 +225,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); @@ -355,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) @@ -407,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) @@ -536,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; } @@ -577,4 +589,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..0d172bb6 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -89,12 +89,18 @@ 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(); virtual IMAPIdentity * serverIdentity(); virtual IMAPIdentity * clientIdentity(); + virtual String * gmailUserDisplayName(); virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder); virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder); @@ -109,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 = NULL); virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder); @@ -126,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 = NULL); virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); @@ -178,6 +184,10 @@ namespace mailcore { IMAPIdentity * mClientIdentity; bool mQueueRunning; OperationQueueCallback * mOperationQueueCallback; +#if __APPLE__ + dispatch_queue_t mDispatchQueue; +#endif + String * mGmailUserDisplayName; virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); virtual IMAPAsyncConnection * session(); 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(); diff --git a/src/async/imap/MCIMAPOperation.cc b/src/async/imap/MCIMAPOperation.cc index da3ae6dd..e4b3529b 100644 --- a/src/async/imap/MCIMAPOperation.cc +++ b/src/async/imap/MCIMAPOperation.cc @@ -9,9 +9,6 @@ #include "MCIMAPOperation.h" #include <stdlib.h> -#if __APPLE__ -#include <dispatch/dispatch.h> -#endif #include "MCIMAPAsyncSession.h" #include "MCIMAPSession.h" @@ -37,6 +34,16 @@ IMAPOperation::~IMAPOperation() void IMAPOperation::setSession(IMAPAsyncConnection * session) { MC_SAFE_REPLACE_RETAIN(IMAPAsyncConnection, mSession, session); +#if __APPLE__ + dispatch_queue_t queue; + if (session != NULL) { + queue = session->dispatchQueue(); + } + else { + queue = dispatch_get_main_queue(); + } + setCallbackDispatchQueue(queue); +#endif } IMAPAsyncConnection * IMAPOperation::session() diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.cc b/src/async/imap/MCIMAPStoreFlagsOperation.cc index e0464c8c..df68529a 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()->storeFlagsAndCustomFlags(folder(), mUids, mKind, mFlags, mCustomFlags, &error); setError(error); } diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.h b/src/async/imap/MCIMAPStoreFlagsOperation.h index 0048283c..c1b17db5 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,7 +40,7 @@ namespace mailcore { IndexSet * mUids; IMAPStoreFlagsRequestKind mKind; MessageFlag mFlags; - + Array * mCustomFlags; }; } 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/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index f5d7f259..1381b5e6 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -42,6 +42,8 @@ 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/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); 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++ = '='; } 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 <stdlib.h> #include <string.h> #include <sys/stat.h> -#define U_DISABLE_RENAMING 1 #include <unicode/ucsdet.h> #include <libetpan/libetpan.h> #include <iconv.h> diff --git a/src/core/basetypes/MCIndexSet.cc b/src/core/basetypes/MCIndexSet.cc index db25f5eb..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); @@ -396,6 +399,34 @@ void IndexSet::importSerializable(HashMap * serializable) } } +void IndexSet::addIndexSet(IndexSet * indexSet) +{ + 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->rangesCount() ; i ++) { + removeRange(indexSet->allRanges()[i]); + } +} + +void IndexSet::intersectsIndexSet(IndexSet * indexSet) +{ + IndexSet * result = new IndexSet(); + for(unsigned int i = 0 ; i < indexSet->rangesCount() ; 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(); 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 <cxxabi.h> #include <libetpan/libetpan.h> #include <string.h> +#include <Block.h> #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 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 <pthread.h> #include <MailCore/MCObject.h> -#if __APPLE__ -#include <dispatch/dispatch.h> -#endif - #ifdef __cplusplus namespace mailcore { 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/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 3862cd4f..054cbb80 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -2,7 +2,6 @@ #include <string.h> #include <stdlib.h> -#define U_DISABLE_RENAMING 1 #include <unicode/ustring.h> #include <unicode/ucnv.h> #include <unicode/utypes.h> @@ -27,6 +26,7 @@ #include "MCValue.h" #include "MCHTMLCleaner.h" #include "MCBase64.h" +#include "MCIterator.h" using namespace mailcore; @@ -1745,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; @@ -2117,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("<br/>")); + } + } + 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("<blockquote type=\"cite\">")); + localString->appendString(quoted->htmlMessageContent()); + localString->appendString(MCSTR("</blockquote>")); + MC_SAFE_RELEASE(quoted); + state = 0; + } + localString->appendString(line->htmlEncodedString()); + localString->appendString(MCSTR("<br/>")); + } + } + } + + if (quoted != nil) { + localString->appendString(MCSTR("<blockquote type=\"cite\">")); + localString->appendString(quoted); + localString->appendString(MCSTR("</blockquote>")); + 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/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 59d67654..6845d19a 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()); @@ -45,6 +47,7 @@ IMAPMessage::~IMAPMessage() { MC_SAFE_RELEASE(mMainPart); MC_SAFE_RELEASE(mGmailLabels); + MC_SAFE_RELEASE(mCustomFlags); } Object * IMAPMessage::copy() @@ -105,6 +108,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 +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())); + if (customFlags() != NULL) { + result->setObjectForKey(MCSTR("customFlags"), customFlags()); + } result->setObjectForKey(MCSTR("mainPart"), mMainPart->serializable()); if (gmailLabels() != NULL) { result->setObjectForKey(MCSTR("gmailLabels"), gmailLabels()); @@ -262,6 +278,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 32cd4ebd..02e569dc 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; @@ -156,6 +156,62 @@ 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; + + clistiter * iter; + bool hasCustomFlags = false; + + 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)) { + 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); + } + } + } + + return result; +} + #pragma mark set conversion static Array * arrayFromSet(struct mailimap_set * imap_set) @@ -320,6 +376,7 @@ void IMAPSession::init() mIdentityEnabled = false; mNamespaceEnabled = false; mCompressionEnabled = false; + mIsGmail = false; mWelcomeString = NULL; mNeedsMboxMailWorkaround = false; mDefaultNamespace = NULL; @@ -344,6 +401,8 @@ void IMAPSession::init() mAutomaticConfigurationEnabled = true; mAutomaticConfigurationDone = false; mShouldDisconnect = false; + mLoginResponse = NULL; + mGmailUserDisplayName = NULL; } IMAPSession::IMAPSession() @@ -353,6 +412,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 +880,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()) { @@ -1500,6 +1578,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; uint32_t uidvalidity; @@ -1514,6 +1598,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); @@ -1876,6 +1969,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; @@ -3165,6 +3262,11 @@ HashMap * IMAPSession::fetchNamespace(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; struct mailimap_flag_list * flag_list; @@ -3233,10 +3335,20 @@ void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsReq } if ((flags & MessageFlagSubmitted) != 0) { struct mailimap_flag * f; - + 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)) { @@ -3494,6 +3606,7 @@ void IMAPSession::applyCapabilities(IndexSet * capabilities) } if (capabilities->containsIndex(IMAPCapabilityGmail)) { mXListEnabled = false; + mIsGmail = true; } if (capabilities->containsIndex(IMAPCapabilityIdle)) { mIdleEnabled = true; @@ -3726,3 +3839,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..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, 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); @@ -163,6 +166,8 @@ namespace mailcore { virtual bool isNamespaceEnabled(); virtual bool isCompressionEnabled(); + virtual String * gmailUserDisplayName(); + virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); @@ -219,6 +224,7 @@ namespace mailcore { bool mXOauth2Enabled; bool mNamespaceEnabled; bool mCompressionEnabled; + bool mIsGmail; String * mWelcomeString; bool mNeedsMboxMailWorkaround; uint32_t mUIDValidity; @@ -241,6 +247,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/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(); 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 <stdlib.h> -#define U_DISABLE_RENAMING 1 #include <unicode/udat.h> #if defined(__APPLE__) 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(); 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/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, diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index 7f28663e..bcee7eaf 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, 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/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) diff --git a/src/objc/imap/MCOIMAPNamespace.mm b/src/objc/imap/MCOIMAPNamespace.mm index 4615fc80..e6181d87 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_OBJC_BRIDGE_GET(prefixes); } - (NSString *) pathForComponents:(NSArray *)components diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 867cfb6d..b013c9c0 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 @@ -110,6 +113,12 @@ */ @property (nonatomic, copy) MCOConnectionLogger connectionLogger; +/** 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. */ +@property (nonatomic, assign) dispatch_queue_t dispatchQueue; + /** The value will be YES when asynchronous operations are running, else it will return NO. */ @@ -263,13 +272,28 @@ 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. 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 @@ -294,6 +318,25 @@ kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags; /** + Returns an operation to change flags and custom flags of messages. + + 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:@["$CNS-Greeting-On"]]; + [op start:^(NSError * error) { + ... + }]; + */ +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + uids:(MCOIndexSet *)uids + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags; +/** Returns an operation to change labels of messages. Intended for Gmail For example: Adds the label "Home" flag to the message with UID 456. diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index a53456ae..0b0c638a 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 { @@ -126,6 +127,11 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma return MCO_OBJC_BRIDGE_GET(serverIdentity); } +- (NSString *) gmailUserDisplayName +{ + return MCO_TO_OBJC(_session->gmailUserDisplayName()); +} + - (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger { [_connectionLogger release]; @@ -238,9 +244,18 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma 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); } @@ -334,10 +349,20 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags { + return [self storeFlagsOperationWithFolder:folder uids:uids kind:kind flags:flags customFlags:NULL]; +} + +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + 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); } 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 { 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(); 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 <Foundation/Foundation.h> + +#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 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}) |