aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dmitry Isaikin <isaikin-dmitry@yandex.ru>2016-07-06 10:17:28 +0300
committerGravatar HoĆ  V. DINH <dinh.viet.hoa@gmail.com>2016-07-06 00:17:28 -0700
commit1e77049bf421997de9d04a6d1e1dde4ce065affe (patch)
treef6358a20850a4f440d870ec857428c7f071160cf
parent17df6ae7c456cc27a316aa0d7b6c83066adb3c49 (diff)
Use libetpan API for fetching whole IMAP attachment to file (#1461)
-rw-r--r--src/async/imap/MCIMAPFetchContentToFileOperation.cpp16
-rw-r--r--src/core/basetypes/MCDataStreamDecoder.cpp4
-rw-r--r--src/core/imap/MCIMAPSession.cpp47
-rw-r--r--src/core/imap/MCIMAPSession.h5
4 files changed, 65 insertions, 7 deletions
diff --git a/src/async/imap/MCIMAPFetchContentToFileOperation.cpp b/src/async/imap/MCIMAPFetchContentToFileOperation.cpp
index 82a1fa23..e6bf7740 100644
--- a/src/async/imap/MCIMAPFetchContentToFileOperation.cpp
+++ b/src/async/imap/MCIMAPFetchContentToFileOperation.cpp
@@ -19,7 +19,7 @@ IMAPFetchContentToFileOperation::IMAPFetchContentToFileOperation()
mPartID = NULL;
mEncoding = Encoding7Bit;
mFilename = NULL;
- mLoadingByChunksEnabled = true;
+ mLoadingByChunksEnabled = false;
mChunksSize = 2*1024*1024;
mEstimatedSize = 0;
}
@@ -83,9 +83,15 @@ uint32_t IMAPFetchContentToFileOperation::estimatedSize()
void IMAPFetchContentToFileOperation::main()
{
ErrorCode error = ErrorNone;
- session()->session()->fetchMessageAttachmentToFileByUID(folder(), mUid, mPartID,
- mEstimatedSize, mEncoding,
- mFilename, mChunksSize,
- this, &error);
+ if (mLoadingByChunksEnabled) {
+ session()->session()->fetchMessageAttachmentToFileByChunksByUID(folder(), mUid, mPartID,
+ mEstimatedSize, mEncoding,
+ mFilename, mChunksSize,
+ this, &error);
+ } else {
+ session()->session()->fetchMessageAttachmentToFileByUID(folder(), mUid, mPartID,
+ mEncoding, mFilename,
+ this, &error);
+ }
setError(error);
}
diff --git a/src/core/basetypes/MCDataStreamDecoder.cpp b/src/core/basetypes/MCDataStreamDecoder.cpp
index 120cfb65..3b24c56e 100644
--- a/src/core/basetypes/MCDataStreamDecoder.cpp
+++ b/src/core/basetypes/MCDataStreamDecoder.cpp
@@ -88,6 +88,10 @@ ErrorCode DataStreamDecoder::appendDecodedData(Data * decodedData)
return ErrorFile;
}
+ if (decodedData->length() == 0) {
+ return ErrorNone;
+ }
+
if (mFile == NULL) {
mFile = fopen(mFilename->fileSystemRepresentation(), "wb");
diff --git a/src/core/imap/MCIMAPSession.cpp b/src/core/imap/MCIMAPSession.cpp
index e58b8cba..a5a5e06c 100644
--- a/src/core/imap/MCIMAPSession.cpp
+++ b/src/core/imap/MCIMAPSession.cpp
@@ -2973,7 +2973,7 @@ Data * IMAPSession::fetchMessageAttachmentByNumber(String * folder, uint32_t num
return fetchMessageAttachment(folder, false, number, partID, encoding, progressCallback, pError);
}
-void IMAPSession::fetchMessageAttachmentToFileByUID(String * folder, uint32_t uid, String * partID,
+void IMAPSession::fetchMessageAttachmentToFileByChunksByUID(String * folder, uint32_t uid, String * partID,
uint32_t estimatedSize, Encoding encoding,
String * outputFile, uint32_t chunkSize,
IMAPProgressCallback * progressCallback, ErrorCode * pError)
@@ -3051,6 +3051,51 @@ void IMAPSession::fetchMessageAttachmentToFileByUID(String * folder, uint32_t ui
* pError = error;
}
+static bool msg_body_handler(int msg_att_type, struct mailimap_msg_att_body_section * section,
+ const char * bytes, size_t len, void * context)
+{
+ DataStreamDecoder * decoder = (DataStreamDecoder *)context;
+
+ AutoreleasePool * pool = new AutoreleasePool();
+
+ Data * data = Data::dataWithBytes(bytes, (unsigned int) len);
+ ErrorCode error = decoder->appendData(data);
+
+ pool->release();
+
+ return error == ErrorNone;
+}
+
+void IMAPSession::fetchMessageAttachmentToFileByUID(String * folder, uint32_t uid, String * partID,
+ Encoding encoding, String * outputFile,
+ IMAPProgressCallback * progressCallback, ErrorCode * pError)
+{
+ DataStreamDecoder * decoder = new DataStreamDecoder();
+ decoder->setEncoding(encoding);
+ decoder->setFilename(outputFile);
+
+ ErrorCode error = ErrorNone;
+ selectIfNeeded(folder, &error);
+ if (error != ErrorNone) {
+ * pError = error;
+ return;
+ }
+
+ mailimap_set_msg_body_handler(mImap, msg_body_handler, decoder);
+
+ fetchNonDecodedMessageAttachment(folder, true, uid, partID, true, 0, 0, encoding, progressCallback, &error);
+
+ mailimap_set_msg_body_handler(mImap, NULL, NULL);
+
+ if (error == ErrorNone) {
+ error = decoder->flushData();
+ }
+
+ MC_SAFE_RELEASE(decoder);
+
+ * pError = error;
+}
+
IndexSet * IMAPSession::search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError)
{
IMAPSearchExpression * expr;
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 55f47de0..4d1f3894 100644
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -122,10 +122,13 @@ namespace mailcore {
virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID,
Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError);
- virtual void fetchMessageAttachmentToFileByUID(String * folder, uint32_t uid, String * partID,
+ virtual void fetchMessageAttachmentToFileByChunksByUID(String * folder, uint32_t uid, String * partID,
uint32_t estimatedSize, Encoding encoding,
String * outputFile, uint32_t chunkSize,
IMAPProgressCallback * progressCallback, ErrorCode * pError);
+ virtual void fetchMessageAttachmentToFileByUID(String * folder, uint32_t uid, String * partID,
+ Encoding encoding, String * outputFile,
+ IMAPProgressCallback * progressCallback, ErrorCode * pError);
virtual Data * fetchMessageAttachmentByNumber(String * folder, uint32_t number, String * partID,
Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError);