diff --git a/src/vmime/net/folder.hpp b/src/vmime/net/folder.hpp index da39f555..0054b1e6 100644 --- a/src/vmime/net/folder.hpp +++ b/src/vmime/net/folder.hpp @@ -368,6 +368,19 @@ public: */ virtual void fetchMessage(shared_ptr msg, const fetchAttributes& attribs) = 0; + /** Get new references to messages in this folder, given either their + * sequence numbers or UIDs, and fetch objects for them at the same time. + * + * @param msgs index set of messages to retrieve + * @param attribs set of attributes to fetch + * @return new objects referencing the specified messages + * @throw exceptions::net_exception if an error occurs + * @see folder::getMessages() + * @see folder::fetchMessages() + */ + virtual std::vector > getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs) = 0; + /** Return the list of fetchable objects supported by * the underlying protocol (see folder::fetchAttributes). * diff --git a/src/vmime/net/imap/IMAPFolder.cpp b/src/vmime/net/imap/IMAPFolder.cpp index 25b7d760..86f13f4b 100644 --- a/src/vmime/net/imap/IMAPFolder.cpp +++ b/src/vmime/net/imap/IMAPFolder.cpp @@ -860,6 +860,90 @@ void IMAPFolder::fetchMessage(shared_ptr msg, const fetchAttributes& o } +std::vector > IMAPFolder::getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs) +{ + shared_ptr store = m_store.lock(); + + if (!store) + throw exceptions::illegal_state("Store disconnected"); + else if (!isOpen()) + throw exceptions::illegal_state("Folder not open"); + + // Ensure we also get the UID for each message + fetchAttributes attribsWithUID(attribs); + attribsWithUID.add(fetchAttributes::UID); + + // Send the request + const string command = IMAPUtils::buildFetchRequest + (m_connection, msgs, attribsWithUID); + + m_connection->send(true, command, true); + + // Get the response + std::auto_ptr resp(m_connection->readResponse()); + + if (resp->isBad() || resp->response_done()->response_tagged()-> + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) + { + throw exceptions::command_error("FETCH", + resp->getErrorLog(), "bad response"); + } + + const std::vector & respDataList = + resp->continue_req_or_response_data(); + + std::vector > messages; + + for (std::vector ::const_iterator + it = respDataList.begin() ; it != respDataList.end() ; ++it) + { + if ((*it)->response_data() == NULL) + { + throw exceptions::command_error("FETCH", + resp->getErrorLog(), "invalid response"); + } + + const IMAPParser::message_data* messageData = + (*it)->response_data()->message_data(); + + // We are only interested in responses of type "FETCH" + if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) + continue; + + // Get message number + const int msgNum = static_cast (messageData->number()); + + // Get message UID + const std::vector atts = messageData->msg_att()->items(); + message::uid msgUID; + + for (std::vector ::const_iterator + it = atts.begin() ; it != atts.end() ; ++it) + { + if ((*it)->type() == IMAPParser::msg_att_item::UID) + { + msgUID = (*it)->unique_id()->value(); + break; + } + } + + // Create a new message reference + shared_ptr thisFolder = dynamicCast (shared_from_this()); + shared_ptr msg = make_shared (thisFolder, msgNum, msgUID); + + messages.push_back(msg); + + // Process fetch response for this message + msg->processFetchResponse(attribsWithUID, messageData); + } + + processStatusUpdate(resp.get()); + + return messages; +} + + int IMAPFolder::getFetchCapabilities() const { return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | diff --git a/src/vmime/net/imap/IMAPFolder.hpp b/src/vmime/net/imap/IMAPFolder.hpp index 96560f38..2604cf75 100644 --- a/src/vmime/net/imap/IMAPFolder.hpp +++ b/src/vmime/net/imap/IMAPFolder.hpp @@ -134,6 +134,9 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); void fetchMessage(shared_ptr msg, const fetchAttributes& options); + std::vector > getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs); + int getFetchCapabilities() const; /** Returns the UID validity of the folder for the current session. diff --git a/src/vmime/net/maildir/maildirFolder.cpp b/src/vmime/net/maildir/maildirFolder.cpp index feb24fd7..79f01ab8 100644 --- a/src/vmime/net/maildir/maildirFolder.cpp +++ b/src/vmime/net/maildir/maildirFolder.cpp @@ -1223,6 +1223,16 @@ void maildirFolder::fetchMessage(shared_ptr msg, const fetchAttributes } +std::vector > maildirFolder::getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs) +{ + std::vector > messages = getMessages(msgs); + fetchMessages(messages, attribs); + + return messages; +} + + int maildirFolder::getFetchCapabilities() const { return fetchAttributes::ENVELOPE | fetchAttributes::STRUCTURE | diff --git a/src/vmime/net/maildir/maildirFolder.hpp b/src/vmime/net/maildir/maildirFolder.hpp index 85677c07..9dfb7a5e 100644 --- a/src/vmime/net/maildir/maildirFolder.hpp +++ b/src/vmime/net/maildir/maildirFolder.hpp @@ -119,6 +119,9 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); void fetchMessage(shared_ptr msg, const fetchAttributes& options); + std::vector > getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs); + int getFetchCapabilities() const; std::vector getMessageNumbersStartingOnUID(const message::uid& uid); diff --git a/src/vmime/net/pop3/POP3Folder.cpp b/src/vmime/net/pop3/POP3Folder.cpp index 354dad2a..e23030d8 100644 --- a/src/vmime/net/pop3/POP3Folder.cpp +++ b/src/vmime/net/pop3/POP3Folder.cpp @@ -484,6 +484,16 @@ void POP3Folder::fetchMessage(shared_ptr msg, const fetchAttributes& o } +std::vector > POP3Folder::getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs) +{ + std::vector > messages = getMessages(msgs); + fetchMessages(messages, attribs); + + return messages; +} + + int POP3Folder::getFetchCapabilities() const { return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | diff --git a/src/vmime/net/pop3/POP3Folder.hpp b/src/vmime/net/pop3/POP3Folder.hpp index 3db2aa27..a549ec96 100644 --- a/src/vmime/net/pop3/POP3Folder.hpp +++ b/src/vmime/net/pop3/POP3Folder.hpp @@ -116,6 +116,9 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); void fetchMessage(shared_ptr msg, const fetchAttributes& options); + std::vector > getAndFetchMessages + (const messageSet& msgs, const fetchAttributes& attribs); + int getFetchCapabilities() const; std::vector getMessageNumbersStartingOnUID(const message::uid& uid);