Permalink
Browse files

Issue #47: get and fetch messages.

Added a feature to get and fetch a list of messages at the same time,
to avoid a roundtrip to the server.
  • Loading branch information...
1 parent 16bd0a6 commit 3fcea19d7558de39cb7be5d4e86609aa90f66fbb @vincent-richard vincent-richard committed Mar 10, 2014
@@ -368,6 +368,19 @@ class VMIME_EXPORT folder : public object
*/
virtual void fetchMessage(shared_ptr <message> 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 <shared_ptr <message> > getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs) = 0;
+
/** Return the list of fetchable objects supported by
* the underlying protocol (see folder::fetchAttributes).
*
@@ -860,6 +860,90 @@ void IMAPFolder::fetchMessage(shared_ptr <message> msg, const fetchAttributes& o
}
+std::vector <shared_ptr <message> > IMAPFolder::getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs)
+{
+ shared_ptr <IMAPStore> 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 <IMAPParser::response> 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 <IMAPParser::continue_req_or_response_data*>& respDataList =
+ resp->continue_req_or_response_data();
+
+ std::vector <shared_ptr <message> > messages;
+
+ for (std::vector <IMAPParser::continue_req_or_response_data*>::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 <int>(messageData->number());
+
+ // Get message UID
+ const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items();
+ message::uid msgUID;
+
+ for (std::vector <IMAPParser::msg_att_item*>::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 <IMAPFolder> thisFolder = dynamicCast <IMAPFolder>(shared_from_this());
+ shared_ptr <IMAPMessage> msg = make_shared <IMAPMessage>(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 |
@@ -134,6 +134,9 @@ class VMIME_EXPORT IMAPFolder : public folder
void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL);
void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options);
+ std::vector <shared_ptr <message> > getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs);
+
int getFetchCapabilities() const;
/** Returns the UID validity of the folder for the current session.
@@ -1223,6 +1223,16 @@ void maildirFolder::fetchMessage(shared_ptr <message> msg, const fetchAttributes
}
+std::vector <shared_ptr <message> > maildirFolder::getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs)
+{
+ std::vector <shared_ptr <message> > messages = getMessages(msgs);
+ fetchMessages(messages, attribs);
+
+ return messages;
+}
+
+
int maildirFolder::getFetchCapabilities() const
{
return fetchAttributes::ENVELOPE | fetchAttributes::STRUCTURE |
@@ -119,6 +119,9 @@ class VMIME_EXPORT maildirFolder : public folder
void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL);
void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options);
+ std::vector <shared_ptr <message> > getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs);
+
int getFetchCapabilities() const;
std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid);
@@ -484,6 +484,16 @@ void POP3Folder::fetchMessage(shared_ptr <message> msg, const fetchAttributes& o
}
+std::vector <shared_ptr <message> > POP3Folder::getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs)
+{
+ std::vector <shared_ptr <message> > messages = getMessages(msgs);
+ fetchMessages(messages, attribs);
+
+ return messages;
+}
+
+
int POP3Folder::getFetchCapabilities() const
{
return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
@@ -116,6 +116,9 @@ class VMIME_EXPORT POP3Folder : public folder
void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL);
void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options);
+ std::vector <shared_ptr <message> > getAndFetchMessages
+ (const messageSet& msgs, const fetchAttributes& attribs);
+
int getFetchCapabilities() const;
std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid);

0 comments on commit 3fcea19

Please sign in to comment.