aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/imap/IMAPFolder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/imap/IMAPFolder.cpp')
-rw-r--r--src/net/imap/IMAPFolder.cpp361
1 files changed, 78 insertions, 283 deletions
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
index 3a38182e..dd7f2512 100644
--- a/src/net/imap/IMAPFolder.cpp
+++ b/src/net/imap/IMAPFolder.cpp
@@ -529,135 +529,93 @@ ref <message> IMAPFolder::getMessage(const int num)
}
-std::vector <ref <message> > IMAPFolder::getMessages(const int from, const int to)
+std::vector <ref <message> > IMAPFolder::getMessages(const messageSet& msgs)
{
- const int messageCount = m_status->getMessageCount();
- const int to2 = (to == -1 ? messageCount : to);
-
if (!isOpen())
throw exceptions::illegal_state("Folder not open");
- else if (to2 < from || from < 1 || to2 < 1 || from > messageCount || to2 > messageCount)
- throw exceptions::message_not_found();
-
- std::vector <ref <message> > v;
- ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
-
- for (int i = from ; i <= to2 ; ++i)
- v.push_back(vmime::create <IMAPMessage>(thisFolder, i));
-
- return (v);
-}
-
-
-std::vector <ref <message> > IMAPFolder::getMessages(const std::vector <int>& nums)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- std::vector <ref <message> > v;
- ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
-
- for (std::vector <int>::const_iterator it = nums.begin() ; it != nums.end() ; ++it)
- v.push_back(vmime::create <IMAPMessage>(thisFolder, *it));
-
- return (v);
-}
-
-
-ref <message> IMAPFolder::getMessageByUID(const message::uid& uid)
-{
- std::vector <message::uid> uids;
- uids.push_back(uid);
-
- std::vector <ref <message> > msgs = getMessagesByUID(uids);
-
- if (msgs.size() == 0)
- throw exceptions::message_not_found();
-
- return msgs[0];
-}
-
-std::vector <ref <message> > IMAPFolder::getMessagesByUID(const std::vector <message::uid>& uids)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (uids.size() == 0)
+ if (msgs.isEmpty() == 0)
return std::vector <ref <message> >();
- // C: . UID FETCH uuuu1,uuuu2,uuuu3 UID
- // S: * nnnn1 FETCH (UID uuuu1)
- // S: * nnnn2 FETCH (UID uuuu2)
- // S: * nnnn3 FETCH (UID uuuu3)
- // S: . OK UID FETCH completed
+ std::vector <ref <message> > messages;
- // Prepare command and arguments
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
+ if (msgs.isNumberSet())
+ {
+ const std::vector <int> numbers = IMAPUtils::messageSetToNumberList(msgs);
- cmd << "UID FETCH " << uids[0];
+ ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
- for (std::vector <message::uid>::size_type i = 1, n = uids.size() ; i < n ; ++i)
- cmd << "," << uids[i];
+ for (std::vector <int>::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it)
+ messages.push_back(vmime::create <IMAPMessage>(thisFolder, *it));
+ }
+ else if (msgs.isUIDSet())
+ {
+ // C: . UID FETCH uuuu1,uuuu2,uuuu3 UID
+ // S: * nnnn1 FETCH (UID uuuu1)
+ // S: * nnnn2 FETCH (UID uuuu2)
+ // S: * nnnn3 FETCH (UID uuuu3)
+ // S: . OK UID FETCH completed
- cmd << " UID";
+ // Prepare command and arguments
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
- // Send the request
- m_connection->send(true, cmd.str(), true);
+ cmd << "UID FETCH " << IMAPUtils::messageSetToSequenceSet(msgs) << " UID";
- // Get the response
- utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
+ // Send the request
+ m_connection->send(true, cmd.str(), true);
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("UID FETCH ... UID", resp->getErrorLog(), "bad response");
- }
+ // Get the response
+ utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
- // Process the response
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
+ if (resp->isBad() || resp->response_done()->response_tagged()->
+ resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
+ {
+ throw exceptions::command_error("UID FETCH ... UID", resp->getErrorLog(), "bad response");
+ }
- std::vector <ref <message> > messages;
+ // Process the response
+ const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
+ resp->continue_req_or_response_data();
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
+ for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
+ it = respDataList.begin() ; it != respDataList.end() ; ++it)
{
- throw exceptions::command_error("UID FETCH ... UID",
- resp->getErrorLog(), "invalid response");
- }
+ if ((*it)->response_data() == NULL)
+ {
+ throw exceptions::command_error("UID FETCH ... UID",
+ resp->getErrorLog(), "invalid response");
+ }
- const IMAPParser::message_data* messageData =
- (*it)->response_data()->message_data();
+ 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;
+ // We are only interested in responses of type "FETCH"
+ if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH)
+ continue;
- // Get Process fetch response for this message
- const int msgNum = static_cast <int>(messageData->number());
- message::uid msgUID;
+ // Get Process fetch response for this message
+ const int msgNum = static_cast <int>(messageData->number());
+ message::uid msgUID;
- // Find UID in message attributes
- const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items();
+ // Find UID in message attributes
+ const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items();
- for (std::vector <IMAPParser::msg_att_item*>::const_iterator
- it = atts.begin() ; it != atts.end() ; ++it)
- {
- if ((*it)->type() == IMAPParser::msg_att_item::UID)
+ for (std::vector <IMAPParser::msg_att_item*>::const_iterator
+ it = atts.begin() ; it != atts.end() ; ++it)
{
- msgUID = (*it)->unique_id()->value();
- break;
+ if ((*it)->type() == IMAPParser::msg_att_item::UID)
+ {
+ msgUID = (*it)->unique_id()->value();
+ break;
+ }
}
- }
- if (!msgUID.empty())
- {
- ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
- messages.push_back(vmime::create <IMAPMessage>(thisFolder, msgNum, msgUID));
+ if (!msgUID.empty())
+ {
+ ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
+ messages.push_back(vmime::create <IMAPMessage>(thisFolder, msgNum, msgUID));
+ }
}
}
@@ -816,7 +774,9 @@ void IMAPFolder::fetchMessages(std::vector <ref <message> >& msg, const int opti
}
// Send the request
- const string command = IMAPUtils::buildFetchRequest(m_connection, list, options);
+ const string command = IMAPUtils::buildFetchRequest
+ (m_connection, messageSet::byNumber(list), options);
+
m_connection->send(true, command, true);
// Get the response
@@ -945,17 +905,11 @@ void IMAPFolder::onStoreDisconnected()
}
-void IMAPFolder::deleteMessage(const int num)
-{
- deleteMessages(num, num);
-}
-
-
-void IMAPFolder::deleteMessages(const int from, const int to)
+void IMAPFolder::deleteMessages(const messageSet& msgs)
{
ref <IMAPStore> store = m_store.acquire();
- if (from < 1 || (to < from && to != -1))
+ if (msgs.isEmpty())
throw exceptions::invalid_argument();
if (!store)
@@ -969,19 +923,10 @@ void IMAPFolder::deleteMessages(const int from, const int to)
std::ostringstream command;
command.imbue(std::locale::classic());
- command << "STORE ";
-
- if (from == to)
- {
- command << from;
- }
+ if (msgs.isUIDSet())
+ command << "UID STORE" << IMAPUtils::messageSetToSequenceSet(msgs);
else
- {
- command << from << ":";
-
- if (to == -1) command << m_status->getMessageCount();
- else command << to;
- }
+ command << "STORE" << IMAPUtils::messageSetToSequenceSet(msgs);
command << " +FLAGS (\\Deleted)";
@@ -1002,116 +947,16 @@ void IMAPFolder::deleteMessages(const int from, const int to)
}
-void IMAPFolder::deleteMessages(const std::vector <int>& nums)
+void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const int mode)
{
- ref <IMAPStore> store = m_store.acquire();
-
- if (nums.empty())
- throw exceptions::invalid_argument();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Sort the list of message numbers
- std::vector <int> list;
-
- list.resize(nums.size());
- std::copy(nums.begin(), nums.end(), list.begin());
-
- std::sort(list.begin(), list.end());
-
// Build the request text
std::ostringstream command;
command.imbue(std::locale::classic());
- command << "STORE ";
- command << IMAPUtils::listToSet(list, m_status->getMessageCount(), true);
- command << " +FLAGS (\\Deleted)";
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- utility::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("STORE",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp);
-}
-
-
-void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, const int mode)
-{
- ref <IMAPStore> store = m_store.acquire();
-
- if (from < 1 || (to < from && to != -1))
- throw exceptions::invalid_argument();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- std::ostringstream oss;
- oss.imbue(std::locale::classic());
-
- if (from == to)
- {
- oss << from;
- }
+ if (msgs.isUIDSet())
+ command << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
else
- {
- if (to == -1)
- oss << from << ":*";
- else
- oss << from << ":" << to;
- }
-
- setMessageFlagsImpl(oss.str(), flags, mode);
-}
-
-
-void IMAPFolder::setMessageFlags(const std::vector <int>& nums, const int flags, const int mode)
-{
- ref <IMAPStore> store = m_store.acquire();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Sort the list of message numbers
- std::vector <int> list;
-
- list.resize(nums.size());
- std::copy(nums.begin(), nums.end(), list.begin());
- std::sort(list.begin(), list.end());
-
- // Delegates call
- setMessageFlagsImpl(IMAPUtils::listToSet(list, m_status->getMessageCount(), true), flags, mode);
-}
-
-
-void IMAPFolder::setMessageFlagsImpl(const string& set, const int flags, const int mode)
-{
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "STORE " << set;
+ command << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
switch (mode)
{
@@ -1364,27 +1209,7 @@ void IMAPFolder::rename(const folder::path& newPath)
}
-void IMAPFolder::copyMessage(const folder::path& dest, const int num)
-{
- ref <IMAPStore> store = m_store.acquire();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Construct set
- std::ostringstream set;
- set.imbue(std::locale::classic());
-
- set << num;
-
- // Delegate message copy
- copyMessagesImpl(set.str(), dest);
-}
-
-
-void IMAPFolder::copyMessages(const folder::path& dest, const int from, const int to)
+void IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set)
{
ref <IMAPStore> store = m_store.acquire();
@@ -1392,44 +1217,12 @@ void IMAPFolder::copyMessages(const folder::path& dest, const int from, const in
throw exceptions::illegal_state("Store disconnected");
else if (!isOpen())
throw exceptions::illegal_state("Folder not open");
- else if (from < 1 || (to < from && to != -1))
- throw exceptions::invalid_argument();
-
- // Construct set
- std::ostringstream set;
- set.imbue(std::locale::classic());
- if (to == -1)
- set << from << ":*";
- else
- set << from << ":" << to;
-
- // Delegate message copy
- copyMessagesImpl(set.str(), dest);
-}
-
-
-void IMAPFolder::copyMessages(const folder::path& dest, const std::vector <int>& nums)
-{
- ref <IMAPStore> store = m_store.acquire();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Delegate message copy
- copyMessagesImpl(IMAPUtils::listToSet(nums, m_status->getMessageCount()), dest);
-}
-
-
-void IMAPFolder::copyMessagesImpl(const string& set, const folder::path& dest)
-{
// Build the request text
std::ostringstream command;
command.imbue(std::locale::classic());
- command << "COPY " << set << " ";
+ command << "COPY " << IMAPUtils::messageSetToSequenceSet(set) << " ";
command << IMAPUtils::quoteString(IMAPUtils::pathToString
(m_connection->hierarchySeparator(), dest));
@@ -1599,6 +1392,8 @@ std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid&
}
}
+ processStatusUpdate(resp);
+
return v;
}