aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/async
diff options
context:
space:
mode:
authorGravatar Michael Lenaghan <michaell@dazzit.com>2014-10-24 17:56:49 -0400
committerGravatar Michael Lenaghan <michaell@dazzit.com>2014-10-24 20:33:20 -0400
commitec1da36eaf2adfb5695f5c0d8ca92d23d31b56a5 (patch)
tree3c57763f4b3fe597a0d28f70d3634b36542dc663 /src/async
parentd0b53a64bdbeaa71d80210640534abea1a85f8d2 (diff)
Add an operation to fetch a parsed message.
This avoids the copying of Data to NSData to Data which happens with the current approach. In one test case, a message with an ~18 MB attachment, the current (copying) approach peaked at ~150 MB of memory usage in my app. This new approach peaks at ~65 MB. Another test case, which often caused iOS to terminate my app, now peaks at ~90 MB. In addition to the improved memory usage this approach also means that message parsing is performed asynchronously.
Diffstat (limited to 'src/async')
-rwxr-xr-xsrc/async/imap/MCAsyncIMAP.h1
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.cc36
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.h1
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.cc32
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.h4
-rw-r--r--src/async/imap/MCIMAPFetchParsedContentOperation.cc79
-rw-r--r--src/async/imap/MCIMAPFetchParsedContentOperation.h53
7 files changed, 183 insertions, 23 deletions
diff --git a/src/async/imap/MCAsyncIMAP.h b/src/async/imap/MCAsyncIMAP.h
index da032c73..15c9e482 100755
--- a/src/async/imap/MCAsyncIMAP.h
+++ b/src/async/imap/MCAsyncIMAP.h
@@ -17,6 +17,7 @@
#include <MailCore/MCIMAPCopyMessagesOperation.h>
#include <MailCore/MCIMAPFetchMessagesOperation.h>
#include <MailCore/MCIMAPFetchContentOperation.h>
+#include <MailCore/MCIMAPFetchParsedContentOperation.h>
#include <MailCore/MCIMAPIdleOperation.h>
#include <MailCore/MCIMAPFolderInfoOperation.h>
#include <MailCore/MCIMAPFolderStatusOperation.h>
diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc
index 3a6508d6..b2fc24c3 100755
--- a/src/async/imap/MCIMAPAsyncConnection.cc
+++ b/src/async/imap/MCIMAPAsyncConnection.cc
@@ -21,7 +21,7 @@
#include "MCIMAPCopyMessagesOperation.h"
#include "MCIMAPFetchMessagesOperation.h"
#include "MCIMAPFetchContentOperation.h"
-#include "MCIMAPFetchContentOperation.h"
+#include "MCIMAPFetchParsedContentOperation.h"
#include "MCIMAPStoreFlagsOperation.h"
#include "MCIMAPStoreLabelsOperation.h"
#include "MCIMAPSearchOperation.h"
@@ -43,51 +43,51 @@
using namespace mailcore;
namespace mailcore {
-
+
class IMAPOperationQueueCallback : public Object, public OperationQueueCallback {
public:
IMAPOperationQueueCallback(IMAPAsyncConnection * connection) {
mConnection = connection;
}
-
+
virtual ~IMAPOperationQueueCallback() {
}
-
+
virtual void queueStartRunning() {
mConnection->setQueueRunning(true);
mConnection->owner()->operationRunningStateChanged();
mConnection->queueStartRunning();
}
-
+
virtual void queueStoppedRunning() {
mConnection->setQueueRunning(false);
mConnection->tryAutomaticDisconnect();
mConnection->owner()->operationRunningStateChanged();
mConnection->queueStoppedRunning();
}
-
+
private:
IMAPAsyncConnection * mConnection;
};
-
+
class IMAPConnectionLogger : public Object, public ConnectionLogger {
public:
IMAPConnectionLogger(IMAPAsyncConnection * connection) {
mConnection = connection;
}
-
+
virtual ~IMAPConnectionLogger() {
}
-
+
virtual void log(void * sender, ConnectionLogType logType, Data * buffer)
{
mConnection->logConnection(logType, buffer);
}
-
+
private:
IMAPAsyncConnection * mConnection;
};
-
+
}
IMAPAsyncConnection::IMAPAsyncConnection()
@@ -292,7 +292,7 @@ void IMAPAsyncConnection::tryAutomaticDisconnect()
if (mSession->isDisconnected()) {
return;
}
-
+
bool scheduledAutomaticDisconnect = mScheduledAutomaticDisconnect;
if (scheduledAutomaticDisconnect) {
#if __APPLE__
@@ -301,7 +301,7 @@ void IMAPAsyncConnection::tryAutomaticDisconnect()
cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL);
#endif
}
-
+
mOwner->retain();
mScheduledAutomaticDisconnect = true;
#if __APPLE__
@@ -309,7 +309,7 @@ void IMAPAsyncConnection::tryAutomaticDisconnect()
#else
performMethodAfterDelay((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL, 30);
#endif
-
+
if (scheduledAutomaticDisconnect) {
mOwner->release();
}
@@ -318,10 +318,10 @@ void IMAPAsyncConnection::tryAutomaticDisconnect()
void IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay(void * context)
{
mScheduledAutomaticDisconnect = false;
-
+
IMAPOperation * op = disconnectOperation();
op->start();
-
+
mOwner->release();
}
@@ -373,11 +373,11 @@ void IMAPAsyncConnection::setConnectionLogger(ConnectionLogger * logger)
ConnectionLogger * IMAPAsyncConnection::connectionLogger()
{
ConnectionLogger * result;
-
+
pthread_mutex_lock(&mConnectionLoggerLock);
result = mConnectionLogger;
pthread_mutex_unlock(&mConnectionLoggerLock);
-
+
return result;
}
diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h
index 50d1409a..b267f7c7 100755
--- a/src/async/imap/MCIMAPAsyncConnection.h
+++ b/src/async/imap/MCIMAPAsyncConnection.h
@@ -15,6 +15,7 @@ namespace mailcore {
class IMAPCopyMessagesOperation;
class IMAPFetchMessagesOperation;
class IMAPFetchContentOperation;
+ class IMAPFetchParsedContentOperation;
class IMAPIdleOperation;
class IMAPFolderInfoOperation;
class IMAPFolderStatusOperation;
diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc
index ef3bb621..f3a55a5e 100755
--- a/src/async/imap/MCIMAPAsyncSession.cc
+++ b/src/async/imap/MCIMAPAsyncSession.cc
@@ -28,7 +28,7 @@
#include "MCIMAPCopyMessagesOperation.h"
#include "MCIMAPFetchMessagesOperation.h"
#include "MCIMAPFetchContentOperation.h"
-#include "MCIMAPFetchContentOperation.h"
+#include "MCIMAPFetchParsedContentOperation.h"
#include "MCIMAPStoreFlagsOperation.h"
#include "MCIMAPStoreLabelsOperation.h"
#include "MCIMAPSearchOperation.h"
@@ -52,7 +52,7 @@ IMAPAsyncSession::IMAPAsyncSession()
mSessions = new Array();
mMaximumConnections = DEFAULT_MAX_CONNECTIONS;
mAllowsFolderConcurrentAccessEnabled = true;
-
+
mHostname = NULL;
mPort = 0;
mUsername = NULL;
@@ -244,7 +244,7 @@ IMAPAsyncConnection * IMAPAsyncSession::session()
session->setConnectionLogger(mConnectionLogger);
session->setOwner(this);
session->autorelease();
-
+
session->setHostname(mHostname);
session->setPort(mPort);
session->setUsername(mUsername);
@@ -265,7 +265,7 @@ IMAPAsyncConnection * IMAPAsyncSession::session()
session->setAutomaticConfigurationEnabled(false);
}
#endif
-
+
return session;
}
@@ -283,7 +283,7 @@ IMAPAsyncConnection * IMAPAsyncSession::sessionForFolder(String * folder, bool u
return s;
}
}
-
+
s = matchingSessionForFolder(folder);
s->setLastFolder(folder);
return s;
@@ -549,6 +549,28 @@ IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByNumberOper
return op;
}
+IMAPFetchParsedContentOperation * IMAPAsyncSession::fetchParsedMessageByUIDOperation(String * folder, uint32_t uid, bool urgent)
+{
+ IMAPFetchParsedContentOperation * op = new IMAPFetchParsedContentOperation();
+ op->setMainSession(this);
+ op->setFolder(folder);
+ op->setUid(uid);
+ op->setUrgent(urgent);
+ op->autorelease();
+ return op;
+}
+
+IMAPFetchParsedContentOperation * IMAPAsyncSession::fetchParsedMessageByNumberOperation(String * folder, uint32_t number, bool urgent)
+{
+ IMAPFetchParsedContentOperation * op = new IMAPFetchParsedContentOperation();
+ op->setMainSession(this);
+ op->setFolder(folder);
+ op->setNumber(number);
+ op->setUrgent(urgent);
+ op->autorelease();
+ return op;
+}
+
IMAPOperation * IMAPAsyncSession::storeFlagsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags)
{
IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation();
diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h
index a7ec90a0..05b1967c 100755
--- a/src/async/imap/MCIMAPAsyncSession.h
+++ b/src/async/imap/MCIMAPAsyncSession.h
@@ -23,6 +23,7 @@ namespace mailcore {
class IMAPCopyMessagesOperation;
class IMAPFetchMessagesOperation;
class IMAPFetchContentOperation;
+ class IMAPFetchParsedContentOperation;
class IMAPIdleOperation;
class IMAPFolderInfoOperation;
class IMAPFolderStatusOperation;
@@ -137,6 +138,9 @@ namespace mailcore {
virtual IMAPFetchContentOperation * fetchMessageAttachmentByNumberOperation(String * folder, uint32_t number, String * partID,
Encoding encoding, bool urgent = false);
+ virtual IMAPFetchParsedContentOperation * fetchParsedMessageByUIDOperation(String * folder, uint32_t uid, bool urgent = false);
+ virtual IMAPFetchParsedContentOperation * fetchParsedMessageByNumberOperation(String * folder, uint32_t number, bool urgent = false);
+
virtual IMAPOperation * storeFlagsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL);
virtual IMAPOperation * storeFlagsByNumberOperation(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL);
virtual IMAPOperation * storeLabelsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels);
diff --git a/src/async/imap/MCIMAPFetchParsedContentOperation.cc b/src/async/imap/MCIMAPFetchParsedContentOperation.cc
new file mode 100644
index 00000000..e32112e6
--- /dev/null
+++ b/src/async/imap/MCIMAPFetchParsedContentOperation.cc
@@ -0,0 +1,79 @@
+//
+// IMAPFetchParsedContentOperation.cc
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/12/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCIMAPFetchParsedContentOperation.h"
+
+#include "MCIMAPSession.h"
+#include "MCIMAPAsyncConnection.h"
+
+using namespace mailcore;
+
+IMAPFetchParsedContentOperation::IMAPFetchParsedContentOperation()
+{
+ mUid = 0;
+ mNumber = 0;
+ mEncoding = Encoding7Bit;
+ mParser = NULL;
+}
+
+IMAPFetchParsedContentOperation::~IMAPFetchParsedContentOperation()
+{
+ MC_SAFE_RELEASE(mParser);
+}
+
+void IMAPFetchParsedContentOperation::setUid(uint32_t uid)
+{
+ mUid = uid;
+}
+
+uint32_t IMAPFetchParsedContentOperation::uid()
+{
+ return mUid;
+}
+
+void IMAPFetchParsedContentOperation::setNumber(uint32_t value)
+{
+ mNumber = value;
+}
+
+uint32_t IMAPFetchParsedContentOperation::number()
+{
+ return mNumber;
+}
+
+void IMAPFetchParsedContentOperation::setEncoding(Encoding encoding)
+{
+ mEncoding = encoding;
+}
+
+Encoding IMAPFetchParsedContentOperation::encoding()
+{
+ return mEncoding;
+}
+
+MessageParser * IMAPFetchParsedContentOperation::parser()
+{
+ return mParser;
+}
+
+void IMAPFetchParsedContentOperation::main()
+{
+ ErrorCode error;
+ Data * data;
+ if (mUid != 0) {
+ data = session()->session()->fetchMessageByUID(folder(), mUid, this, &error);
+ }
+ else {
+ data = session()->session()->fetchMessageByNumber(folder(), mNumber, this, &error);
+ }
+ if (data) {
+ mParser = new mailcore::MessageParser(data);
+ }
+ setError(error);
+}
+
diff --git a/src/async/imap/MCIMAPFetchParsedContentOperation.h b/src/async/imap/MCIMAPFetchParsedContentOperation.h
new file mode 100644
index 00000000..0262a35b
--- /dev/null
+++ b/src/async/imap/MCIMAPFetchParsedContentOperation.h
@@ -0,0 +1,53 @@
+//
+// IMAPFetchParsedContentOperation.h
+// mailcore2
+//
+// Created by DINH Viêt Hoà on 1/12/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef MAILCORE_IMAPFETCHPARSEDCONTENTOPERATION_H
+
+#define MAILCORE_IMAPFETCHPARSEDCONTENTOPERATION_H
+
+#include <MailCore/MCIMAPOperation.h>
+
+#include <MailCore/MCRFC822.h>
+
+#ifdef __cplusplus
+
+namespace mailcore {
+
+ class IMAPFetchParsedContentOperation : public IMAPOperation {
+ public:
+ IMAPFetchParsedContentOperation();
+ virtual ~IMAPFetchParsedContentOperation();
+
+ virtual void setUid(uint32_t uid);
+ virtual uint32_t uid();
+
+ virtual void setNumber(uint32_t value);
+ virtual uint32_t number();
+
+ virtual void setEncoding(Encoding encoding);
+ virtual Encoding encoding();
+
+ // Result.
+ virtual MessageParser * parser();
+
+ public: // subclass behavior
+ virtual void main();
+
+ private:
+ uint32_t mUid;
+ uint32_t mNumber;
+ Encoding mEncoding;
+ MessageParser * mParser;
+
+ };
+
+}
+
+#endif
+
+#endif