aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar CodaFi <devteam.codafi@gmail.com>2014-02-08 14:04:34 -0700
committerGravatar CodaFi <devteam.codafi@gmail.com>2014-02-08 14:04:34 -0700
commit662a300de7b1d32d90fd6bbd52ecd1bcb7e93b5d (patch)
tree766c294fb46f4057938fce526d1cde007feaacd6
parent1d054727b1f37c5c2e5c591534a42bee798adff8 (diff)
parente451b9d5497f15c3234f1d2d72e4f4f81522cd48 (diff)
Merge remote-tracking branch 'upstream/master'
-rw-r--r--README.md4
-rwxr-xr-xbuild-mac/mailcore2.xcodeproj/project.pbxproj32
-rw-r--r--example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj8
-rw-r--r--example/mac/macExample/macExample/AppDelegate.m6
-rwxr-xr-xscripts/travis/before-script.sh2
-rw-r--r--src/CMakeLists.txt38
-rw-r--r--src/async/imap/MCIMAPAppendMessageOperation.cc14
-rw-r--r--src/async/imap/MCIMAPAppendMessageOperation.h4
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.cc35
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.h10
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.cc34
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.h14
-rw-r--r--src/async/imap/MCIMAPMultiDisconnectOperation.cc5
-rw-r--r--src/async/imap/MCIMAPOperation.cc13
-rw-r--r--src/async/imap/MCIMAPStoreFlagsOperation.cc14
-rw-r--r--src/async/imap/MCIMAPStoreFlagsOperation.h5
-rw-r--r--src/async/pop/MCPOPAsyncSession.cc12
-rw-r--r--src/async/pop/MCPOPAsyncSession.h5
-rw-r--r--src/async/pop/MCPOPOperation.cc10
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.cc12
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.h5
-rw-r--r--src/async/smtp/MCSMTPOperation.cc10
-rw-r--r--src/core/abstract/MCMessageConstants.h2
-rw-r--r--src/core/basetypes/MCArray.cc5
-rw-r--r--src/core/basetypes/MCArray.h1
-rw-r--r--src/core/basetypes/MCBase64.c19
-rw-r--r--src/core/basetypes/MCData.cc1
-rw-r--r--src/core/basetypes/MCIndexSet.cc31
-rw-r--r--src/core/basetypes/MCIndexSet.h4
-rw-r--r--src/core/basetypes/MCObject.cc170
-rw-r--r--src/core/basetypes/MCObject.h4
-rw-r--r--src/core/basetypes/MCOperation.h4
-rw-r--r--src/core/basetypes/MCOperationQueue.cc23
-rw-r--r--src/core/basetypes/MCOperationQueue.h8
-rw-r--r--src/core/basetypes/MCString.cc84
-rw-r--r--src/core/basetypes/MCString.h1
-rw-r--r--src/core/imap/MCIMAPMessage.cc20
-rw-r--r--src/core/imap/MCIMAPMessage.h4
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cc126
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h11
-rw-r--r--src/core/pop/MCPOPSession.cc1
-rw-r--r--src/core/renderer/MCDateFormatter.cc1
-rw-r--r--src/core/renderer/MCHTMLRenderer.cc3
-rw-r--r--src/objc/abstract/MCOConstants.h3
-rw-r--r--src/objc/imap/MCOIMAPCapabilityOperation.h2
-rw-r--r--src/objc/imap/MCOIMAPMessage.h3
-rw-r--r--src/objc/imap/MCOIMAPMessage.mm1
-rw-r--r--src/objc/imap/MCOIMAPNamespace.mm2
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.h47
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.mm29
-rw-r--r--src/objc/pop/MCOPOPSession.h6
-rw-r--r--src/objc/pop/MCOPOPSession.mm1
-rw-r--r--src/objc/smtp/MCOSMTPSession.h6
-rw-r--r--src/objc/smtp/MCOSMTPSession.mm1
-rw-r--r--src/objc/utils/MCOIndexSet.h9
-rw-r--r--src/objc/utils/MCOIndexSet.mm15
-rw-r--r--src/objc/utils/NSObject+MCO.mm7
-rw-r--r--src/objc/utils/NSSet+MCO.h25
-rw-r--r--src/objc/utils/NSSet+MCO.mm45
-rw-r--r--tests/CMakeLists.txt7
60 files changed, 887 insertions, 137 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..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})