aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/net/events.cpp59
-rw-r--r--src/net/folder.cpp29
-rw-r--r--src/net/imap/IMAPFolder.cpp334
-rw-r--r--src/net/imap/IMAPFolderStatus.cpp165
-rw-r--r--src/net/imap/IMAPMessage.cpp134
-rw-r--r--src/net/maildir/maildirFolder.cpp91
-rw-r--r--src/net/maildir/maildirFolderStatus.cpp21
-rw-r--r--src/net/pop3/POP3Folder.cpp35
-rw-r--r--src/net/pop3/POP3FolderStatus.cpp21
-rw-r--r--vmime/net/events.hpp56
-rw-r--r--vmime/net/folder.hpp7
-rw-r--r--vmime/net/folderStatus.hpp6
-rw-r--r--vmime/net/imap/IMAPFolder.hpp9
-rw-r--r--vmime/net/imap/IMAPFolderStatus.hpp9
-rw-r--r--vmime/net/imap/IMAPMessage.hpp20
-rw-r--r--vmime/net/maildir/maildirFolderStatus.hpp6
-rw-r--r--vmime/net/message.hpp4
-rw-r--r--vmime/net/pop3/POP3FolderStatus.hpp6
18 files changed, 562 insertions, 450 deletions
diff --git a/src/net/events.cpp b/src/net/events.cpp
index 7dbb4adb..8cc23706 100644
--- a/src/net/events.cpp
+++ b/src/net/events.cpp
@@ -39,9 +39,26 @@ namespace events {
//
+// event
+//
+
+event::event()
+{
+}
+
+
+event::~event()
+{
+}
+
+
+//
// messageCountEvent
//
+const char* messageCountEvent::EVENT_CLASS = "messageCountEvent";
+
+
messageCountEvent::messageCountEvent
(ref <folder> folder, const Types type, const std::vector <int>& nums)
: m_folder(folder), m_type(type)
@@ -56,12 +73,18 @@ messageCountEvent::Types messageCountEvent::getType() const { return (m_type); }
const std::vector <int>& messageCountEvent::getNumbers() const { return (m_nums); }
-void messageCountEvent::dispatch(messageCountListener* listener) const
+void messageCountEvent::dispatch(messageCountListener* listener)
{
if (m_type == TYPE_ADDED)
- listener->messagesAdded(*this);
+ listener->messagesAdded(thisRef().dynamicCast <messageCountEvent>());
else
- listener->messagesRemoved(*this);
+ listener->messagesRemoved(thisRef().dynamicCast <messageCountEvent>());
+}
+
+
+const char* messageCountEvent::getClass() const
+{
+ return EVENT_CLASS;
}
@@ -69,6 +92,9 @@ void messageCountEvent::dispatch(messageCountListener* listener) const
// messageChangedEvent
//
+const char* messageChangedEvent::EVENT_CLASS = "messageChangedEvent";
+
+
messageChangedEvent::messageChangedEvent
(ref <folder> folder, const Types type, const std::vector <int>& nums)
: m_folder(folder), m_type(type)
@@ -83,9 +109,15 @@ messageChangedEvent::Types messageChangedEvent::getType() const { return (m_type
const std::vector <int>& messageChangedEvent::getNumbers() const { return (m_nums); }
-void messageChangedEvent::dispatch(messageChangedListener* listener) const
+void messageChangedEvent::dispatch(messageChangedListener* listener)
+{
+ listener->messageChanged(thisRef().dynamicCast <messageChangedEvent>());
+}
+
+
+const char* messageChangedEvent::getClass() const
{
- listener->messageChanged(*this);
+ return EVENT_CLASS;
}
@@ -93,6 +125,9 @@ void messageChangedEvent::dispatch(messageChangedListener* listener) const
// folderEvent
//
+const char* folderEvent::EVENT_CLASS = "folderEvent";
+
+
folderEvent::folderEvent
(ref <folder> folder, const Types type,
const utility::path& oldPath, const utility::path& newPath)
@@ -105,17 +140,23 @@ ref <folder> folderEvent::getFolder() const { return (m_folder); }
folderEvent::Types folderEvent::getType() const { return (m_type); }
-void folderEvent::dispatch(folderListener* listener) const
+void folderEvent::dispatch(folderListener* listener)
{
switch (m_type)
{
- case TYPE_CREATED: listener->folderCreated(*this); break;
- case TYPE_RENAMED: listener->folderRenamed(*this); break;
- case TYPE_DELETED: listener->folderDeleted(*this); break;
+ case TYPE_CREATED: listener->folderCreated(thisRef().dynamicCast <folderEvent>()); break;
+ case TYPE_RENAMED: listener->folderRenamed(thisRef().dynamicCast <folderEvent>()); break;
+ case TYPE_DELETED: listener->folderDeleted(thisRef().dynamicCast <folderEvent>()); break;
}
}
+const char* folderEvent::getClass() const
+{
+ return EVENT_CLASS;
+}
+
+
} // events
} // net
} // vmime
diff --git a/src/net/folder.cpp b/src/net/folder.cpp
index 58523399..1cc618d4 100644
--- a/src/net/folder.cpp
+++ b/src/net/folder.cpp
@@ -48,12 +48,12 @@ void folder::removeMessageChangedListener(events::messageChangedListener* l)
}
-void folder::notifyMessageChanged(const events::messageChangedEvent& event)
+void folder::notifyMessageChanged(ref <events::messageChangedEvent> event)
{
for (std::list <events::messageChangedListener*>::iterator
it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it)
{
- event.dispatch(*it);
+ event->dispatch(*it);
}
}
@@ -70,12 +70,12 @@ void folder::removeMessageCountListener(events::messageCountListener* l)
}
-void folder::notifyMessageCount(const events::messageCountEvent& event)
+void folder::notifyMessageCount(ref <events::messageCountEvent> event)
{
for (std::list <events::messageCountListener*>::iterator
it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it)
{
- event.dispatch(*it);
+ event->dispatch(*it);
}
}
@@ -92,12 +92,29 @@ void folder::removeFolderListener(events::folderListener* l)
}
-void folder::notifyFolder(const events::folderEvent& event)
+void folder::notifyFolder(ref <events::folderEvent> event)
{
for (std::list <events::folderListener*>::iterator
it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it)
{
- event.dispatch(*it);
+ event->dispatch(*it);
+ }
+}
+
+
+void folder::notifyEvent(ref <events::event> event)
+{
+ if (event->getClass() == events::messageCountEvent::EVENT_CLASS)
+ {
+ notifyMessageCount(event.dynamicCast <events::messageCountEvent>());
+ }
+ else if (event->getClass() == events::messageChangedEvent::EVENT_CLASS)
+ {
+ notifyMessageChanged(event.dynamicCast <events::messageChangedEvent>());
+ }
+ else if (event->getClass() == events::folderEvent::EVENT_CLASS)
+ {
+ notifyFolder(event.dynamicCast <events::folderEvent>());
}
}
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
index cbcfd418..60133a29 100644
--- a/src/net/imap/IMAPFolder.cpp
+++ b/src/net/imap/IMAPFolder.cpp
@@ -381,9 +381,10 @@ void IMAPFolder::create(const int type)
}
// Notify folder created
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_CREATED, m_path, m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_CREATED, m_path, m_path);
notifyFolder(event);
}
@@ -418,9 +419,10 @@ void IMAPFolder::destroy()
}
// Notify folder deleted
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_DELETED, m_path, m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_DELETED, m_path, m_path);
notifyFolder(event);
}
@@ -674,6 +676,15 @@ int IMAPFolder::getMessageCount()
}
+vmime_uint64 IMAPFolder::getHighestModSequence() const
+{
+ if (!isOpen())
+ throw exceptions::illegal_state("Folder not open");
+
+ return m_status->getHighestModSeq();
+}
+
+
ref <folder> IMAPFolder::getFolder(const folder::path::component& name)
{
ref <IMAPStore> store = m_store.acquire();
@@ -965,7 +976,7 @@ void IMAPFolder::deleteMessages(const int from, const int to)
else command << to;
}
- command << " +FLAGS.SILENT (\\Deleted)";
+ command << " +FLAGS (\\Deleted)";
// Send the request
m_connection->send(true, command.str(), true);
@@ -980,33 +991,6 @@ void IMAPFolder::deleteMessages(const int from, const int to)
resp->getErrorLog(), "bad response");
}
- // Update local flags
- const int to2 = (to == -1) ? m_status->getMessageCount() : to;
- const int count = to - from + 1;
-
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags |= message::FLAG_DELETED;
- }
- }
-
- // Notify message flags changed
- std::vector <int> nums;
- nums.resize(count);
-
- for (int i = from, j = 0 ; i <= to2 ; ++i, ++j)
- nums[j] = i;
-
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
-
- notifyMessageChanged(event);
-
processStatusUpdate(resp);
}
@@ -1039,7 +1023,7 @@ void IMAPFolder::deleteMessages(const std::vector <int>& nums)
command << "STORE ";
command << IMAPUtils::listToSet(list, m_status->getMessageCount(), true);
- command << " +FLAGS.SILENT (\\Deleted)";
+ command << " +FLAGS (\\Deleted)";
// Send the request
m_connection->send(true, command.str(), true);
@@ -1054,24 +1038,6 @@ void IMAPFolder::deleteMessages(const std::vector <int>& nums)
resp->getErrorLog(), "bad response");
}
- // Update local flags
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()))
- {
- if ((*it)->m_flags != message::FLAG_UNDEFINED)
- (*it)->m_flags |= message::FLAG_DELETED;
- }
- }
-
- // Notify message flags changed
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, list);
-
- notifyMessageChanged(event);
-
processStatusUpdate(resp);
}
@@ -1093,77 +1059,19 @@ void IMAPFolder::setMessageFlags(const int from, const int to, const int flags,
std::ostringstream oss;
oss.imbue(std::locale::classic());
- if (to == -1)
- oss << from << ":*";
- else
- oss << from << ":" << to;
-
- setMessageFlagsImpl(oss.str(), flags, mode);
-
- // Update local flags
- const int to2 = (to == -1) ? m_status->getMessageCount() : to;
- const int count = to - from + 1;
-
- switch (mode)
- {
- case message::FLAG_MODE_ADD:
- {
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags |= flags;
- }
- }
-
- break;
- }
- case message::FLAG_MODE_REMOVE:
+ if (from == to)
{
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags &= ~flags;
- }
- }
-
- break;
+ oss << from;
}
- default:
- case message::FLAG_MODE_SET:
+ else
{
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags = flags;
- }
- }
-
- break;
- }
-
+ if (to == -1)
+ oss << from << ":*";
+ else
+ oss << from << ":" << to;
}
- // Notify message flags changed
- std::vector <int> nums;
- nums.resize(count);
-
- for (int i = from, j = 0 ; i <= to2 ; ++i, ++j)
- nums[j] = i;
-
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
-
- notifyMessageChanged(event);
+ setMessageFlagsImpl(oss.str(), flags, mode);
}
@@ -1183,67 +1091,10 @@ void IMAPFolder::setMessageFlags(const std::vector <int>& nums, const int flags,
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);
-
- // Update local flags
- switch (mode)
- {
- case message::FLAG_MODE_ADD:
- {
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags |= flags;
- }
- }
-
- break;
- }
- case message::FLAG_MODE_REMOVE:
- {
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags &= ~flags;
- }
- }
-
- break;
- }
- default:
- case message::FLAG_MODE_SET:
- {
- for (std::vector <IMAPMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags = flags;
- }
- }
-
- break;
- }
-
- }
-
- // Notify message flags changed
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
-
- notifyMessageChanged(event);
}
@@ -1257,10 +1108,10 @@ void IMAPFolder::setMessageFlagsImpl(const string& set, const int flags, const i
switch (mode)
{
- case message::FLAG_MODE_ADD: command << " +FLAGS.SILENT "; break;
- case message::FLAG_MODE_REMOVE: command << " -FLAGS.SILENT "; break;
+ case message::FLAG_MODE_ADD: command << " +FLAGS "; break;
+ case message::FLAG_MODE_REMOVE: command << " -FLAGS "; break;
default:
- case message::FLAG_MODE_SET: command << " FLAGS.SILENT "; break;
+ case message::FLAG_MODE_SET: command << " FLAGS "; break;
}
const string flagList = IMAPUtils::messageFlagList(flags);
@@ -1367,7 +1218,7 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int
if (progress)
progress->start(total);
- const socket::size_type blockSize = std::min(is.getBlockSize(),
+ const socket::size_type blockSize = std::min(is.getBlockSize(),
static_cast <size_t>(m_connection->getSocket()->getBlockSize()));
std::vector <char> vbuffer(blockSize);
@@ -1430,45 +1281,6 @@ void IMAPFolder::expunge()
resp->getErrorLog(), "bad response");
}
- // Update the numbering of the messages
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- std::vector <int> nums;
-
- 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("EXPUNGE",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::message_data* messageData =
- (*it)->response_data()->message_data();
-
- // We are only interested in responses of type "EXPUNGE"
- if (messageData == NULL ||
- messageData->type() != IMAPParser::message_data::EXPUNGE)
- {
- continue;
- }
-
- const int number = messageData->number();
-
- nums.push_back(number);
-
- for (std::vector <IMAPMessage*>::iterator jt =
- m_messages.begin() ; jt != m_messages.end() ; ++jt)
- {
- if ((*jt)->m_num == number)
- (*jt)->m_expunged = true;
- else if ((*jt)->m_num > number)
- (*jt)->m_num--;
- }
- }
-
processStatusUpdate(resp);
}
@@ -1515,9 +1327,10 @@ void IMAPFolder::rename(const folder::path& newPath)
m_path = newPath;
m_name = newPath.getLastComponent();
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_RENAMED, oldPath, newPath);
notifyFolder(event);
@@ -1531,9 +1344,10 @@ void IMAPFolder::rename(const folder::path& newPath)
(*it)->m_path.renameParent(oldPath, newPath);
- events::folderEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
(*it)->notifyFolder(event);
}
@@ -1784,6 +1598,11 @@ std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid&
void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp)
{
+ std::vector <ref <events::event> > events;
+
+ ref <IMAPFolderStatus> oldStatus = m_status->clone().dynamicCast <IMAPFolderStatus>();
+ int expungedMessageCount = 0;
+
// Process tagged response
if (resp->response_done() && resp->response_done()->response_tagged() &&
resp->response_done()->response_tagged()
@@ -1813,11 +1632,74 @@ void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp)
{
m_status->updateFromResponse((*it)->response_data()->mailbox_data());
}
+ else if ((*it)->response_data() && (*it)->response_data()->message_data())
+ {
+ const IMAPParser::message_data* msgData = (*it)->response_data()->message_data();
+ const int msgNumber = msgData->number();
+
+ if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::FETCH)
+ {
+ // Message changed
+ for (std::vector <IMAPMessage*>::iterator mit =
+ m_messages.begin() ; mit != m_messages.end() ; ++mit)
+ {
+ if ((*mit)->getNumber() == msgNumber)
+ (*mit)->processFetchResponse(/* options */ 0, msgData);
+ }
+
+ events.push_back(vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS,
+ std::vector <int>(1, msgNumber)));
+ }
+ else if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::EXPUNGE)
+ {
+ // A message has been expunged, renumber messages
+ for (std::vector <IMAPMessage*>::iterator jt =
+ m_messages.begin() ; jt != m_messages.end() ; ++jt)
+ {
+ if ((*jt)->getNumber() == msgNumber)
+ (*jt)->setExpunged();
+ else if ((*jt)->getNumber() > msgNumber)
+ (*jt)->renumber((*jt)->getNumber() - 1);
+ }
+
+ events.push_back(vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_REMOVED,
+ std::vector <int>(1, msgNumber)));
+
+ expungedMessageCount++;
+ }
+ }
}
- // TODO: notification
+ // New messages arrived
+ if (m_status->getMessageCount() > oldStatus->getMessageCount() - expungedMessageCount)
+ {
+ std::vector <int> newMessageNumbers;
+
+ for (int msgNumber = oldStatus->getMessageCount() - expungedMessageCount ;
+ msgNumber <= m_status->getMessageCount() ; ++msgNumber)
+ {
+ newMessageNumbers.push_back(msgNumber);
+ }
+
+ events.push_back(vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED,
+ newMessageNumbers));
+ }
+
+ // Dispatch notifications
+ for (std::vector <ref <events::event> >::iterator evit =
+ events.begin() ; evit != events.end() ; ++evit)
+ {
+ notifyEvent(*evit);
+ }
}
+
} // imap
} // net
} // vmime
diff --git a/src/net/imap/IMAPFolderStatus.cpp b/src/net/imap/IMAPFolderStatus.cpp
index 14a77024..c231cb38 100644
--- a/src/net/imap/IMAPFolderStatus.cpp
+++ b/src/net/imap/IMAPFolderStatus.cpp
@@ -46,6 +46,18 @@ IMAPFolderStatus::IMAPFolderStatus()
}
+IMAPFolderStatus::IMAPFolderStatus(const IMAPFolderStatus& other)
+ : folderStatus(),
+ m_count(other.m_count),
+ m_unseen(other.m_unseen),
+ m_recent(other.m_recent),
+ m_uidValidity(other.m_uidValidity),
+ m_uidNext(other.m_uidNext),
+ m_highestModSeq(other.m_highestModSeq)
+{
+}
+
+
unsigned int IMAPFolderStatus::getMessageCount() const
{
return m_count;
@@ -82,8 +94,16 @@ vmime_uint64 IMAPFolderStatus::getHighestModSeq() const
}
-void IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp)
+ref <folderStatus> IMAPFolderStatus::clone() const
{
+ return vmime::create <IMAPFolderStatus>(*this);
+}
+
+
+bool IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp)
+{
+ bool changed = false;
+
if (resp->type() == IMAPParser::mailbox_data::STATUS)
{
const IMAPParser::status_att_list* statusAttList = resp->status_att_list();
@@ -94,81 +114,176 @@ void IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp)
switch ((*jt)->type())
{
case IMAPParser::status_att_val::MESSAGES:
+ {
+ const unsigned int count = (*jt)->value_as_number()->value();
- m_count = (*jt)->value_as_number()->value();
- break;
+ if (m_count != count)
+ {
+ m_count = count;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::status_att_val::UNSEEN:
+ {
+ const unsigned int unseen = (*jt)->value_as_number()->value();
- m_unseen = (*jt)->value_as_number()->value();
- break;
+ if (m_unseen != unseen)
+ {
+ m_unseen = unseen;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::status_att_val::RECENT:
+ {
+ const unsigned int recent = (*jt)->value_as_number()->value();
- m_recent = (*jt)->value_as_number()->value();
- break;
+ if (m_recent != recent)
+ {
+ m_recent = recent;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::status_att_val::UIDNEXT:
+ {
+ const vmime_uint32 uidNext = (*jt)->value_as_number()->value();
- m_uidNext = (*jt)->value_as_number()->value();
- break;
+ if (m_uidNext != uidNext)
+ {
+ m_uidNext = uidNext;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::status_att_val::UIDVALIDITY:
+ {
+ const vmime_uint32 uidValidity = (*jt)->value_as_number()->value();
- m_uidValidity = (*jt)->value_as_number()->value();
- break;
+ if (m_uidValidity != uidValidity)
+ {
+ m_uidValidity = uidValidity;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::status_att_val::HIGHESTMODSEQ:
+ {
+ const vmime_uint64 highestModSeq = (*jt)->value_as_mod_sequence_value()->value();
+
+ if (m_highestModSeq != highestModSeq)
+ {
+ m_highestModSeq = highestModSeq;
+ changed = true;
+ }
- m_highestModSeq = (*jt)->value_as_mod_sequence_value()->value();
break;
}
+
+ }
}
}
else if (resp->type() == IMAPParser::mailbox_data::EXISTS)
{
- m_count = resp->number()->value();
+ const unsigned int count = resp->number()->value();
+
+ if (m_count != count)
+ {
+ m_count = count;
+ changed = true;
+ }
}
else if (resp->type() == IMAPParser::mailbox_data::RECENT)
{
- m_recent = resp->number()->value();
+ const unsigned int recent = resp->number()->value();
+
+ if (m_recent != recent)
+ {
+ m_recent = recent;
+ changed = true;
+ }
}
+
+ return changed;
}
-void IMAPFolderStatus::updateFromResponse(const IMAPParser::resp_text_code* resp)
+bool IMAPFolderStatus::updateFromResponse(const IMAPParser::resp_text_code* resp)
{
+ bool changed = false;
+
switch (resp->type())
{
case IMAPParser::resp_text_code::UIDVALIDITY:
+ {
+ const vmime_uint32 uidValidity = resp->nz_number()->value();
- m_uidValidity = resp->nz_number()->value();
- break;
+ if (m_uidValidity != uidValidity)
+ {
+ m_uidValidity = uidValidity;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::resp_text_code::UIDNEXT:
+ {
+ const vmime_uint32 uidNext = resp->nz_number()->value();
- m_uidNext = resp->nz_number()->value();
- break;
+ if (m_uidNext != uidNext)
+ {
+ m_uidNext = uidNext;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::resp_text_code::UNSEEN:
+ {
+ const unsigned int unseen = resp->nz_number()->value();
- m_unseen = resp->nz_number()->value();
- break;
+ if (m_unseen != unseen)
+ {
+ m_unseen = unseen;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::resp_text_code::HIGHESTMODSEQ:
+ {
+ const vmime_uint64 highestModSeq = resp->mod_sequence_value()->value();
- m_highestModSeq = resp->mod_sequence_value()->value();
- break;
+ if (m_highestModSeq != highestModSeq)
+ {
+ m_highestModSeq = highestModSeq;
+ changed = true;
+ }
+ break;
+ }
case IMAPParser::resp_text_code::NOMODSEQ:
+ {
+ if (m_highestModSeq != 0)
+ {
+ m_highestModSeq = 0;
+ changed = true;
+ }
- m_highestModSeq = 0;
break;
-
+ }
default:
break;
}
+
+ return changed;
}
diff --git a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp
index 2b7dba14..9ae264c0 100644
--- a/src/net/imap/IMAPMessage.cpp
+++ b/src/net/imap/IMAPMessage.cpp
@@ -365,15 +365,14 @@ void IMAPMessage::extractImpl(ref <const messagePart> p, utility::outputStream&
}
-void IMAPMessage::processFetchResponse
+int IMAPMessage::processFetchResponse
(const int options, const IMAPParser::message_data* msgData)
{
ref <IMAPFolder> folder = m_folder.acquire();
// Get message attributes
const std::vector <IMAPParser::msg_att_item*> atts = msgData->msg_att()->items();
-
- int flags = 0;
+ int changes = 0;
for (std::vector <IMAPParser::msg_att_item*>::const_iterator
it = atts.begin() ; it != atts.end() ; ++it)
@@ -382,7 +381,14 @@ void IMAPMessage::processFetchResponse
{
case IMAPParser::msg_att_item::FLAGS:
{
- flags |= IMAPUtils::messageFlagsFromFlags((*it)->flag_list());
+ int flags = IMAPUtils::messageFlagsFromFlags((*it)->flag_list());
+
+ if (m_flags != flags)
+ {
+ m_flags = flags;
+ changes |= events::messageChangedEvent::TYPE_FLAGS;
+ }
+
break;
}
case IMAPParser::msg_att_item::UID:
@@ -505,8 +511,7 @@ void IMAPMessage::processFetchResponse
}
}
- if (options & folder::FETCH_FLAGS)
- m_flags = flags;
+ return changes;
}
@@ -525,111 +530,8 @@ void IMAPMessage::setFlags(const int flags, const int mode)
if (!folder)
throw exceptions::folder_not_found();
- else if (folder->m_mode == folder::MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "STORE " << m_num;
-
- switch (mode)
- {
- case FLAG_MODE_ADD: command << " +FLAGS"; break;
- case FLAG_MODE_REMOVE: command << " -FLAGS"; break;
- default:
- case FLAG_MODE_SET: command << " FLAGS"; break;
- }
-
- if (m_flags == FLAG_UNDEFINED) // Update local flags only if they
- command << ".SILENT "; // have been fetched previously
- else
- command << " ";
-
- std::vector <string> flagList;
-
- if (flags & FLAG_REPLIED) flagList.push_back("\\Answered");
- if (flags & FLAG_MARKED) flagList.push_back("\\Flagged");
- if (flags & FLAG_DELETED) flagList.push_back("\\Deleted");
- if (flags & FLAG_SEEN) flagList.push_back("\\Seen");
- if (flags & FLAG_DRAFT) flagList.push_back("\\Draft");
-
- if (!flagList.empty())
- {
- command << "(";
-
- if (flagList.size() >= 2)
- {
- std::copy(flagList.begin(), flagList.end() - 1,
- std::ostream_iterator <string>(command, " "));
- }
-
- command << *(flagList.end() - 1) << ")";
-
- // Send the request
- folder->m_connection->send(true, command.str(), true);
-
- // Get the response
- utility::auto_ptr <IMAPParser::response> resp(folder->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");
- }
- // Update the local flags for this message
- if (m_flags != FLAG_UNDEFINED)
- {
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- int newFlags = 0;
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- continue;
-
- 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 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::FLAGS)
- newFlags |= IMAPUtils::messageFlagsFromFlags((*it)->flag_list());
- }
- }
-
- m_flags = newFlags;
- }
-
- // Notify message flags changed
- std::vector <int> nums;
- nums.push_back(m_num);
-
- events::messageChangedEvent event
- (folder, events::messageChangedEvent::TYPE_FLAGS, nums);
-
- for (std::list <IMAPFolder*>::iterator it = folder->m_store.acquire()->m_folders.begin() ;
- it != folder->m_store.acquire()->m_folders.end() ; ++it)
- {
- if ((*it)->getFullPath() == folder->m_path)
- (*it)->notifyMessageChanged(event);
- }
- }
+ folder->setMessageFlags(m_num, m_num, flags, mode);
}
@@ -711,6 +613,18 @@ ref <vmime::message> IMAPMessage::getParsedMessage()
}
+void IMAPMessage::renumber(const int number)
+{
+ m_num = number;
+}
+
+
+void IMAPMessage::setExpunged()
+{
+ m_expunged = true;
+}
+
+
} // imap
} // net
} // vmime
diff --git a/src/net/maildir/maildirFolder.cpp b/src/net/maildir/maildirFolder.cpp
index 3ea1093e..3042d4b5 100644
--- a/src/net/maildir/maildirFolder.cpp
+++ b/src/net/maildir/maildirFolder.cpp
@@ -215,9 +215,10 @@ void maildirFolder::create(const int /* type */)
}
// Notify folder created
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_CREATED, m_path, m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_CREATED, m_path, m_path);
notifyFolder(event);
}
@@ -243,9 +244,10 @@ void maildirFolder::destroy()
}
// Notify folder deleted
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_DELETED, m_path, m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_DELETED, m_path, m_path);
notifyFolder(event);
}
@@ -548,9 +550,10 @@ void maildirFolder::rename(const folder::path& newPath)
m_path = newPath;
m_name = newPath.getLastComponent();
- events::folderEvent event
- (thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_RENAMED, oldPath, newPath);
notifyFolder(event);
@@ -563,9 +566,10 @@ void maildirFolder::rename(const folder::path& newPath)
(*it)->m_path = newPath;
(*it)->m_name = newPath.getLastComponent();
- events::folderEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_RENAMED, oldPath, newPath);
(*it)->notifyFolder(event);
}
@@ -575,9 +579,10 @@ void maildirFolder::rename(const folder::path& newPath)
(*it)->m_path.renameParent(oldPath, newPath);
- events::folderEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
+ ref <events::folderEvent> event =
+ vmime::create <events::folderEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
(*it)->notifyFolder(event);
}
@@ -684,9 +689,10 @@ void maildirFolder::setMessageFlags
}
// Notify message flags changed
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
+ ref <events::messageChangedEvent> event =
+ vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS, nums);
notifyMessageChanged(event);
@@ -767,9 +773,10 @@ void maildirFolder::setMessageFlags
}
// Notify message flags changed
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
+ ref <events::messageChangedEvent> event =
+ vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS, nums);
notifyMessageChanged(event);
@@ -906,9 +913,10 @@ void maildirFolder::addMessage(utility::inputStream& is, const int size,
std::vector <int> nums;
nums.push_back(m_messageCount);
- events::messageCountEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
notifyMessageCount(event);
@@ -924,9 +932,10 @@ void maildirFolder::addMessage(utility::inputStream& is, const int size,
(*it)->m_messageInfos.resize(m_messageInfos.size());
std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
- events::messageCountEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
(*it)->notifyMessageCount(event);
}
@@ -1196,9 +1205,10 @@ ref <folderStatus> maildirFolder::getStatus()
for (int i = oldCount + 1, j = 0 ; i <= m_messageCount ; ++i, ++j)
nums[j] = i;
- events::messageCountEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
notifyMessageCount(event);
@@ -1214,9 +1224,10 @@ ref <folderStatus> maildirFolder::getStatus()
(*it)->m_messageInfos.resize(m_messageInfos.size());
std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
- events::messageCountEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
(*it)->notifyMessageCount(event);
}
@@ -1289,9 +1300,10 @@ void maildirFolder::expunge()
m_unreadMessageCount -= unreadCount;
// Notify message expunged
- events::messageCountEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_REMOVED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_REMOVED, nums);
notifyMessageCount(event);
@@ -1307,9 +1319,10 @@ void maildirFolder::expunge()
(*it)->m_messageInfos.resize(m_messageInfos.size());
std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
- events::messageCountEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_REMOVED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_REMOVED, nums);
(*it)->notifyMessageCount(event);
}
diff --git a/src/net/maildir/maildirFolderStatus.cpp b/src/net/maildir/maildirFolderStatus.cpp
index 49425e59..bc00ba28 100644
--- a/src/net/maildir/maildirFolderStatus.cpp
+++ b/src/net/maildir/maildirFolderStatus.cpp
@@ -35,6 +35,21 @@ namespace net {
namespace maildir {
+maildirFolderStatus::maildirFolderStatus()
+ : m_count(0),
+ m_unseen(0)
+{
+}
+
+
+maildirFolderStatus::maildirFolderStatus(const maildirFolderStatus& other)
+ : folderStatus(),
+ m_count(other.m_count),
+ m_unseen(other.m_unseen)
+{
+}
+
+
unsigned int maildirFolderStatus::getMessageCount() const
{
return m_count;
@@ -59,6 +74,12 @@ void maildirFolderStatus::setUnseenCount(const unsigned int unseen)
}
+ref <folderStatus> maildirFolderStatus::clone() const
+{
+ return vmime::create <maildirFolderStatus>(*this);
+}
+
+
} // maildir
} // net
} // vmime
diff --git a/src/net/pop3/POP3Folder.cpp b/src/net/pop3/POP3Folder.cpp
index 1b7b3df6..9dc4589b 100644
--- a/src/net/pop3/POP3Folder.cpp
+++ b/src/net/pop3/POP3Folder.cpp
@@ -591,9 +591,10 @@ void POP3Folder::deleteMessage(const int num)
std::vector <int> nums;
nums.push_back(num);
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
+ ref <events::messageChangedEvent> event =
+ vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS, nums);
notifyMessageChanged(event);
}
@@ -640,9 +641,10 @@ void POP3Folder::deleteMessages(const int from, const int to)
for (int i = from ; i <= to2 ; ++i)
nums.push_back(i);
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, nums);
+ ref <events::messageChangedEvent> event =
+ vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS, nums);
notifyMessageChanged(event);
}
@@ -691,9 +693,10 @@ void POP3Folder::deleteMessages(const std::vector <int>& nums)
}
// Notify message flags changed
- events::messageChangedEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageChangedEvent::TYPE_FLAGS, list);
+ ref <events::messageChangedEvent> event =
+ vmime::create <events::messageChangedEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageChangedEvent::TYPE_FLAGS, list);
notifyMessageChanged(event);
}
@@ -805,9 +808,10 @@ ref <folderStatus> POP3Folder::getStatus()
nums[j] = i;
// Notify message count changed
- events::messageCountEvent event
- (thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ (thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
notifyMessageCount(event);
@@ -819,9 +823,10 @@ ref <folderStatus> POP3Folder::getStatus()
{
(*it)->m_messageCount = count;
- events::messageCountEvent event
- ((*it)->thisRef().dynamicCast <folder>(),
- events::messageCountEvent::TYPE_ADDED, nums);
+ ref <events::messageCountEvent> event =
+ vmime::create <events::messageCountEvent>
+ ((*it)->thisRef().dynamicCast <folder>(),
+ events::messageCountEvent::TYPE_ADDED, nums);
(*it)->notifyMessageCount(event);
}
diff --git a/src/net/pop3/POP3FolderStatus.cpp b/src/net/pop3/POP3FolderStatus.cpp
index e8c5face..64c8d9d1 100644
--- a/src/net/pop3/POP3FolderStatus.cpp
+++ b/src/net/pop3/POP3FolderStatus.cpp
@@ -35,6 +35,21 @@ namespace net {
namespace pop3 {
+POP3FolderStatus::POP3FolderStatus()
+ : m_count(0),
+ m_unseen(0)
+{
+}
+
+
+POP3FolderStatus::POP3FolderStatus(const POP3FolderStatus& other)
+ : folderStatus(),
+ m_count(other.m_count),
+ m_unseen(other.m_unseen)
+{
+}
+
+
unsigned int POP3FolderStatus::getMessageCount() const
{
return m_count;
@@ -59,6 +74,12 @@ void POP3FolderStatus::setUnseenCount(const unsigned int unseen)
}
+ref <folderStatus> POP3FolderStatus::clone() const
+{
+ return vmime::create <POP3FolderStatus>(*this);
+}
+
+
} // pop3
} // net
} // vmime
diff --git a/vmime/net/events.hpp b/vmime/net/events.hpp
index d42f3c1c..1e5fd7f3 100644
--- a/vmime/net/events.hpp
+++ b/vmime/net/events.hpp
@@ -44,13 +44,30 @@ class folder;
namespace events {
+/** Event occurring on folders or messages.
+ */
+
+class VMIME_EXPORT event : public object
+{
+public:
+
+ event();
+ virtual ~event();
+
+ virtual const char* getClass() const = 0;
+};
+
+
/** Event about the message count in a folder.
*/
-class VMIME_EXPORT messageCountEvent
+class VMIME_EXPORT messageCountEvent : public event
{
public:
+ static const char* EVENT_CLASS;
+
+
enum Types
{
TYPE_ADDED, /**< New messages have been added. */
@@ -82,7 +99,10 @@ public:
*
* @param listener listener to notify
*/
- void dispatch(class messageCountListener* listener) const;
+ void dispatch(class messageCountListener* listener);
+
+
+ const char* getClass() const;
private:
@@ -103,18 +123,21 @@ protected:
public:
- virtual void messagesAdded(const messageCountEvent& event) = 0;
- virtual void messagesRemoved(const messageCountEvent& event) = 0;
+ virtual void messagesAdded(ref <messageCountEvent> event) = 0;
+ virtual void messagesRemoved(ref <messageCountEvent> event) = 0;
};
/** Event occuring on a message.
*/
-class VMIME_EXPORT messageChangedEvent
+class VMIME_EXPORT messageChangedEvent : public event
{
public:
+ static const char* EVENT_CLASS;
+
+
enum Types
{
TYPE_FLAGS // flags changed
@@ -145,7 +168,10 @@ public:
*
* @param listener listener to notify
*/
- void dispatch(class messageChangedListener* listener) const;
+ void dispatch(class messageChangedListener* listener);
+
+
+ const char* getClass() const;
private:
@@ -166,17 +192,20 @@ protected:
public:
- virtual void messageChanged(const messageChangedEvent& event) = 0;
+ virtual void messageChanged(ref <messageChangedEvent> event) = 0;
};
/** Event occuring on a folder.
*/
-class VMIME_EXPORT folderEvent
+class VMIME_EXPORT folderEvent : public event
{
public:
+ static const char* EVENT_CLASS;
+
+
enum Types
{
TYPE_CREATED, /**< A folder was created. */
@@ -203,7 +232,10 @@ public:
*
* @param listener listener to notify
*/
- void dispatch(class folderListener* listener) const;
+ void dispatch(class folderListener* listener);
+
+
+ const char* getClass() const;
private:
@@ -225,9 +257,9 @@ protected:
public:
- virtual void folderCreated(const folderEvent& event) = 0;
- virtual void folderRenamed(const folderEvent& event) = 0;
- virtual void folderDeleted(const folderEvent& event) = 0;
+ virtual void folderCreated(ref <folderEvent> event) = 0;
+ virtual void folderRenamed(ref <folderEvent> event) = 0;
+ virtual void folderDeleted(ref <folderEvent> event) = 0;
};
diff --git a/vmime/net/folder.hpp b/vmime/net/folder.hpp
index 6c0a3a3a..4cb6bb1a 100644
--- a/vmime/net/folder.hpp
+++ b/vmime/net/folder.hpp
@@ -437,9 +437,10 @@ public:
protected:
- void notifyMessageChanged(const events::messageChangedEvent& event);
- void notifyMessageCount(const events::messageCountEvent& event);
- void notifyFolder(const events::folderEvent& event);
+ void notifyMessageChanged(ref <events::messageChangedEvent> event);
+ void notifyMessageCount(ref <events::messageCountEvent> event);
+ void notifyFolder(ref <events::folderEvent> event);
+ void notifyEvent(ref <events::event> event);
private:
diff --git a/vmime/net/folderStatus.hpp b/vmime/net/folderStatus.hpp
index 90beea66..f4cc62fc 100644
--- a/vmime/net/folderStatus.hpp
+++ b/vmime/net/folderStatus.hpp
@@ -56,6 +56,12 @@ public:
* @return number of unseen messages
*/
virtual unsigned int getUnseenCount() const = 0;
+
+ /** Clones this object.
+ *
+ * @return a copy of this object
+ */
+ virtual ref <folderStatus> clone() const = 0;
};
diff --git a/vmime/net/imap/IMAPFolder.hpp b/vmime/net/imap/IMAPFolder.hpp
index 88a52523..d7ad19ee 100644
--- a/vmime/net/imap/IMAPFolder.hpp
+++ b/vmime/net/imap/IMAPFolder.hpp
@@ -138,6 +138,15 @@ public:
int getFetchCapabilities() const;
+ /** Returns the highest modification sequence of this folder, ie the
+ * modification sequence of the last message that changed in this
+ * folder.
+ *
+ * @return modification sequence, or zero if not supported by
+ * the underlying protocol
+ */
+ vmime_uint64 getHighestModSequence() const;
+
private:
void registerMessage(IMAPMessage* msg);
diff --git a/vmime/net/imap/IMAPFolderStatus.hpp b/vmime/net/imap/IMAPFolderStatus.hpp
index 77373f1a..bcd6415e 100644
--- a/vmime/net/imap/IMAPFolderStatus.hpp
+++ b/vmime/net/imap/IMAPFolderStatus.hpp
@@ -49,11 +49,14 @@ class VMIME_EXPORT IMAPFolderStatus : public folderStatus
public:
IMAPFolderStatus();
+ IMAPFolderStatus(const IMAPFolderStatus& other);
// Inherited from folderStatus
unsigned int getMessageCount() const;
unsigned int getUnseenCount() const;
+ ref <folderStatus> clone() const;
+
/** Returns the the number of messages with the Recent flag set.
*
* @return number of messages flagged Recent
@@ -89,14 +92,16 @@ public:
/** Reads the folder status from the specified IMAP response.
*
* @param resp parsed IMAP response
+ * @return true if the status changed, or false otherwise
*/
- void updateFromResponse(const IMAPParser::mailbox_data* resp);
+ bool updateFromResponse(const IMAPParser::mailbox_data* resp);
/** Reads the folder status from the specified IMAP response.
*
* @param resp parsed IMAP response
+ * @return true if the status changed, or false otherwise
*/
- void updateFromResponse(const IMAPParser::resp_text_code* resp);
+ bool updateFromResponse(const IMAPParser::resp_text_code* resp);
private:
diff --git a/vmime/net/imap/IMAPMessage.hpp b/vmime/net/imap/IMAPMessage.hpp
index fdda139a..59f9fc83 100644
--- a/vmime/net/imap/IMAPMessage.hpp
+++ b/vmime/net/imap/IMAPMessage.hpp
@@ -101,7 +101,25 @@ public:
private:
- void processFetchResponse(const int options, const IMAPParser::message_data* msgData);
+ /** Renumbers the message.
+ *
+ * @param number new sequence number
+ */
+ void renumber(const int number);
+
+ /** Marks the message as expunged.
+ */
+ void setExpunged();
+
+ /** Processes the parsed response to fill in the attributes
+ * and metadata of this message.
+ *
+ * @param options one or more fetch options (see folder::FetchOptions)
+ * @param msgData pointer to message_data component of the parsed response
+ * @return a combination of flags that specify what changed exactly on
+ * this message (see events::messageChangedEvent::Types)
+ */
+ int processFetchResponse(const int options, const IMAPParser::message_data* msgData);
/** Recursively fetch part header for all parts in the structure.
*
diff --git a/vmime/net/maildir/maildirFolderStatus.hpp b/vmime/net/maildir/maildirFolderStatus.hpp
index 80018b14..28e01f11 100644
--- a/vmime/net/maildir/maildirFolderStatus.hpp
+++ b/vmime/net/maildir/maildirFolderStatus.hpp
@@ -46,10 +46,16 @@ class VMIME_EXPORT maildirFolderStatus : public folderStatus
{
public:
+ maildirFolderStatus();
+ maildirFolderStatus(const maildirFolderStatus& other);
+
// Inherited from folderStatus
unsigned int getMessageCount() const;
unsigned int getUnseenCount() const;
+ ref <folderStatus> clone() const;
+
+
void setMessageCount(const unsigned int count);
void setUnseenCount(const unsigned int unseen);
diff --git a/vmime/net/message.hpp b/vmime/net/message.hpp
index a0f79aae..76bfb16b 100644
--- a/vmime/net/message.hpp
+++ b/vmime/net/message.hpp
@@ -217,8 +217,8 @@ public:
*/
virtual int getSize() const = 0;
- /** Check whether this message has been expunged
- * (ie: definitively deleted).
+ /** Check whether this message has been expunged (ie: definitively
+ * deleted) and does not exist in the folder anymore.
*
* @return true if the message is expunged, false otherwise
*/
diff --git a/vmime/net/pop3/POP3FolderStatus.hpp b/vmime/net/pop3/POP3FolderStatus.hpp
index 3e5d15a1..d074ff47 100644
--- a/vmime/net/pop3/POP3FolderStatus.hpp
+++ b/vmime/net/pop3/POP3FolderStatus.hpp
@@ -46,10 +46,16 @@ class VMIME_EXPORT POP3FolderStatus : public folderStatus
{
public:
+ POP3FolderStatus();
+ POP3FolderStatus(const POP3FolderStatus& other);
+
// Inherited from folderStatus
unsigned int getMessageCount() const;
unsigned int getUnseenCount() const;
+ ref <folderStatus> clone() const;
+
+
void setMessageCount(const unsigned int count);
void setUnseenCount(const unsigned int unseen);