aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--build-mac/mailcore2.xcodeproj/project.pbxproj24
-rw-r--r--example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h2
-rw-r--r--example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m23
-rw-r--r--example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib235
-rw-r--r--src/async/imap/MCIMAPAsyncConnection.cc75
-rw-r--r--src/async/imap/MCIMAPAsyncConnection.h15
-rw-r--r--src/async/imap/MCIMAPAsyncSession.cc2
-rw-r--r--src/async/imap/MCIMAPAsyncSession.h8
-rw-r--r--src/async/imap/MCIMAPDisconnectOperation.cc28
-rw-r--r--src/async/imap/MCIMAPDisconnectOperation.h32
-rw-r--r--src/async/pop/MCPOPAsyncSession.cc28
-rw-r--r--src/async/pop/MCPOPAsyncSession.h4
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.cc67
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.h12
-rw-r--r--src/async/smtp/MCSMTPDisconnectOperation.cc28
-rw-r--r--src/async/smtp/MCSMTPDisconnectOperation.h32
-rw-r--r--src/async/smtp/MCSMTPOperation.cc1
-rw-r--r--src/core/abstract/MCMessageConstants.h1
-rw-r--r--src/core/basetypes/MCMainThread.h11
-rw-r--r--src/core/basetypes/MCMainThread.mm9
-rw-r--r--src/core/basetypes/MCObject.cc71
-rw-r--r--src/core/basetypes/MCObject.h1
-rw-r--r--src/core/basetypes/MCOperationQueue.cc24
-rw-r--r--src/core/basetypes/MCOperationQueue.h65
-rw-r--r--src/core/basetypes/MCOperationQueueCallback.h23
-rw-r--r--src/core/imap/MCIMAPMessage.cc11
-rw-r--r--src/core/imap/MCIMAPMessage.h72
-rw-r--r--src/core/imap/MCIMAPSession.cc36
-rw-r--r--src/core/imap/MCIMAPSession.h269
-rw-r--r--src/core/smtp/MCSMTPSession.cc6
-rw-r--r--src/core/smtp/MCSMTPSession.h3
-rw-r--r--src/objc/abstract/MCOConstants.h2
-rw-r--r--src/objc/imap/MCOIMAPBaseOperation+Private.h20
-rw-r--r--src/objc/imap/MCOIMAPBaseOperation.mm15
-rw-r--r--src/objc/imap/MCOIMAPMessage.h3
-rw-r--r--src/objc/imap/MCOIMAPMessage.mm1
-rw-r--r--src/objc/imap/MCOIMAPOperation.h4
-rw-r--r--src/objc/imap/MCOIMAPSession.mm70
-rw-r--r--src/objc/pop/MCOPOPOperation+Private.h20
-rw-r--r--src/objc/pop/MCOPOPOperation.mm13
-rw-r--r--src/objc/pop/MCOPOPSession.mm31
-rw-r--r--src/objc/smtp/MCOSMTPOperation+Private.h20
-rw-r--r--src/objc/smtp/MCOSMTPOperation.mm14
-rw-r--r--src/objc/smtp/MCOSMTPSession.mm9
44 files changed, 1132 insertions, 308 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj
index 37a955c6..0f932f5c 100644
--- a/build-mac/mailcore2.xcodeproj/project.pbxproj
+++ b/build-mac/mailcore2.xcodeproj/project.pbxproj
@@ -29,6 +29,10 @@
C07AD5D7FD82F8ACAB576231 /* NSError+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C07AD44B013BB42A240B4F04 /* NSError+MCO.h */; };
C07AD99B2E2054C684DB8FF6 /* NSError+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */; };
C07ADC28B83E7959BF114D46 /* MCOIMAPSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */; };
+ C608167517759967001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; };
+ C608167617759968001F1018 /* MCSMTPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */; };
+ C608167B177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */; };
+ C608167C177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */; };
C623C58616FD6A50001BBEFC /* MCOConstants.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB26D16FD63F6000DB34C /* MCOConstants.h */; };
C623C58716FD6A61001BBEFC /* MCOOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25716FD3BC2000DB34C /* MCOOperation.h */; };
C623C58816FD6DF6001BBEFC /* NSValue+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB25016FC2846000DB34C /* NSValue+MCO.h */; };
@@ -1072,6 +1076,14 @@
C07AD057D3C8FBDC7AC95733 /* MCOIMAPSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPSession.mm; sourceTree = "<group>"; };
C07AD44B013BB42A240B4F04 /* NSError+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+MCO.h"; sourceTree = "<group>"; };
C07ADFE43E22B38EFF23ADB5 /* NSError+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+MCO.mm"; sourceTree = "<group>"; };
+ C60136941776B96600A5AF45 /* MCOSMTPOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOSMTPOperation+Private.h"; sourceTree = "<group>"; };
+ C60136951776C31000A5AF45 /* MCOPOPOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOPOPOperation+Private.h"; sourceTree = "<group>"; };
+ C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCSMTPDisconnectOperation.cc; sourceTree = "<group>"; };
+ C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCSMTPDisconnectOperation.h; sourceTree = "<group>"; };
+ C6081678177625AD001F1018 /* MCOperationQueueCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOperationQueueCallback.h; sourceTree = "<group>"; };
+ C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPDisconnectOperation.cc; sourceTree = "<group>"; };
+ C608167A177635D2001F1018 /* MCIMAPDisconnectOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPDisconnectOperation.h; sourceTree = "<group>"; };
+ C608167F17766FC5001F1018 /* MCOIMAPBaseOperation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOIMAPBaseOperation+Private.h"; sourceTree = "<group>"; };
C623C58A16FD8C22001BBEFC /* MCOAbstractMessage+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCOAbstractMessage+Private.h"; sourceTree = "<group>"; };
C623C58B16FE52C0001BBEFC /* MCOHTMLRendererDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOHTMLRendererDelegate.h; sourceTree = "<group>"; };
C623C58D16FE6B45001BBEFC /* MCOIMAPOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPOperation.h; sourceTree = "<group>"; };
@@ -1669,6 +1681,8 @@
C64BB22A16E5C0A3000DB34C /* MCIMAPCapabilityOperation.h */,
9EF9AB10175F319A0027FA3B /* MCIMAPFolderStatusOperation.cc */,
9EF9AB0E175F30C20027FA3B /* MCIMAPFolderStatusOperation.h */,
+ C6081679177635D2001F1018 /* MCIMAPDisconnectOperation.cc */,
+ C608167A177635D2001F1018 /* MCIMAPDisconnectOperation.h */,
);
path = imap;
sourceTree = "<group>";
@@ -1704,6 +1718,8 @@
C64EA690169E847800778456 /* MCSMTPAsyncSession.h */,
C64EA79C169F29A700778456 /* MCSMTPSendWithDataOperation.cc */,
C64EA79D169F29A700778456 /* MCSMTPSendWithDataOperation.h */,
+ C608167317759967001F1018 /* MCSMTPDisconnectOperation.cc */,
+ C608167417759967001F1018 /* MCSMTPDisconnectOperation.h */,
C64EA7D816A1386500778456 /* MCSMTPOperation.cc */,
C64EA7D916A1386600778456 /* MCSMTPOperation.h */,
C64EA7E116A1425400778456 /* MCSMTPOperationCallback.h */,
@@ -1797,6 +1813,7 @@
C64EA6C0169E847800778456 /* MCOperationCallback.h */,
C64EA6C1169E847800778456 /* MCOperationQueue.cc */,
C64EA6C2169E847800778456 /* MCOperationQueue.h */,
+ C6081678177625AD001F1018 /* MCOperationQueueCallback.h */,
C63CD68F16BE566D00DB18F1 /* MCHTMLCleaner.cc */,
C63CD69016BE566E00DB18F1 /* MCHTMLCleaner.h */,
C64BB22C16E5C1EE000DB34C /* MCIndexSet.cc */,
@@ -1993,6 +2010,7 @@
C6A81BD41706903500882C15 /* MCOPOPSession.h */,
C6A81BD51706903500882C15 /* MCOPOPSession.mm */,
C6A81BE01706905600882C15 /* MCOPOPOperation.h */,
+ C60136951776C31000A5AF45 /* MCOPOPOperation+Private.h */,
C6A81BE11706905600882C15 /* MCOPOPOperation.mm */,
C6A81BD81706903E00882C15 /* MCOPOPFetchHeaderOperation.h */,
C6A81BD91706903E00882C15 /* MCOPOPFetchHeaderOperation.mm */,
@@ -2015,6 +2033,7 @@
C6A81BC117068E9500882C15 /* MCOSMTPSendOperation.h */,
C6A81BC217068E9500882C15 /* MCOSMTPSendOperation.mm */,
C6A81BC517068EB000882C15 /* MCOSMTPOperation.h */,
+ C60136941776B96600A5AF45 /* MCOSMTPOperation+Private.h */,
C6A81BC617068EB000882C15 /* MCOSMTPOperation.mm */,
);
path = smtp;
@@ -2049,6 +2068,7 @@
C6F61F79170169EE0073032E /* MCOIMAPFolderInfoOperation.h */,
C6F61F7A170169EE0073032E /* MCOIMAPFolderInfoOperation.mm */,
C6F61FB31702AB2A0073032E /* MCOIMAPBaseOperation.h */,
+ C608167F17766FC5001F1018 /* MCOIMAPBaseOperation+Private.h */,
C6F61FB41702AB2F0073032E /* MCOIMAPBaseOperation.mm */,
C6F61F7C170169FB0073032E /* MCOIMAPAppendMessageOperation.h */,
C6F61F7D170169FB0073032E /* MCOIMAPAppendMessageOperation.mm */,
@@ -2419,11 +2439,13 @@
C6F61F9917016B460073032E /* MCOIMAPSearchExpression.mm in Sources */,
C6F61F9F17016EA10073032E /* MCOIMAPFolderInfo.m in Sources */,
C6F61FB51702AB340073032E /* MCOIMAPBaseOperation.mm in Sources */,
+ C608167517759967001F1018 /* MCSMTPDisconnectOperation.cc in Sources */,
C6A81BBF17068E5E00882C15 /* MCOSMTPSession.mm in Sources */,
C6A81BC317068E9500882C15 /* MCOSMTPSendOperation.mm in Sources */,
C6A81BC717068EB000882C15 /* MCOSMTPOperation.mm in Sources */,
C6A81BD61706903500882C15 /* MCOPOPSession.mm in Sources */,
C6A81BDA1706903E00882C15 /* MCOPOPFetchHeaderOperation.mm in Sources */,
+ C608167B177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */,
C6A81BDE1706904800882C15 /* MCOPOPFetchMessageOperation.mm in Sources */,
C6A81BE21706905600882C15 /* MCOPOPOperation.mm in Sources */,
C6A81BE61706906D00882C15 /* MCOPOPFetchMessagesOperation.mm in Sources */,
@@ -2597,11 +2619,13 @@
C6BA2C121705F4E6003F0E9E /* MCOIMAPSearchExpression.mm in Sources */,
C6BA2C131705F4E6003F0E9E /* MCOIMAPFolderInfo.m in Sources */,
C6BA2C141705F4E6003F0E9E /* MCOIMAPBaseOperation.mm in Sources */,
+ C608167617759968001F1018 /* MCSMTPDisconnectOperation.cc in Sources */,
C6A81BC017068E5E00882C15 /* MCOSMTPSession.mm in Sources */,
C6A81BC417068E9500882C15 /* MCOSMTPSendOperation.mm in Sources */,
C6A81BC817068EB000882C15 /* MCOSMTPOperation.mm in Sources */,
C6A81BD71706903500882C15 /* MCOPOPSession.mm in Sources */,
C6A81BDB1706903E00882C15 /* MCOPOPFetchHeaderOperation.mm in Sources */,
+ C608167C177635D2001F1018 /* MCIMAPDisconnectOperation.cc in Sources */,
C6A81BDF1706904800882C15 /* MCOPOPFetchMessageOperation.mm in Sources */,
C6A81BE31706905600882C15 /* MCOPOPOperation.mm in Sources */,
C6A81BE71706906D00882C15 /* MCOPOPFetchMessagesOperation.mm in Sources */,
diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h
index 2172b4d4..e5f5da48 100644
--- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h
+++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h
@@ -11,6 +11,7 @@
extern NSString * const UsernameKey;
extern NSString * const PasswordKey;
extern NSString * const HostnameKey;
+extern NSString * const FetchFullMessageKey;
@protocol SettingsViewControllerDelegate;
@@ -19,6 +20,7 @@ extern NSString * const HostnameKey;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@property (weak, nonatomic) IBOutlet UITextField *hostnameTextField;
+@property (weak, nonatomic) IBOutlet UISwitch *fetchFullMessageSwitch;
@property (nonatomic, weak) id<SettingsViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m
index 6fbd6db2..e2f0d2c5 100644
--- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m
+++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m
@@ -12,24 +12,27 @@
NSString * const UsernameKey = @"username";
NSString * const PasswordKey = @"password";
NSString * const HostnameKey = @"hostname";
+NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled";
@implementation SettingsViewController
- (void)done:(id)sender {
- [[NSUserDefaults standardUserDefaults] setObject:self.emailTextField.text ?: @"" forKey:UsernameKey];
- [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey];
- [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey];
-
- [self.delegate settingsViewControllerFinished:self];
+ [[NSUserDefaults standardUserDefaults] setObject:self.emailTextField.text ?: @"" forKey:UsernameKey];
+ [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey];
+ [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey];
+ [[NSUserDefaults standardUserDefaults] setBool:[self.fetchFullMessageSwitch isOn] forKey:FetchFullMessageKey];
+
+ [self.delegate settingsViewControllerFinished:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
-
- self.view.backgroundColor = [UIColor underPageBackgroundColor];
- self.emailTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:UsernameKey];
- self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey];
- self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey];
+
+ self.view.backgroundColor = [UIColor underPageBackgroundColor];
+ self.emailTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:UsernameKey];
+ self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey];
+ self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey];
+ self.fetchFullMessageSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:FetchFullMessageKey];
}
@end
diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib
index 00041150..3de561bd 100644
--- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib
+++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib
@@ -2,9 +2,9 @@
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1552</int>
- <string key="IBDocument.SystemVersion">12D78</string>
+ <string key="IBDocument.SystemVersion">12E55</string>
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
- <string key="IBDocument.AppKitVersion">1187.37</string>
+ <string key="IBDocument.AppKitVersion">1187.39</string>
<string key="IBDocument.HIToolboxVersion">626.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
@@ -14,8 +14,10 @@
<string>IBNSLayoutConstraint</string>
<string>IBProxyObject</string>
<string>IBUIBarButtonItem</string>
+ <string>IBUILabel</string>
<string>IBUINavigationBar</string>
<string>IBUINavigationItem</string>
+ <string>IBUISwitch</string>
<string>IBUITextField</string>
<string>IBUIView</string>
</array>
@@ -136,7 +138,7 @@
<string key="NSFrame">{{20, 142}, {280, 30}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
- <reference key="NSNextKeyView"/>
+ <reference key="NSNextKeyView" ref="484795553"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
@@ -159,6 +161,44 @@
<reference key="IBUIFontDescription" ref="985700861"/>
<reference key="IBUIFont" ref="649714166"/>
</object>
+ <object class="IBUISwitch" id="348875194">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{208, 180}, {94, 27}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ </object>
+ <object class="IBUILabel" id="484795553">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 183}, {143, 21}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="348875194"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">Fetch full message</string>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAAA</bytes>
+ <string key="IBUIColorCocoaTouchKeyPath">darkTextColor</string>
+ </object>
+ <nil key="IBUIHighlightedColor"/>
+ <int key="IBUIBaselineAdjustment">0</int>
+ <reference key="IBUIFontDescription" ref="985700861"/>
+ <reference key="IBUIFont" ref="649714166"/>
+ <bool key="IBUIAdjustsFontSizeToFit">NO</bool>
+ </object>
</array>
<string key="NSFrame">{{0, 20}, {320, 548}}</string>
<reference key="NSSuperview"/>
@@ -193,14 +233,6 @@
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
- <string key="label">view</string>
- <reference key="source" ref="372490531"/>
- <reference key="destination" ref="191373211"/>
- </object>
- <int key="connectionID">3</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">emailTextField</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="339913914"/>
@@ -224,6 +256,22 @@
<int key="connectionID">55</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">fetchFullMessageSwitch</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="348875194"/>
+ </object>
+ <int key="connectionID">68</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">69</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">done:</string>
<reference key="source" ref="38144743"/>
@@ -244,6 +292,70 @@
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
+ <object class="IBNSLayoutConstraint" id="148058045">
+ <reference key="firstItem" ref="348875194"/>
+ <int key="firstAttribute">3</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="394260873"/>
+ <int key="secondAttribute">4</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">8</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="191373211"/>
+ <int key="scoringType">6</int>
+ <float key="scoringTypeFloat">24</float>
+ <int key="contentType">3</int>
+ </object>
+ <object class="IBNSLayoutConstraint" id="719571487">
+ <reference key="firstItem" ref="191373211"/>
+ <int key="firstAttribute">6</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="348875194"/>
+ <int key="secondAttribute">6</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="191373211"/>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ </object>
+ <object class="IBNSLayoutConstraint" id="918242346">
+ <reference key="firstItem" ref="484795553"/>
+ <int key="firstAttribute">10</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="348875194"/>
+ <int key="secondAttribute">10</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">0.0</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="191373211"/>
+ <int key="scoringType">6</int>
+ <float key="scoringTypeFloat">24</float>
+ <int key="contentType">2</int>
+ </object>
+ <object class="IBNSLayoutConstraint" id="342906512">
+ <reference key="firstItem" ref="484795553"/>
+ <int key="firstAttribute">5</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="191373211"/>
+ <int key="secondAttribute">5</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="191373211"/>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ </object>
<object class="IBNSLayoutConstraint" id="1036238214">
<reference key="firstItem" ref="191373211"/>
<int key="firstAttribute">6</int>
@@ -440,6 +552,8 @@
<reference ref="339913914"/>
<reference ref="923634912"/>
<reference ref="394260873"/>
+ <reference ref="348875194"/>
+ <reference ref="484795553"/>
</array>
<reference key="parent" ref="0"/>
</object>
@@ -551,6 +665,80 @@
<reference key="object" ref="1036238214"/>
<reference key="parent" ref="191373211"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="348875194"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="719571487"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="148058045"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">59</int>
+ <reference key="object" ref="484795553"/>
+ <array class="NSMutableArray" key="children">
+ <object class="IBNSLayoutConstraint" id="269062633">
+ <reference key="firstItem" ref="484795553"/>
+ <int key="firstAttribute">8</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">21</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="484795553"/>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ </object>
+ <object class="IBNSLayoutConstraint" id="670227139">
+ <reference key="firstItem" ref="484795553"/>
+ <int key="firstAttribute">7</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">143</double>
+ </object>
+ <float key="priority">1000</float>
+ <reference key="containingView" ref="484795553"/>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ </object>
+ </array>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">60</int>
+ <reference key="object" ref="342906512"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">61</int>
+ <reference key="object" ref="918242346"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">70</int>
+ <reference key="object" ref="670227139"/>
+ <reference key="parent" ref="484795553"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">71</int>
+ <reference key="object" ref="269062633"/>
+ <reference key="parent" ref="484795553"/>
+ </object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -572,6 +760,10 @@
<reference ref="457196062"/>
<reference ref="662191761"/>
<reference ref="1036238214"/>
+ <reference ref="342906512"/>
+ <reference ref="918242346"/>
+ <reference ref="719571487"/>
+ <reference ref="148058045"/>
</array>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
@@ -594,13 +786,27 @@
<string key="52.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="53.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="54.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <boolean value="NO" key="56.IBViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="59.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <array key="59.IBViewMetadataConstraints">
+ <reference ref="670227139"/>
+ <reference ref="269062633"/>
+ </array>
+ <boolean value="NO" key="59.IBViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="60.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="61.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="70.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="71.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">55</int>
+ <int key="maxID">71</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -628,6 +834,7 @@
</object>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="emailTextField">UITextField</string>
+ <string key="fetchFullMessageSwitch">UISwitch</string>
<string key="hostnameTextField">UITextField</string>
<string key="passwordTextField">UITextField</string>
</dictionary>
@@ -636,6 +843,10 @@
<string key="name">emailTextField</string>
<string key="candidateClassName">UITextField</string>
</object>
+ <object class="IBToOneOutletInfo" key="fetchFullMessageSwitch">
+ <string key="name">fetchFullMessageSwitch</string>
+ <string key="candidateClassName">UISwitch</string>
+ </object>
<object class="IBToOneOutletInfo" key="hostnameTextField">
<string key="name">hostnameTextField</string>
<string key="candidateClassName">UITextField</string>
diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc
index 5b1269da..ed40932c 100644
--- a/src/async/imap/MCIMAPAsyncConnection.cc
+++ b/src/async/imap/MCIMAPAsyncConnection.cc
@@ -30,9 +30,36 @@
#include "MCIMAPIdleOperation.h"
#include "MCIMAPIdentityOperation.h"
#include "MCIMAPCapabilityOperation.h"
+#include "MCOperationQueueCallback.h"
+#include "MCIMAPDisconnectOperation.h"
+#include "MCIMAPAsyncSession.h"
using namespace mailcore;
+namespace mailcore {
+ class IMAPOperationQueueCallback : public Object, public OperationQueueCallback {
+ public:
+ IMAPOperationQueueCallback(IMAPAsyncConnection * connection) {
+ mConnection = connection;
+ }
+
+ virtual ~IMAPOperationQueueCallback() {
+ }
+
+ virtual void queueStartRunning() {
+ mConnection->queueStartRunning();
+ }
+
+ virtual void queueStoppedRunning() {
+ mConnection->tryAutomaticDisconnect();
+ mConnection->queueStoppedRunning();
+ }
+
+ private:
+ IMAPAsyncConnection * mConnection;
+ };
+}
+
IMAPAsyncConnection::IMAPAsyncConnection()
{
mSession = new IMAPSession();
@@ -40,10 +67,15 @@ IMAPAsyncConnection::IMAPAsyncConnection()
mDefaultNamespace = NULL;
mDelimiter = 0;
mLastFolder = NULL;
+ mQueueCallback = new IMAPOperationQueueCallback(this);
+ mQueue->setCallback(mQueueCallback);
+ mOwner = NULL;
}
IMAPAsyncConnection::~IMAPAsyncConnection()
{
+ cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL);
+ MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mLastFolder);
MC_SAFE_RELEASE(mDefaultNamespace);
MC_SAFE_RELEASE(mQueue);
@@ -439,10 +471,40 @@ unsigned int IMAPAsyncConnection::operationsCount()
void IMAPAsyncConnection::runOperation(IMAPOperation * operation)
{
-#warning disconnect after delay
+ cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL);
mQueue->addOperation(operation);
}
+void IMAPAsyncConnection::tryAutomaticDisconnect()
+{
+ // It's safe since no thread is running when this function is called.
+ if (mSession->isDisconnected()) {
+ return;
+ }
+
+ performMethodAfterDelay((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL, 30);
+}
+
+void IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay(void * context)
+{
+ IMAPDisconnectOperation * op = new IMAPDisconnectOperation();
+ op->setSession(this);
+ op->autorelease();
+ op->start();
+}
+
+void IMAPAsyncConnection::queueStartRunning()
+{
+ this->retain();
+ mOwner->retain();
+}
+
+void IMAPAsyncConnection::queueStoppedRunning()
+{
+ mOwner->release();
+ this->release();
+}
+
void IMAPAsyncConnection::setLastFolder(String * folder)
{
MC_SAFE_REPLACE_COPY(String, mLastFolder, folder);
@@ -453,3 +515,14 @@ String * IMAPAsyncConnection::lastFolder()
return mLastFolder;
}
+void IMAPAsyncConnection::setOwner(IMAPAsyncSession * owner)
+{
+ mOwner = owner;
+}
+
+IMAPAsyncSession * IMAPAsyncConnection::owner()
+{
+ return mOwner;
+}
+
+
diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h
index 4843702b..d6ef6a91 100644
--- a/src/async/imap/MCIMAPAsyncConnection.h
+++ b/src/async/imap/MCIMAPAsyncConnection.h
@@ -25,6 +25,8 @@ namespace mailcore {
class IMAPFetchNamespaceOperation;
class IMAPIdentityOperation;
class IMAPCapabilityOperation;
+ class IMAPOperationQueueCallback;
+ class IMAPAsyncSession;
class IMAPAsyncConnection : public Object {
public:
@@ -116,8 +118,10 @@ namespace mailcore {
char mDelimiter;
IMAPNamespace * mDefaultNamespace;
String * mLastFolder;
-
- void queue(IMAPOperation * op);
+ IMAPOperationQueueCallback * mQueueCallback;
+ IMAPAsyncSession * mOwner;
+
+ virtual void tryAutomaticDisconnectAfterDelay(void * context);
public: // private
virtual void runOperation(IMAPOperation * operation);
@@ -127,6 +131,13 @@ namespace mailcore {
virtual void setLastFolder(String * folder);
virtual String * lastFolder();
+
+ virtual void tryAutomaticDisconnect();
+ virtual void queueStartRunning();
+ virtual void queueStoppedRunning();
+
+ virtual void setOwner(IMAPAsyncSession * owner);
+ virtual IMAPAsyncSession * owner();
};
}
diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc
index 766b6fe6..7c085e4a 100644
--- a/src/async/imap/MCIMAPAsyncSession.cc
+++ b/src/async/imap/MCIMAPAsyncSession.cc
@@ -10,6 +10,7 @@
#include "MCIMAPAsyncConnection.h"
#include "MCIMAPNamespace.h"
+#include "MCOperationQueueCallback.h"
#define DEFAULT_MAX_CONNECTIONS 3
@@ -173,6 +174,7 @@ unsigned int IMAPAsyncSession::maximumConnections()
IMAPAsyncConnection * IMAPAsyncSession::session()
{
IMAPAsyncConnection * session = new IMAPAsyncConnection();
+ session->setOwner(this);
session->autorelease();
session->setHostname(mHostname);
diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h
index a2bc05f8..390fdab8 100644
--- a/src/async/imap/MCIMAPAsyncSession.h
+++ b/src/async/imap/MCIMAPAsyncSession.h
@@ -142,10 +142,10 @@ namespace mailcore {
bool mAllowsFolderConcurrentAccessEnabled;
unsigned int mMaximumConnections;
- IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false);
- IMAPAsyncConnection * session();
- IMAPAsyncConnection * matchingSessionForFolder(String * folder);
- IMAPAsyncConnection * availableSession();
+ virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false);
+ virtual IMAPAsyncConnection * session();
+ virtual IMAPAsyncConnection * matchingSessionForFolder(String * folder);
+ virtual IMAPAsyncConnection * availableSession();
};
}
diff --git a/src/async/imap/MCIMAPDisconnectOperation.cc b/src/async/imap/MCIMAPDisconnectOperation.cc
new file mode 100644
index 00000000..070eeaae
--- /dev/null
+++ b/src/async/imap/MCIMAPDisconnectOperation.cc
@@ -0,0 +1,28 @@
+//
+// MCIMAPDisconnectOperation.cc
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCIMAPDisconnectOperation.h"
+
+#include "MCIMAPAsyncConnection.h"
+#include "MCIMAPSession.h"
+
+using namespace mailcore;
+
+IMAPDisconnectOperation::IMAPDisconnectOperation()
+{
+}
+
+IMAPDisconnectOperation::~IMAPDisconnectOperation()
+{
+}
+
+void IMAPDisconnectOperation::main()
+{
+ session()->session()->disconnect();
+ setError(ErrorCode::ErrorNone);
+}
diff --git a/src/async/imap/MCIMAPDisconnectOperation.h b/src/async/imap/MCIMAPDisconnectOperation.h
new file mode 100644
index 00000000..5d572def
--- /dev/null
+++ b/src/async/imap/MCIMAPDisconnectOperation.h
@@ -0,0 +1,32 @@
+//
+// MCIMAPDisconnectOperation.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCIMAPDISCONNECTOPERATION_H_
+#define __MAILCORE_MCIMAPDISCONNECTOPERATION_H_
+
+#include <MailCore/MCBaseTypes.h>
+#include <MailCore/MCAbstract.h>
+#include <MailCore/MCIMAPOperation.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class IMAPDisconnectOperation : public IMAPOperation {
+ public:
+ IMAPDisconnectOperation();
+ virtual ~IMAPDisconnectOperation();
+
+ public: // subclass behavior
+ virtual void main();
+ };
+}
+
+#endif
+
+#endif \ No newline at end of file
diff --git a/src/async/pop/MCPOPAsyncSession.cc b/src/async/pop/MCPOPAsyncSession.cc
index 39f356db..1269a34b 100644
--- a/src/async/pop/MCPOPAsyncSession.cc
+++ b/src/async/pop/MCPOPAsyncSession.cc
@@ -14,17 +14,44 @@
#include "MCPOPDeleteMessagesOperation.h"
#include "MCPOPFetchMessagesOperation.h"
#include "MCPOPCheckAccountOperation.h"
+#include "MCOperationQueueCallback.h"
using namespace mailcore;
+namespace mailcore {
+ class POPOperationQueueCallback : public Object, public OperationQueueCallback {
+ public:
+ POPOperationQueueCallback(POPAsyncSession * session) {
+ mSession = session;
+ }
+
+ virtual ~POPOperationQueueCallback() {
+ }
+
+ virtual void queueStartRunning() {
+ mSession->retain();
+ }
+
+ virtual void queueStoppedRunning() {
+ mSession->release();
+ }
+
+ private:
+ POPAsyncSession * mSession;
+ };
+}
+
POPAsyncSession::POPAsyncSession()
{
mSession = new POPSession();
mQueue = new OperationQueue();
+ mQueueCallback = new POPOperationQueueCallback(this);
+ mQueue->setCallback(mQueueCallback);
}
POPAsyncSession::~POPAsyncSession()
{
+ MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mSession);
MC_SAFE_RELEASE(mQueue);
}
@@ -164,6 +191,5 @@ POPSession * POPAsyncSession::session()
void POPAsyncSession::runOperation(POPOperation * operation)
{
-#warning disconnect after delay
mQueue->addOperation(operation);
}
diff --git a/src/async/pop/MCPOPAsyncSession.h b/src/async/pop/MCPOPAsyncSession.h
index 166675e0..452d4d75 100644
--- a/src/async/pop/MCPOPAsyncSession.h
+++ b/src/async/pop/MCPOPAsyncSession.h
@@ -22,7 +22,8 @@ namespace mailcore {
class POPFetchMessageOperation;
class POPDeleteMessagesOperation;
class POPFetchMessagesOperation;
-
+ class POPOperationQueueCallback;
+
class POPAsyncSession : public Object {
public:
POPAsyncSession();
@@ -68,6 +69,7 @@ namespace mailcore {
private:
POPSession * mSession;
OperationQueue * mQueue;
+ POPOperationQueueCallback * mQueueCallback;
public: // private
virtual void runOperation(POPOperation * operation);
diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc
index 95101a50..73bc2a54 100644
--- a/src/async/smtp/MCSMTPAsyncSession.cc
+++ b/src/async/smtp/MCSMTPAsyncSession.cc
@@ -1,22 +1,50 @@
#include "MCSMTPAsyncSession.h"
#include "MCSMTPSession.h"
-//#include "MCSMTPSendWithRecipientOperation.h"
#include "MCSMTPSendWithDataOperation.h"
-//#include "MCSMTPSendWithBuilderOperation.h"
#include "MCSMTPCheckAccountOperation.h"
+#include "MCSMTPDisconnectOperation.h"
#include "MCSMTPOperation.h"
+#include "MCOperationQueueCallback.h"
using namespace mailcore;
+namespace mailcore {
+ class SMTPOperationQueueCallback : public Object, public OperationQueueCallback {
+ public:
+ SMTPOperationQueueCallback(SMTPAsyncSession * session) {
+ mSession = session;
+ }
+
+ virtual ~SMTPOperationQueueCallback() {
+ }
+
+ virtual void queueStartRunning() {
+ mSession->retain();
+ }
+
+ virtual void queueStoppedRunning() {
+ mSession->tryAutomaticDisconnect();
+ mSession->release();
+ }
+
+ private:
+ SMTPAsyncSession * mSession;
+ };
+}
+
SMTPAsyncSession::SMTPAsyncSession()
{
mSession = new SMTPSession();
mQueue = new OperationQueue();
+ mQueueCallback = new SMTPOperationQueueCallback(this);
+ mQueue->setCallback(mQueueCallback);
}
SMTPAsyncSession::~SMTPAsyncSession()
{
+ cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL);
+ MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mQueue);
MC_SAFE_RELEASE(mSession);
}
@@ -113,7 +141,7 @@ bool SMTPAsyncSession::useHeloIPEnabled()
void SMTPAsyncSession::runOperation(SMTPOperation * operation)
{
-#warning disconnect after delay
+ cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL);
mQueue->addOperation(operation);
}
@@ -122,35 +150,31 @@ SMTPSession * SMTPAsyncSession::session()
return mSession;
}
-#if 0
-SMTPOperation * SMTPAsyncSession::sendMessageOperationWithFromAndRecipient(Address * from, Array * recipients, Data * messageData)
+void SMTPAsyncSession::tryAutomaticDisconnect()
{
- SMTPSendWithRecipientOperation * op = new SMTPSendWithRecipientOperation();
- op->setSession(this);
- op->setFrom(from);
- op->setRecipients(recipients);
- op->setMessageData(messageData);
- return (SMTPOperation *) op->autorelease();
+ // It's safe since no thread is running when this function is called.
+ if (mSession->isDisconnected()) {
+ return;
+ }
+
+ performMethodAfterDelay((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL, 30);
}
-#endif
-SMTPOperation * SMTPAsyncSession::sendMessageOperation(Data * messageData)
+void SMTPAsyncSession::tryAutomaticDisconnectAfterDelay(void * context)
{
- SMTPSendWithDataOperation * op = new SMTPSendWithDataOperation();
+ SMTPDisconnectOperation * op = new SMTPDisconnectOperation();
op->setSession(this);
- op->setMessageData(messageData);
- return (SMTPOperation *) op->autorelease();
+ op->autorelease();
+ op->start();
}
-#if 0
-SMTPOperation * SMTPAsyncSession::sendMessageOperation(MessageBuilder * msg)
+SMTPOperation * SMTPAsyncSession::sendMessageOperation(Data * messageData)
{
- SMTPSendWithBuilderOperation * op = new SMTPSendWithBuilderOperation();
+ SMTPSendWithDataOperation * op = new SMTPSendWithDataOperation();
op->setSession(this);
- op->setBuilder(msg);
+ op->setMessageData(messageData);
return (SMTPOperation *) op->autorelease();
}
-#endif
SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from)
{
@@ -159,4 +183,3 @@ SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from)
op->setSession(this);
return (SMTPOperation *) op->autorelease();
}
-
diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h
index 0be287af..9cd7a8f0 100644
--- a/src/async/smtp/MCSMTPAsyncSession.h
+++ b/src/async/smtp/MCSMTPAsyncSession.h
@@ -13,6 +13,7 @@ namespace mailcore {
class SMTPOperation;
class SMTPSession;
class Address;
+ class SMTPOperationQueueCallback;
class SMTPAsyncSession : public Object {
public:
@@ -52,13 +53,14 @@ namespace mailcore {
public: // private
virtual void runOperation(SMTPOperation * operation);
virtual SMTPSession * session();
+ virtual void tryAutomaticDisconnect();
private:
- SMTPSession * mSession;
- OperationQueue * mQueue;
-
- void queue(SMTPOperation * op);
-
+ SMTPSession * mSession;
+ OperationQueue * mQueue;
+ SMTPOperationQueueCallback * mQueueCallback;
+
+ virtual void tryAutomaticDisconnectAfterDelay(void * context);
};
}
diff --git a/src/async/smtp/MCSMTPDisconnectOperation.cc b/src/async/smtp/MCSMTPDisconnectOperation.cc
new file mode 100644
index 00000000..592ceb48
--- /dev/null
+++ b/src/async/smtp/MCSMTPDisconnectOperation.cc
@@ -0,0 +1,28 @@
+//
+// SMTPDisconnectOperation.cpp
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCSMTPDisconnectOperation.h"
+
+#include "MCSMTPAsyncSession.h"
+#include "MCSMTPSession.h"
+
+using namespace mailcore;
+
+SMTPDisconnectOperation::SMTPDisconnectOperation()
+{
+}
+
+SMTPDisconnectOperation::~SMTPDisconnectOperation()
+{
+}
+
+void SMTPDisconnectOperation::main()
+{
+ session()->session()->disconnect();
+ setError(ErrorCode::ErrorNone);
+}
diff --git a/src/async/smtp/MCSMTPDisconnectOperation.h b/src/async/smtp/MCSMTPDisconnectOperation.h
new file mode 100644
index 00000000..dacf72a6
--- /dev/null
+++ b/src/async/smtp/MCSMTPDisconnectOperation.h
@@ -0,0 +1,32 @@
+//
+// SMTPDisconnectOperation.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCSMTPDISCONNECTOPERATION_H_
+#define __MAILCORE_MCSMTPDISCONNECTOPERATION_H_
+
+#include <MailCore/MCBaseTypes.h>
+#include <MailCore/MCAbstract.h>
+#include <MailCore/MCSMTPOperation.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class SMTPDisconnectOperation : public SMTPOperation {
+ public:
+ SMTPDisconnectOperation();
+ virtual ~SMTPDisconnectOperation();
+
+ public: // subclass behavior
+ virtual void main();
+ };
+}
+
+#endif
+
+#endif \ No newline at end of file
diff --git a/src/async/smtp/MCSMTPOperation.cc b/src/async/smtp/MCSMTPOperation.cc
index 532c6ab4..e8211a24 100644
--- a/src/async/smtp/MCSMTPOperation.cc
+++ b/src/async/smtp/MCSMTPOperation.cc
@@ -82,4 +82,3 @@ void SMTPOperation::bodyProgressOnMainThread(void * ctx)
}
free(context);
}
-
diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h
index c06acd06..eb9e80f4 100644
--- a/src/core/abstract/MCMessageConstants.h
+++ b/src/core/abstract/MCMessageConstants.h
@@ -65,6 +65,7 @@ namespace mailcore {
IMAPMessagesRequestKindFullHeaders = 1 << 4,
IMAPMessagesRequestKindHeaderSubject = 1 << 5,
IMAPMessagesRequestKindGmailLabels = 1 << 6,
+ IMAPMessagesRequestKindGmailThreadID = 1 << 7,
};
enum IMAPFetchRequestType {
diff --git a/src/core/basetypes/MCMainThread.h b/src/core/basetypes/MCMainThread.h
index 31819a29..c9fe4e8d 100644
--- a/src/core/basetypes/MCMainThread.h
+++ b/src/core/basetypes/MCMainThread.h
@@ -5,9 +5,14 @@
#ifdef __cplusplus
namespace mailcore {
- void callOnMainThread(void (*)(void *), void * context);
- void callOnMainThreadAndWait(void (*)(void *), void * context);
- void callAfterDelay(void (*)(void *), void * context, double time);
+ void callOnMainThread(void (*)(void *), void * context);
+ void callOnMainThreadAndWait(void (*)(void *), void * context);
+
+ // Returns a "call" object.
+ void * callAfterDelay(void (*)(void *), void * context, double time);
+
+ // Pass the pointer returns by callAfterDelay() to cancel a delayed call.
+ void cancelDelayedCall(void * call);
}
#endif
diff --git a/src/core/basetypes/MCMainThread.mm b/src/core/basetypes/MCMainThread.mm
index 0bdc2ce1..4e9c6fc7 100644
--- a/src/core/basetypes/MCMainThread.mm
+++ b/src/core/basetypes/MCMainThread.mm
@@ -52,13 +52,18 @@ void mailcore::callOnMainThreadAndWait(void (* function)(void *), void * context
[caller release];
}
-void mailcore::callAfterDelay(void (* function)(void *), void * context, double time)
+void * mailcore::callAfterDelay(void (* function)(void *), void * context, double time)
{
LEPPPMainThreadCaller * caller;
caller = [[LEPPPMainThreadCaller alloc] init];
[caller setFunction:function];
[caller setContext:context];
[caller performSelector:@selector(call) withObject:nil afterDelay:time];
- [caller release];
+ return [caller autorelease];
}
+void mailcore::cancelDelayedCall(void * delayedCall)
+{
+ LEPPPMainThreadCaller * caller = (LEPPPMainThreadCaller *) delayedCall;
+ [NSObject cancelPreviousPerformRequestsWithTarget:caller selector:@selector(call) object:nil];
+}
diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc
index 32d51fc4..879c194f 100644
--- a/src/core/basetypes/MCObject.cc
+++ b/src/core/basetypes/MCObject.cc
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <typeinfo>
#include <cxxabi.h>
+#include <libetpan/libetpan.h>
#include "MCAutoreleasePool.h"
#include "MCString.h"
@@ -115,6 +116,26 @@ struct mainThreadCallData {
Object * obj;
void * context;
Object::Method method;
+ void * caller;
+};
+
+static pthread_once_t delayedPerformOnce = PTHREAD_ONCE_INIT;
+static chash * delayedPerformHash = NULL;
+
+static void reallyInitDelayedPerform()
+{
+ delayedPerformHash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
+}
+
+static void initDelayedPerform()
+{
+ pthread_once(&delayedPerformOnce, reallyInitDelayedPerform);
+}
+
+struct mainThreadCallKeyData {
+ Object * obj;
+ void * context;
+ Object::Method method;
};
static void performOnMainThread(void * info)
@@ -134,7 +155,7 @@ static void performOnMainThread(void * info)
free(data);
}
-static void callAfterDelay(void * info)
+static void performAfterDelay(void * info)
{
struct mainThreadCallData * data;
void * context;
@@ -146,6 +167,15 @@ static void callAfterDelay(void * info)
context = data->context;
method = data->method;
+ chashdatum key;
+ struct mainThreadCallKeyData keyData;
+ keyData.obj = obj;
+ keyData.context = context;
+ keyData.method = method;
+ key.data = &keyData;
+ key.len = sizeof(keyData);
+ chash_delete(delayedPerformHash, &key, NULL);
+
(obj->*method)(context);
free(data);
@@ -159,6 +189,7 @@ void Object::performMethodOnMainThread(Method method, void * context, bool waitU
data->obj = this;
data->context = context;
data->method = method;
+ data->caller = NULL;
if (waitUntilDone) {
callOnMainThreadAndWait(performOnMainThread, data);
@@ -170,12 +201,48 @@ void Object::performMethodOnMainThread(Method method, void * context, bool waitU
void Object::performMethodAfterDelay(Method method, void * context, double delay)
{
+ initDelayedPerform();
+
struct mainThreadCallData * data;
data = (struct mainThreadCallData *) calloc(sizeof(* data), 1);
data->obj = this;
data->context = context;
data->method = method;
+ data->caller = callAfterDelay(performAfterDelay, data, delay);
+
+ chashdatum key;
+ chashdatum value;
+ struct mainThreadCallKeyData keyData;
+ keyData.obj = this;
+ keyData.context = context;
+ keyData.method = method;
+ key.data = &keyData;
+ key.len = sizeof(keyData);
+ value.data = (void *) data;
+ value.len = 0;
+ chash_set(delayedPerformHash, &key, &value, NULL);
+}
+
+void Object::cancelDelayedPerformMethod(Method method, void * context)
+{
+ initDelayedPerform();
- callAfterDelay(performOnMainThread, data, delay);
+ int r;
+ chashdatum key;
+ chashdatum value;
+ struct mainThreadCallKeyData keyData;
+ keyData.obj = this;
+ keyData.context = context;
+ keyData.method = method;
+ key.data = &keyData;
+ key.len = sizeof(keyData);
+ r = chash_get(delayedPerformHash, &key, &value);
+ if (r < 0)
+ return;
+
+ chash_delete(delayedPerformHash, &key, NULL);
+ struct mainThreadCallData * data = (struct mainThreadCallData *) value.data;
+ cancelDelayedCall(data->caller);
+ free(data);
}
diff --git a/src/core/basetypes/MCObject.h b/src/core/basetypes/MCObject.h
index 0fd65d09..01812191 100644
--- a/src/core/basetypes/MCObject.h
+++ b/src/core/basetypes/MCObject.h
@@ -38,6 +38,7 @@ namespace mailcore {
virtual void performMethod(Method method, void * context);
virtual void performMethodOnMainThread(Method method, void * context, bool waitUntilDone = false);
virtual void performMethodAfterDelay(Method method, void * context, double delay);
+ virtual void cancelDelayedPerformMethod(Method method, void * context);
private:
pthread_mutex_t mLock;
diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc
index 72d0041d..e448c237 100644
--- a/src/core/basetypes/MCOperationQueue.cc
+++ b/src/core/basetypes/MCOperationQueue.cc
@@ -1,13 +1,15 @@
#include "MCOperationQueue.h"
+#include <libetpan/libetpan.h>
+
#include "MCOperation.h"
#include "MCOperationCallback.h"
+#include "MCOperationQueueCallback.h"
#include "MCMainThread.h"
#include "MCUtils.h"
#include "MCArray.h"
#include "MCLog.h"
#include "MCAutoreleasePool.h"
-#include <libetpan/libetpan.h>
using namespace mailcore;
@@ -21,6 +23,8 @@ OperationQueue::OperationQueue()
mStartSem = mailsem_new();
mStopSem = mailsem_new();
mWaitingFinishedSem = mailsem_new();
+ mQuitting = false;
+ mCallback = NULL;
}
OperationQueue::~OperationQueue()
@@ -153,6 +157,10 @@ void OperationQueue::stoppedOnMainThread(void * context)
mailsem_down(mStopSem);
mStarted = false;
+ if (mCallback) {
+ mCallback->queueStoppedRunning();
+ }
+
release(); // (2)
release(); // (3)
@@ -163,6 +171,10 @@ void OperationQueue::startThread()
if (mStarted)
return;
+ if (mCallback) {
+ mCallback->queueStartRunning();
+ }
+
retain(); // (3)
mQuitting = false;
mStarted = true;
@@ -181,6 +193,16 @@ unsigned int OperationQueue::count()
return count;
}
+void OperationQueue::setCallback(OperationQueueCallback * callback)
+{
+ mCallback = callback;
+}
+
+OperationQueueCallback * OperationQueue::callback()
+{
+ return mCallback;
+}
+
#if 0
void OperationQueue::waitUntilAllOperationsAreFinished()
{
diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h
index b9323dea..ddfe9de2 100644
--- a/src/core/basetypes/MCOperationQueue.h
+++ b/src/core/basetypes/MCOperationQueue.h
@@ -10,41 +10,46 @@
#ifdef __cplusplus
namespace mailcore {
-
- class Operation;
- class Array;
- class OperationQueue : public Object {
- public:
- OperationQueue();
- virtual ~OperationQueue();
-
- virtual void addOperation(Operation * op);
-
+ class Operation;
+ class OperationQueueCallback;
+ class Array;
+
+ class OperationQueue : public Object {
+ public:
+ OperationQueue();
+ virtual ~OperationQueue();
+
+ virtual void addOperation(Operation * op);
+
virtual unsigned int count();
- private:
- Array * mOperations;
- pthread_t mThreadID;
- bool mStarted;
- struct mailsem * mOperationSem;
- struct mailsem * mStartSem;
- struct mailsem * mStopSem;
- pthread_mutex_t mLock;
- bool mWaiting;
- struct mailsem * mWaitingFinishedSem;
- bool mQuitting;
+ virtual void setCallback(OperationQueueCallback * callback);
+ virtual OperationQueueCallback * callback();
- void startThread();
- static void runOperationsOnThread(OperationQueue * queue);
- void runOperations();
- void callbackOnMainThread(Operation * op);
- void checkRunningOnMainThread(void * context);
- void checkRunningAfterDelay(void * context);
+ private:
+ Array * mOperations;
+ pthread_t mThreadID;
+ bool mStarted;
+ struct mailsem * mOperationSem;
+ struct mailsem * mStartSem;
+ struct mailsem * mStopSem;
+ pthread_mutex_t mLock;
+ bool mWaiting;
+ struct mailsem * mWaitingFinishedSem;
+ bool mQuitting;
+ OperationQueueCallback * mCallback;
+
+ void startThread();
+ static void runOperationsOnThread(OperationQueue * queue);
+ void runOperations();
+ void callbackOnMainThread(Operation * op);
+ void checkRunningOnMainThread(void * context);
+ void checkRunningAfterDelay(void * context);
void stoppedOnMainThread(void * context);
-
- };
-
+
+ };
+
}
#endif
diff --git a/src/core/basetypes/MCOperationQueueCallback.h b/src/core/basetypes/MCOperationQueueCallback.h
new file mode 100644
index 00000000..367888bb
--- /dev/null
+++ b/src/core/basetypes/MCOperationQueueCallback.h
@@ -0,0 +1,23 @@
+//
+// MCOperationQueueCallback.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_OPERATIONQUEUECALLBACK_H_
+#define __MAILCORE_OPERATIONQUEUECALLBACK_H_
+
+namespace mailcore {
+
+ class OperationQueue;
+
+ class OperationQueueCallback {
+ public:
+ virtual void queueStartRunning() {}
+ virtual void queueStoppedRunning() {}
+ };
+}
+
+#endif
diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc
index 6f8a0dbb..f8b9f4e6 100644
--- a/src/core/imap/MCIMAPMessage.cc
+++ b/src/core/imap/MCIMAPMessage.cc
@@ -35,6 +35,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other)
setOriginalFlags(other->originalFlags());
setMainPart((AbstractPart *) other->mainPart()->copy()->autorelease());
setGmailLabels(other->gmailLabels());
+ setGmailThreadID(other->gmailThreadID());
}
IMAPMessage::~IMAPMessage()
@@ -121,6 +122,16 @@ Array * IMAPMessage::gmailLabels()
return mLabels;
}
+void IMAPMessage::setGmailThreadID(uint64_t threadID)
+{
+ mThreadID = threadID;
+}
+
+uint64_t IMAPMessage::gmailThreadID()
+{
+ return mThreadID;
+}
+
AbstractPart * IMAPMessage::partForPartID(String * partID)
{
return partForPartIDInPart(mainPart(), partID);
diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h
index 5a9cadcb..3c2ee9c0 100644
--- a/src/core/imap/MCIMAPMessage.h
+++ b/src/core/imap/MCIMAPMessage.h
@@ -10,33 +10,36 @@
#ifdef __cplusplus
namespace mailcore {
-
+
class IMAPPart;
class HTMLRendererIMAPCallback;
class HTMLRendererTemplateCallback;
- class IMAPMessage : public AbstractMessage {
- public:
- IMAPMessage();
- ~IMAPMessage();
-
- virtual uint32_t uid();
- virtual void setUid(uint32_t uid);
-
- virtual void setFlags(MessageFlag flags);
- virtual MessageFlag flags();
-
- virtual void setOriginalFlags(MessageFlag flags);
- virtual MessageFlag originalFlags();
-
- virtual uint64_t modSeqValue();
- virtual void setModSeqValue(uint64_t uid);
+ class IMAPMessage : public AbstractMessage {
+ public:
+ IMAPMessage();
+ ~IMAPMessage();
+
+ virtual uint32_t uid();
+ virtual void setUid(uint32_t uid);
+
+ virtual void setFlags(MessageFlag flags);
+ virtual MessageFlag flags();
+
+ virtual void setOriginalFlags(MessageFlag flags);
+ virtual MessageFlag originalFlags();
- virtual void setMainPart(AbstractPart * mainPart);
- virtual AbstractPart * mainPart();
-
- virtual void setGmailLabels(Array * /* String */ labels);
- virtual Array * /* String */ gmailLabels();
+ virtual uint64_t modSeqValue();
+ virtual void setModSeqValue(uint64_t uid);
+
+ virtual void setMainPart(AbstractPart * mainPart);
+ virtual AbstractPart * mainPart();
+
+ virtual void setGmailLabels(Array * /* String */ labels);
+ virtual Array * /* String */ gmailLabels();
+
+ virtual void setGmailThreadID(uint64_t threadID);
+ virtual uint64_t gmailThreadID();
virtual AbstractPart * partForPartID(String * partID);
@@ -48,20 +51,21 @@ namespace mailcore {
HTMLRendererTemplateCallback * htmlCallback = NULL);
public: // subclass behavior
- IMAPMessage(IMAPMessage * other);
- virtual Object * copy();
- virtual String * description();
+ IMAPMessage(IMAPMessage * other);
+ virtual Object * copy();
+ virtual String * description();
- private:
+ private:
uint64_t mModSeqValue;
- uint32_t mUid;
- MessageFlag mFlags;
- MessageFlag mOriginalFlags;
- AbstractPart * mMainPart;
- Array * /* String */ mLabels;
- void init();
- };
-
+ uint32_t mUid;
+ MessageFlag mFlags;
+ MessageFlag mOriginalFlags;
+ AbstractPart * mMainPart;
+ Array * /* String */ mLabels;
+ uint64_t mThreadID;
+ void init();
+ };
+
}
#endif
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index 52e819d9..254f9865 100644
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -514,6 +514,8 @@ void IMAPSession::unsetup()
mailimap_free(imap);
imap = NULL;
}
+
+ mState = STATE_DISCONNECTED;
}
void IMAPSession::connect(ErrorCode * pError)
@@ -1582,6 +1584,7 @@ struct msg_att_handler_data {
bool needsBody;
bool needsFlags;
bool needsGmailLabels;
+ bool needsGmailThreadID;
uint32_t startUid;
};
@@ -1594,6 +1597,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
bool hasBody;
bool hasFlags;
bool hasGmailLabels;
+ bool hasGmailThreadID;
struct msg_att_handler_data * msg_att_context;
// struct
IMAPSession * self;
@@ -1607,6 +1611,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
bool needsBody;
bool needsFlags;
bool needsGmailLabels;
+ bool needsGmailThreadID;
uint32_t startUid;
msg_att_context = (struct msg_att_handler_data *) context;
@@ -1621,13 +1626,15 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
needsBody = msg_att_context->needsBody;
needsFlags = msg_att_context->needsFlags;
needsGmailLabels = msg_att_context->needsGmailLabels;
+ needsGmailThreadID = msg_att_context->needsGmailThreadID;
startUid = msg_att_context->startUid;
hasHeader = false;
hasBody = false;
hasFlags = false;
hasGmailLabels = false;
-
+ hasGmailThreadID = false;
+
msg = new IMAPMessage();
uid = 0;
@@ -1718,6 +1725,13 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
}
labels->release();
}
+ else if (ext_data->ext_extension == &mailimap_extension_xgmthrid) {
+ uint64_t * threadID;
+
+ threadID = (uint64_t *) ext_data->ext_data;
+ msg->setGmailThreadID(*threadID);
+ hasGmailThreadID = true;
+ }
}
}
for(item_iter = clist_begin(msg_att->att_list) ; item_iter != NULL ; item_iter = clist_next(item_iter)) {
@@ -1752,7 +1766,10 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
msg->release();
return;
}
-
+ if (needsGmailThreadID && !hasGmailThreadID) {
+ msg->release();
+ return;
+ }
if (uid != 0) {
msg->setUid(uid);
}
@@ -1780,6 +1797,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest
bool needsBody;
bool needsFlags;
bool needsGmailLabels;
+ bool needsGmailThreadID;
Array * messages;
IndexSet * vanishedMessages;
@@ -1803,7 +1821,8 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest
needsBody = false;
needsFlags = false;
needsGmailLabels = false;
-
+ needsGmailThreadID = false;
+
fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
fetch_att = mailimap_fetch_att_new_uid();
mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
@@ -1819,6 +1838,11 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest
mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
needsGmailLabels = true;
}
+ if ((requestKind & IMAPMessagesRequestKindGmailThreadID) != 0) {
+ fetch_att = mailimap_fetch_att_new_xgmthrid();
+ mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
+ needsGmailThreadID = true;
+ }
if ((requestKind & IMAPMessagesRequestKindFullHeaders) != 0) {
clist * hdrlist;
char * header;
@@ -1908,7 +1932,7 @@ IMAPSyncResult * IMAPSession::fetchMessages(String * folder, IMAPMessagesRequest
msg_att_data.needsFlags = needsFlags;
msg_att_data.needsGmailLabels = needsGmailLabels;
msg_att_data.startUid = startUid;
-
+ msg_att_data.needsGmailThreadID = needsGmailThreadID;
mailimap_set_msg_att_handler(mImap, msg_att_handler, &msg_att_data);
mBodyProgressEnabled = false;
@@ -2912,3 +2936,7 @@ bool IMAPSession::isIdentityEnabled()
return mIdentityEnabled;
}
+bool IMAPSession::isDisconnected()
+{
+ return mState == STATE_DISCONNECTED;
+}
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 8531b050..c21c36cd 100644
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -5,92 +5,90 @@
#include <MailCore/MCBaseTypes.h>
#include <MailCore/MCMessageConstants.h>
-
-
#ifdef __cplusplus
namespace mailcore {
- extern String * IMAPNamespacePersonal;
- extern String * IMAPNamespaceOther;
- extern String * IMAPNamespaceShared;
+ extern String * IMAPNamespacePersonal;
+ extern String * IMAPNamespaceOther;
+ extern String * IMAPNamespaceShared;
- class IMAPNamespace;
- class IMAPSearchExpression;
- class IMAPFolder;
- class IMAPProgressCallback;
+ class IMAPNamespace;
+ class IMAPSearchExpression;
+ class IMAPFolder;
+ class IMAPProgressCallback;
class IMAPSyncResult;
class IMAPFolderStatus;
-
- class IMAPSession : public Object {
- public:
- IMAPSession();
- virtual ~IMAPSession();
-
- virtual void setHostname(String * hostname);
- virtual String * hostname();
+
+ class IMAPSession : public Object {
+ public:
+ IMAPSession();
+ virtual ~IMAPSession();
+
+ virtual void setHostname(String * hostname);
+ virtual String * hostname();
- virtual void setPort(unsigned int port);
- virtual unsigned int port();
+ virtual void setPort(unsigned int port);
+ virtual unsigned int port();
- virtual void setUsername(String * username);
- virtual String * username();
+ virtual void setUsername(String * username);
+ virtual String * username();
- virtual void setPassword(String * password);
- virtual String * password();
+ virtual void setPassword(String * password);
+ virtual String * password();
- virtual void setAuthType(AuthType authType);
- virtual AuthType authType();
+ virtual void setAuthType(AuthType authType);
+ virtual AuthType authType();
- virtual void setConnectionType(ConnectionType connectionType);
- virtual ConnectionType connectionType();
+ virtual void setConnectionType(ConnectionType connectionType);
+ virtual ConnectionType connectionType();
- virtual void setTimeout(time_t timeout);
- virtual time_t timeout();
-
- virtual void setCheckCertificateEnabled(bool enabled);
- virtual bool isCheckCertificateEnabled();
+ virtual void setTimeout(time_t timeout);
+ virtual time_t timeout();
- virtual void setVoIPEnabled(bool enabled);
- virtual bool isVoIPEnabled();
+ virtual void setCheckCertificateEnabled(bool enabled);
+ virtual bool isCheckCertificateEnabled();
+
+ virtual void setVoIPEnabled(bool enabled);
+ virtual bool isVoIPEnabled();
// Needed for fetchSubscribedFolders() and fetchAllFolders().
- virtual void setDelimiter(char delimiter);
- virtual char delimiter();
+ virtual void setDelimiter(char delimiter);
+ virtual char delimiter();
// Needed for fetchSubscribedFolders() and fetchAllFolders().
- virtual void setDefaultNamespace(IMAPNamespace * ns);
- virtual IMAPNamespace * defaultNamespace();
+ virtual void setDefaultNamespace(IMAPNamespace * ns);
+ virtual IMAPNamespace * defaultNamespace();
- virtual void select(String * folder, ErrorCode * pError);
+ virtual void select(String * folder, ErrorCode * pError);
virtual IMAPFolderStatus * folderStatus(String * folder, ErrorCode * pError);
-
- virtual Array * /* IMAPFolder */ fetchSubscribedFolders(ErrorCode * pError);
- virtual Array * /* IMAPFolder */ fetchAllFolders(ErrorCode * pError); // will use xlist if available
- virtual void renameFolder(String * folder, String * otherName, ErrorCode * pError);
- virtual void deleteFolder(String * folder, ErrorCode * pError);
- virtual void createFolder(String * folder, ErrorCode * pError);
+ virtual Array * /* IMAPFolder */ fetchSubscribedFolders(ErrorCode * pError);
+ virtual Array * /* IMAPFolder */ fetchAllFolders(ErrorCode * pError); // will use xlist if available
+
+ virtual void renameFolder(String * folder, String * otherName, ErrorCode * pError);
+ virtual void deleteFolder(String * folder, ErrorCode * pError);
+ virtual void createFolder(String * folder, ErrorCode * pError);
- virtual void subscribeFolder(String * folder, ErrorCode * pError);
- virtual void unsubscribeFolder(String * folder, ErrorCode * pError);
+ virtual void subscribeFolder(String * folder, ErrorCode * pError);
+ virtual void unsubscribeFolder(String * folder, ErrorCode * pError);
- virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags,
+ virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags,
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
-
- virtual void copyMessages(String * folder, IndexSet * uidSet, String * destFolder,
+
+ virtual void copyMessages(String * folder, IndexSet * uidSet, String * destFolder,
IndexSet ** pDestUIDs, ErrorCode * pError);
-
- virtual void expunge(String * folder, ErrorCode * pError);
-
- virtual Array * /* IMAPMessage */ fetchMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind,
+
+ virtual void expunge(String * folder, ErrorCode * pError);
+
+ virtual Array * /* IMAPMessage */ fetchMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind,
IndexSet * uids, IMAPProgressCallback * progressCallback, ErrorCode * pError);
- virtual Array * /* IMAPMessage */ fetchMessagesByNumber(String * folder, IMAPMessagesRequestKind requestKind,
+ virtual Array * /* IMAPMessage */ fetchMessagesByNumber(String * folder, IMAPMessagesRequestKind requestKind,
IndexSet * numbers, IMAPProgressCallback * progressCallback, ErrorCode * pError);
- virtual Data * fetchMessageByUID(String * folder, uint32_t uid,
+ virtual Data * fetchMessageByUID(String * folder, uint32_t uid,
IMAPProgressCallback * progressCallback, ErrorCode * pError);
- virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID,
+ virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID,
Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError);
virtual HashMap * fetchMessageNumberUIDMapping(String * folder, uint32_t fromUID, uint32_t toUID,
ErrorCode * pError);
@@ -100,94 +98,95 @@ namespace mailcore {
IndexSet * uids, uint64_t modseq,
IMAPProgressCallback * progressCallback, ErrorCode * pError);
- virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError);
- virtual void storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError);
-
- virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError);
- virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError);
-
- virtual bool setupIdle();
- virtual void idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError);
- virtual void interruptIdle();
- virtual void unsetupIdle();
-
- virtual void connect(ErrorCode * pError);
- virtual void disconnect();
-
- virtual HashMap * fetchNamespace(ErrorCode * pError);
-
- virtual void login(ErrorCode * pError);
-
- virtual HashMap * identity(String * vendor, String * name, String * version, ErrorCode * pError);
+ virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError);
+ virtual void storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError);
+
+ virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError);
+ virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError);
+
+ virtual bool setupIdle();
+ virtual void idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError);
+ virtual void interruptIdle();
+ virtual void unsetupIdle();
+
+ virtual void connect(ErrorCode * pError);
+ virtual void disconnect();
+
+ virtual HashMap * fetchNamespace(ErrorCode * pError);
+
+ virtual void login(ErrorCode * pError);
+
+ virtual HashMap * identity(String * vendor, String * name, String * version, ErrorCode * pError);
virtual IndexSet * capability(ErrorCode * pError);
- virtual uint32_t uidValidity();
- virtual uint32_t uidNext();
+ virtual uint32_t uidValidity();
+ virtual uint32_t uidNext();
virtual uint64_t modSequenceValue();
- virtual unsigned int lastFolderMessageCount();
+ virtual unsigned int lastFolderMessageCount();
virtual uint32_t firstUnseenUid();
- virtual bool isIdleEnabled();
- virtual bool isXListEnabled();
- virtual bool isCondstoreEnabled();
- virtual bool isQResyncEnabled();
- virtual bool isIdentityEnabled();
+ virtual bool isIdleEnabled();
+ virtual bool isXListEnabled();
+ virtual bool isCondstoreEnabled();
+ virtual bool isQResyncEnabled();
+ virtual bool isIdentityEnabled();
public: // private
- virtual void loginIfNeeded(ErrorCode * pError);
- virtual void connectIfNeeded(ErrorCode * pError);
-
- private:
- String * mHostname;
- unsigned int mPort;
- String * mUsername;
- String * mPassword;
- AuthType mAuthType;
- ConnectionType mConnectionType;
- bool mCheckCertificateEnabled;
- bool mVoIPEnabled;
- char mDelimiter;
- IMAPNamespace * mDefaultNamespace;
- time_t mTimeout;
-
- bool mBodyProgressEnabled;
- bool mIdleEnabled;
- bool mXListEnabled;
- bool mCondstoreEnabled;
- bool mQResyncEnabled;
- bool mIdentityEnabled;
- String * mWelcomeString;
- bool mNeedsMboxMailWorkaround;
- uint32_t mUIDValidity;
- uint32_t mUIDNext;
- uint64_t mModSequenceValue;
- unsigned int mFolderMsgCount;
- uint32_t mFirstUnseenUid;
-
- unsigned int mLastFetchedSequenceNumber;
- String * mCurrentFolder;
- pthread_mutex_t mIdleLock;
- bool mCanIdle;
- int mState;
- mailimap * mImap;
- IMAPProgressCallback * mProgressCallback;
- unsigned int mProgressItemsCount;
-
- void init();
- void bodyProgress(unsigned int current, unsigned int maximum);
- void itemsProgress(unsigned int current, unsigned int maximum);
- bool checkCertificate();
- static void body_progress(size_t current, size_t maximum, void * context);
- static void items_progress(size_t current, size_t maximum, void * context);
- void setup();
- void unsetup();
- void selectIfNeeded(String * folder, ErrorCode * pError);
- char fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError);
- IMAPSyncResult * fetchMessages(String * folder, IMAPMessagesRequestKind requestKind, bool fetchByUID,
+ virtual void loginIfNeeded(ErrorCode * pError);
+ virtual void connectIfNeeded(ErrorCode * pError);
+ virtual bool isDisconnected();
+
+ private:
+ String * mHostname;
+ unsigned int mPort;
+ String * mUsername;
+ String * mPassword;
+ AuthType mAuthType;
+ ConnectionType mConnectionType;
+ bool mCheckCertificateEnabled;
+ bool mVoIPEnabled;
+ char mDelimiter;
+ IMAPNamespace * mDefaultNamespace;
+ time_t mTimeout;
+
+ bool mBodyProgressEnabled;
+ bool mIdleEnabled;
+ bool mXListEnabled;
+ bool mCondstoreEnabled;
+ bool mQResyncEnabled;
+ bool mIdentityEnabled;
+ String * mWelcomeString;
+ bool mNeedsMboxMailWorkaround;
+ uint32_t mUIDValidity;
+ uint32_t mUIDNext;
+ uint64_t mModSequenceValue;
+ unsigned int mFolderMsgCount;
+ uint32_t mFirstUnseenUid;
+
+ unsigned int mLastFetchedSequenceNumber;
+ String * mCurrentFolder;
+ pthread_mutex_t mIdleLock;
+ bool mCanIdle;
+ int mState;
+ mailimap * mImap;
+ IMAPProgressCallback * mProgressCallback;
+ unsigned int mProgressItemsCount;
+
+ void init();
+ void bodyProgress(unsigned int current, unsigned int maximum);
+ void itemsProgress(unsigned int current, unsigned int maximum);
+ bool checkCertificate();
+ static void body_progress(size_t current, size_t maximum, void * context);
+ static void items_progress(size_t current, size_t maximum, void * context);
+ void setup();
+ void unsetup();
+ void selectIfNeeded(String * folder, ErrorCode * pError);
+ char fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError);
+ IMAPSyncResult * fetchMessages(String * folder, IMAPMessagesRequestKind requestKind, bool fetchByUID,
struct mailimap_set * imapset, uint64_t modseq, HashMap * mapping, uint32_t startUid,
IMAPProgressCallback * progressCallback, ErrorCode * pError);
- };
+ };
}
#endif
diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc
index fd5832f3..ee225b16 100644
--- a/src/core/smtp/MCSMTPSession.cc
+++ b/src/core/smtp/MCSMTPSession.cc
@@ -44,12 +44,10 @@ SMTPSession::SMTPSession()
SMTPSession::~SMTPSession()
{
- MCLog("dealloc");
MC_SAFE_RELEASE(mLastSMTPResponse);
MC_SAFE_RELEASE(mHostname);
MC_SAFE_RELEASE(mUsername);
MC_SAFE_RELEASE(mPassword);
- MCLog("dealloc4");
}
void SMTPSession::setHostname(String * hostname)
@@ -679,3 +677,7 @@ void SMTPSession::sendMessage(MessageBuilder * msg, SMTPProgressCallback * callb
recipients->release();
}
+bool SMTPSession::isDisconnected()
+{
+ return mState == STATE_DISCONNECTED;
+}
diff --git a/src/core/smtp/MCSMTPSession.h b/src/core/smtp/MCSMTPSession.h
index 70237c16..57c6e0ce 100644
--- a/src/core/smtp/MCSMTPSession.h
+++ b/src/core/smtp/MCSMTPSession.h
@@ -85,6 +85,9 @@ namespace mailcore {
void sendMessage(Address * from, Array * /* Address */ recipients, Data * messageData,
SMTPProgressCallback * callback, ErrorCode * pError);
void sendMessage(MessageBuilder * msg, SMTPProgressCallback * callback, ErrorCode * pError);
+
+ public: // private
+ virtual bool isDisconnected();
};
}
diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h
index 6f9dd446..8b73aeaf 100644
--- a/src/objc/abstract/MCOConstants.h
+++ b/src/objc/abstract/MCOConstants.h
@@ -134,6 +134,8 @@ typedef enum {
MCOIMAPMessagesRequestKindHeaderSubject = 1 << 5,
/** Gmail Labels.*/
MCOIMAPMessagesRequestKindGmailLabels = 1 << 6,
+ /** Gmail Thread ID.*/
+ MCOIMAPMessagesRequestKindGmailThreadID = 1 << 7,
} MCOIMAPMessagesRequestKind;
/** It defines the behavior of the STORE flags request.*/
diff --git a/src/objc/imap/MCOIMAPBaseOperation+Private.h b/src/objc/imap/MCOIMAPBaseOperation+Private.h
new file mode 100644
index 00000000..e744355a
--- /dev/null
+++ b/src/objc/imap/MCOIMAPBaseOperation+Private.h
@@ -0,0 +1,20 @@
+//
+// Header.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCOIMAPBASEOPERATION_PRIVATE_H_
+#define __MAILCORE_MCOIMAPBASEOPERATION_PRIVATE_H_
+
+@class MCOIMAPSession;
+
+@interface MCOIMAPBaseOperation (Private)
+
+@property (nonatomic, retain) MCOIMAPSession * session;
+
+@end
+
+#endif
diff --git a/src/objc/imap/MCOIMAPBaseOperation.mm b/src/objc/imap/MCOIMAPBaseOperation.mm
index be398ece..ed67e34e 100644
--- a/src/objc/imap/MCOIMAPBaseOperation.mm
+++ b/src/objc/imap/MCOIMAPBaseOperation.mm
@@ -7,10 +7,12 @@
//
#import "MCOIMAPBaseOperation.h"
+#import "MCOIMAPBaseOperation+Private.h"
#import "MCOOperation+Private.h"
#import "MCAsyncIMAP.h"
+#import "MCOIMAPSession.h"
class MCOIMAPBaseOperationIMAPCallback : public mailcore::IMAPOperationCallback {
public:
@@ -33,6 +35,7 @@ private:
@implementation MCOIMAPBaseOperation {
MCOIMAPBaseOperationIMAPCallback * _imapCallback;
+ MCOIMAPSession * _session;
}
- (id) initWithMCOperation:(mailcore::Operation *)op
@@ -47,10 +50,22 @@ private:
- (void) dealloc
{
+ [_session release];
delete _imapCallback;
[super dealloc];
}
+- (void) setSession:(MCOIMAPSession *)session
+{
+ [_session release];
+ _session = [session retain];
+}
+
+- (MCOIMAPSession *) session
+{
+ return _session;
+}
+
- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
{
}
diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h
index c6d8595b..ab9771ca 100644
--- a/src/objc/imap/MCOIMAPMessage.h
+++ b/src/objc/imap/MCOIMAPMessage.h
@@ -49,6 +49,9 @@
/** All Gmail labels of the message */
@property (nonatomic, copy) NSArray * /* NSString */ gmailLabels;
+/** Gmail thread iD of the message */
+@property (nonatomic, assign) uint64_t gmailThreadID;
+
/**
Returns the part with the given part identifier.
@param partID A part identifier looks like 1.2.1
diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm
index 9984443e..b5845bc2 100644
--- a/src/objc/imap/MCOIMAPMessage.mm
+++ b/src/objc/imap/MCOIMAPMessage.mm
@@ -47,6 +47,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFla
MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setModSeqValue, modSeqValue)
MCO_OBJC_SYNTHESIZE(AbstractPart, setMainPart, mainPart)
MCO_OBJC_SYNTHESIZE_ARRAY(setGmailLabels, gmailLabels)
+MCO_OBJC_SYNTHESIZE_SCALAR(uint64_t, uint64_t, setGmailThreadID, gmailThreadID)
- (MCOAbstractPart *) partForPartID:(NSString *)partID
{
diff --git a/src/objc/imap/MCOIMAPOperation.h b/src/objc/imap/MCOIMAPOperation.h
index b8ee37e4..6f286596 100644
--- a/src/objc/imap/MCOIMAPOperation.h
+++ b/src/objc/imap/MCOIMAPOperation.h
@@ -12,9 +12,9 @@
/** This class implements a generic IMAP operation */
-#import <MailCore/MCOOperation.h>
+#import <MailCore/MCOIMAPBaseOperation.h>
-@interface MCOIMAPOperation : MCOOperation
+@interface MCOIMAPOperation : MCOIMAPBaseOperation
/**
Starts the asynchronous append operation.
diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm
index a13724ae..a8df8aed 100644
--- a/src/objc/imap/MCOIMAPSession.mm
+++ b/src/objc/imap/MCOIMAPSession.mm
@@ -13,6 +13,7 @@
#import "MCOObjectWrapper.h"
#import "MCOIMAPOperation.h"
#import "MCOIMAPFetchFoldersOperation.h"
+#import "MCOIMAPBaseOperation+Private.h"
#import "MCOUtils.h"
@@ -60,57 +61,74 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
#pragma mark - Operations
+#define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op];
+#define OPAQUE_OPERATION(op) [self _objcOpaqueOperationFromNativeOp:op]
+
+- (id) _objcOperationFromNativeOp:(IMAPOperation *)op
+{
+ MCOIMAPBaseOperation * result = MCO_TO_OBJC(op);
+ [result setSession:self];
+ return result;
+}
+
+- (id) _objcOpaqueOperationFromNativeOp:(IMAPOperation *)op
+{
+ MCOIMAPOperation * result = [[[MCOIMAPOperation alloc] initWithMCOperation:op] autorelease];
+ [result setSession:self];
+ return result;
+}
+
- (MCOIMAPFolderInfoOperation *) folderInfoOperation:(NSString *)folder
{
IMAPFolderInfoOperation * coreOp = MCO_NATIVE_INSTANCE->folderInfoOperation([folder mco_mcString]);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFolderStatusOperation *) folderStatusOperation:(NSString *)folder
{
IMAPFolderStatusOperation * coreOp = MCO_NATIVE_INSTANCE->folderStatusOperation([folder mco_mcString]);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchFoldersOperation *) fetchSubscribedFoldersOperation
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->fetchSubscribedFoldersOperation();
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchFoldersOperation *)fetchAllFoldersOperation {
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->fetchAllFoldersOperation();
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPOperation *) renameFolderOperation:(NSString *)folder otherName:(NSString *)otherName
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->renameFolderOperation([folder mco_mcString], [otherName mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPOperation *) deleteFolderOperation:(NSString *)folder
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->deleteFolderOperation([folder mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPOperation *) createFolderOperation:(NSString *)folder
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->createFolderOperation([folder mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPOperation *) subscribeFolderOperation:(NSString *)folder
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->subscribeFolderOperation([folder mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPOperation *) unsubscribeFolderOperation:(NSString *)folder
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->unsubscribeFolderOperation([folder mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPAppendMessageOperation *)appendMessageOperationWithFolder:(NSString *)folder
@@ -120,7 +138,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPAppendMessageOperation * coreOp = MCO_NATIVE_INSTANCE->appendMessageOperation([folder mco_mcString],
[messageData mco_mcData],
(MessageFlag) flags);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPCopyMessagesOperation *)copyMessagesOperationWithFolder:(NSString *)folder
@@ -130,14 +148,14 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPCopyMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->copyMessagesOperation([folder mco_mcString],
MCO_FROM_OBJC(IndexSet, uids),
[destFolder mco_mcString]);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPOperation *) expungeOperation:(NSString *)folder
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->expungeOperation([folder mco_mcString]);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPFetchMessagesOperation *) fetchMessagesByUIDOperationWithFolder:(NSString *)folder
@@ -147,7 +165,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesByUIDOperation([folder mco_mcString],
(IMAPMessagesRequestKind) requestKind,
MCO_FROM_OBJC(IndexSet, uids));
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchMessagesOperation *) fetchMessagesByNumberOperationWithFolder:(NSString *)folder
@@ -157,7 +175,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesByNumberOperation([folder mco_mcString],
(IMAPMessagesRequestKind) requestKind,
MCO_FROM_OBJC(IndexSet, numbers));
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchMessagesOperation *) syncMessagesByUIDWithFolder:(NSString *)folder
@@ -169,7 +187,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
(IMAPMessagesRequestKind) requestKind,
MCO_FROM_OBJC(IndexSet, uids),
modSeq);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder
@@ -177,7 +195,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
urgent:(BOOL)urgent
{
IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageByUIDOperation([folder mco_mcString], uid, urgent);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder
@@ -197,7 +215,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
[partID mco_mcString],
(Encoding) encoding,
urgent);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder
@@ -217,7 +235,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
MCO_FROM_OBJC(IndexSet, uids),
(IMAPStoreFlagsRequestKind) kind,
(MessageFlag) flags);
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPOperation *) storeLabelsOperationWithFolder:(NSString *)folder
@@ -229,7 +247,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
MCO_FROM_OBJC(IndexSet, uids),
(IMAPStoreFlagsRequestKind) kind,
MCO_FROM_OBJC(Array, labels));
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPSearchOperation *) searchOperationWithFolder:(NSString *)folder
@@ -239,7 +257,7 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPSearchOperation * coreOp = MCO_NATIVE_INSTANCE->searchOperation([folder mco_mcString],
(IMAPSearchKind) kind,
[searchString mco_mcString]);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPSearchOperation *) searchExpressionOperationWithFolder:(NSString *)folder
@@ -247,20 +265,20 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
{
IMAPSearchOperation * coreOp = MCO_NATIVE_INSTANCE->searchOperation([folder mco_mcString],
MCO_FROM_OBJC(IMAPSearchExpression, expression));
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPIdleOperation *) idleOperationWithFolder:(NSString *)folder
lastKnownUID:(uint32_t)lastKnownUID
{
IMAPIdleOperation * coreOp = MCO_NATIVE_INSTANCE->idleOperation([folder mco_mcString], lastKnownUID);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPFetchNamespaceOperation *) fetchNamespaceOperation
{
IMAPFetchNamespaceOperation * coreOp = MCO_NATIVE_INSTANCE->fetchNamespaceOperation();
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPIdentityOperation *) identityOperationWithVendor:(NSString *)vendor
@@ -270,19 +288,19 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
IMAPIdentityOperation * coreOp = MCO_NATIVE_INSTANCE->identityOperation([vendor mco_mcString],
[name mco_mcString],
[version mco_mcString]);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOIMAPOperation *)checkAccountOperation
{
IMAPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation();
- return [[[MCOIMAPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOIMAPCapabilityOperation *) capabilityOperation
{
IMAPCapabilityOperation * coreOp = MCO_NATIVE_INSTANCE->capabilityOperation();
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
@end
diff --git a/src/objc/pop/MCOPOPOperation+Private.h b/src/objc/pop/MCOPOPOperation+Private.h
new file mode 100644
index 00000000..1d888f08
--- /dev/null
+++ b/src/objc/pop/MCOPOPOperation+Private.h
@@ -0,0 +1,20 @@
+//
+// MCOPOPOperation+Private.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCOPOPOPERATION_PRIVATE_H_
+#define __MAILCORE_MCOPOPOPERATION_PRIVATE_H_
+
+@class MCOPOPSession;
+
+@interface MCOPOPOperation (Private)
+
+@property (nonatomic, retain) MCOPOPSession * session;
+
+@end
+
+#endif
diff --git a/src/objc/pop/MCOPOPOperation.mm b/src/objc/pop/MCOPOPOperation.mm
index 7bb17bb8..9b58f84d 100644
--- a/src/objc/pop/MCOPOPOperation.mm
+++ b/src/objc/pop/MCOPOPOperation.mm
@@ -12,17 +12,20 @@
#import "MCOUtils.h"
#import "MCOOperation+Private.h"
+#import "MCOPOPSession.h"
typedef void (^CompletionType)(NSError *error);
@implementation MCOPOPOperation {
CompletionType _completionBlock;
+ MCOPOPSession * _session;
}
#define nativeType mailcore::POPOperation
- (void) dealloc
{
+ [_session release];
[_completionBlock release];
[super dealloc];
}
@@ -40,5 +43,15 @@ typedef void (^CompletionType)(NSError *error);
_completionBlock(error);
}
+- (void) setSession:(MCOPOPSession *)session
+{
+ [_session release];
+ _session = [session retain];
+}
+
+- (MCOPOPSession *) session
+{
+ return _session;
+}
@end
diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm
index 10806937..11f7cad6 100644
--- a/src/objc/pop/MCOPOPSession.mm
+++ b/src/objc/pop/MCOPOPSession.mm
@@ -14,6 +14,7 @@
#import "MCOPOPOperation.h"
#import "MCOOperation+Private.h"
#import "MCOPOPFetchMessagesOperation.h"
+#import "MCOPOPOperation+Private.h"
@implementation MCOPOPSession {
mailcore::POPAsyncSession * _session;
@@ -55,41 +56,59 @@ MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled)
#pragma mark - Operations
+
+#define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op];
+#define OPAQUE_OPERATION(op) [self _objcOpaqueOperationFromNativeOp:op]
+
+- (id) _objcOperationFromNativeOp:(mailcore::POPOperation *)op
+{
+ MCOPOPOperation * result = MCO_TO_OBJC(op);
+ [result setSession:self];
+ return result;
+}
+
+- (id) _objcOpaqueOperationFromNativeOp:(mailcore::POPOperation *)op
+{
+ MCOPOPOperation * result = [[[MCOPOPOperation alloc] initWithMCOperation:op] autorelease];
+ [result setSession:self];
+ return result;
+}
+
- (MCOPOPFetchMessagesOperation *) fetchMessagesOperation
{
mailcore::POPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesOperation();
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOPOPFetchHeaderOperation *) fetchHeaderOperationWithIndex:(unsigned int)index
{
mailcore::POPFetchHeaderOperation * coreOp = MCO_NATIVE_INSTANCE->fetchHeaderOperation(index);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
- (MCOPOPFetchMessageOperation *) fetchMessageOperationWithIndex:(unsigned int)index;
{
mailcore::POPFetchMessageOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageOperation(index);
- return MCO_TO_OBJC(coreOp);
+ return MCO_TO_OBJC_OP(coreOp);
}
// Will disconnect.
- (MCOPOPOperation *) deleteMessagesOperationWithIndexes:(MCOIndexSet *)indexes
{
mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->deleteMessagesOperation(MCO_FROM_OBJC(mailcore::IndexSet, indexes));
- return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOPOPOperation *) disconnectOperation
{
mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->disconnectOperation();
- return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
- (MCOPOPOperation *) checkAccountOperation
{
mailcore::POPOperation * coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation();
- return [[[MCOPOPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ return OPAQUE_OPERATION(coreOp);
}
@end
diff --git a/src/objc/smtp/MCOSMTPOperation+Private.h b/src/objc/smtp/MCOSMTPOperation+Private.h
new file mode 100644
index 00000000..5b9b5ee9
--- /dev/null
+++ b/src/objc/smtp/MCOSMTPOperation+Private.h
@@ -0,0 +1,20 @@
+//
+// MCOSMTPOperation+Private.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 6/22/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCOSMTPOPERATION_PRIVATE_H_
+#define __MAILCORE_MCOSMTPOPERATION_PRIVATE_H_
+
+@class MCOSMTPSession;
+
+@interface MCOSMTPOperation (Private)
+
+@property (nonatomic, retain) MCOSMTPSession * session;
+
+@end
+
+#endif
diff --git a/src/objc/smtp/MCOSMTPOperation.mm b/src/objc/smtp/MCOSMTPOperation.mm
index d95c434d..cd52ad13 100644
--- a/src/objc/smtp/MCOSMTPOperation.mm
+++ b/src/objc/smtp/MCOSMTPOperation.mm
@@ -12,17 +12,20 @@
#import "MCOUtils.h"
#import "MCOOperation+Private.h"
+#import "MCOSMTPSession.h"
typedef void (^CompletionType)(NSError *error);
@implementation MCOSMTPOperation {
CompletionType _completionBlock;
+ MCOSMTPSession * _session;
}
#define nativeType mailcore::SMTPOperation
- (void) dealloc
{
+ [_session release];
[_completionBlock release];
[super dealloc];
}
@@ -40,4 +43,15 @@ typedef void (^CompletionType)(NSError *error);
_completionBlock(error);
}
+- (void) setSession:(MCOSMTPSession *)session
+{
+ [_session release];
+ _session = [session retain];
+}
+
+- (MCOSMTPSession *) session
+{
+ return _session;
+}
+
@end
diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm
index ad8f212e..de6b54cd 100644
--- a/src/objc/smtp/MCOSMTPSession.mm
+++ b/src/objc/smtp/MCOSMTPSession.mm
@@ -15,6 +15,7 @@
#import "MCOSMTPOperation.h"
#import "MCOOperation+Private.h"
#import "MCOAddress.h"
+#import "MCOSMTPOperation+Private.h"
@implementation MCOSMTPSession {
mailcore::SMTPAsyncSession * _session;
@@ -55,13 +56,17 @@ MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled)
- (MCOSMTPSendOperation *) sendOperationWithData:(NSData *)messageData
{
mailcore::SMTPOperation * coreOp = MCO_NATIVE_INSTANCE->sendMessageOperation([messageData mco_mcData]);
- return [[[MCOSMTPSendOperation alloc] initWithMCOperation:coreOp] autorelease];
+ MCOSMTPSendOperation * result = [[[MCOSMTPSendOperation alloc] initWithMCOperation:coreOp] autorelease];
+ [result setSession:self];
+ return result;
}
- (MCOOperation *) checkAccountOperationWithFrom:(MCOAddress *)from
{
mailcore::SMTPOperation *coreOp = MCO_NATIVE_INSTANCE->checkAccountOperation(MCO_FROM_OBJC(mailcore::Address, from));
- return [[[MCOSMTPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ MCOSMTPOperation * result = [[[MCOSMTPOperation alloc] initWithMCOperation:coreOp] autorelease];
+ [result setSession:self];
+ return result;
}
@end