diff options
Diffstat (limited to '')
-rw-r--r-- | src/net/imap/IMAPFolder.cpp | 158 |
1 files changed, 101 insertions, 57 deletions
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp index f28fa8a3..0179620b 100644 --- a/src/net/imap/IMAPFolder.cpp +++ b/src/net/imap/IMAPFolder.cpp @@ -39,23 +39,25 @@ namespace net { namespace imap { -IMAPFolder::IMAPFolder(const folder::path& path, IMAPStore* store, const int type, const int flags) - : m_store(store), m_connection(m_store->connection()), m_path(path), +IMAPFolder::IMAPFolder(const folder::path& path, ref <IMAPStore> store, const int type, const int flags) + : m_store(store), m_connection(store->connection()), m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1), m_open(false), m_type(type), m_flags(flags), m_messageCount(0), m_uidValidity(0) { - m_store->registerFolder(this); + store->registerFolder(this); } IMAPFolder::~IMAPFolder() { - if (m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (store) { if (m_open) close(false); - m_store->unregisterFolder(this); + store->unregisterFolder(this); } else if (m_open) { @@ -128,12 +130,14 @@ const folder::path IMAPFolder::getFullPath() const void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); // Open a connection for this folder ref <IMAPConnection> connection = - vmime::create <IMAPConnection>(m_store, m_store->getAuthenticator()); + vmime::create <IMAPConnection>(store, store->getAuthenticator()); try { @@ -270,7 +274,9 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) void IMAPFolder::close(const bool expunge) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); if (!isOpen()) @@ -292,7 +298,7 @@ void IMAPFolder::close(const bool expunge) oldConnection->disconnect(); // Now use default store connection - m_connection = m_store->connection(); + m_connection = m_store.acquire()->connection(); m_open = false; m_mode = -1; @@ -317,13 +323,15 @@ void IMAPFolder::onClose() void IMAPFolder::create(const int type) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (isOpen()) throw exceptions::illegal_state("Folder is open"); else if (exists()) throw exceptions::illegal_state("Folder already exists"); - else if (!m_store->isValidFolderName(m_name)) + else if (!store->isValidFolderName(m_name)) throw exceptions::invalid_folder_name(); // Emit the "CREATE" command @@ -365,7 +373,9 @@ void IMAPFolder::create(const int type) const bool IMAPFolder::exists() { - if (!isOpen() && !m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!isOpen() && !store) throw exceptions::illegal_state("Store disconnected"); return (testExistAndGetType() != TYPE_UNDEFINED); @@ -458,7 +468,7 @@ ref <message> IMAPFolder::getMessage(const int num) if (num < 1 || num > m_messageCount) throw exceptions::message_not_found(); - return vmime::create <IMAPMessage>(this, num); + return vmime::create <IMAPMessage>(thisRef().dynamicCast <IMAPFolder>(), num); } @@ -473,9 +483,10 @@ std::vector <ref <message> > IMAPFolder::getMessages(const int from, const int t 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>(this, i)); + v.push_back(vmime::create <IMAPMessage>(thisFolder, i)); return (v); } @@ -487,9 +498,10 @@ std::vector <ref <message> > IMAPFolder::getMessages(const std::vector <int>& nu 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>(this, *it)); + v.push_back(vmime::create <IMAPMessage>(thisFolder, *it)); return (v); } @@ -506,16 +518,20 @@ const int IMAPFolder::getMessageCount() ref <folder> IMAPFolder::getFolder(const folder::path::component& name) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); - return vmime::create <IMAPFolder>(m_path / name, m_store); + return vmime::create <IMAPFolder>(m_path / name, store); } std::vector <ref <folder> > IMAPFolder::getFolders(const bool recursive) { - if (!isOpen() && !m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!isOpen() && !store) throw exceptions::illegal_state("Store disconnected"); // Eg. List folders in '/foo/bar' @@ -591,7 +607,7 @@ std::vector <ref <folder> > IMAPFolder::getFolders(const bool recursive) const class IMAPParser::mailbox_flag_list* mailbox_flag_list = mailboxData->mailbox_list()->mailbox_flag_list(); - v.push_back(vmime::create <IMAPFolder>(path, m_store, + v.push_back(vmime::create <IMAPFolder>(path, store, IMAPUtils::folderTypeFromFlags(mailbox_flag_list), IMAPUtils::folderFlagsFromFlags(mailbox_flag_list))); } @@ -604,7 +620,9 @@ std::vector <ref <folder> > IMAPFolder::getFolders(const bool recursive) void IMAPFolder::fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -691,12 +709,14 @@ void IMAPFolder::fetchMessages(std::vector <ref <message> >& msg, const int opti void IMAPFolder::fetchMessage(ref <message> msg, const int options) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); - msg.dynamicCast <IMAPMessage>()->fetch(this, options); + msg.dynamicCast <IMAPMessage>()->fetch(thisRef().dynamicCast <IMAPFolder>(), options); } @@ -713,19 +733,19 @@ ref <folder> IMAPFolder::getParent() if (m_path.isEmpty()) return NULL; else - return vmime::create <IMAPFolder>(m_path.getParent(), m_store); + return vmime::create <IMAPFolder>(m_path.getParent(), m_store.acquire()); } -weak_ref <const store> IMAPFolder::getStore() const +ref <const store> IMAPFolder::getStore() const { - return (m_store); + return m_store.acquire(); } -weak_ref <store> IMAPFolder::getStore() +ref <store> IMAPFolder::getStore() { - return (m_store); + return m_store.acquire(); } @@ -753,7 +773,9 @@ void IMAPFolder::onStoreDisconnected() void IMAPFolder::deleteMessage(const int num) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -802,10 +824,12 @@ void IMAPFolder::deleteMessage(const int num) void IMAPFolder::deleteMessages(const int from, const int to) { + ref <IMAPStore> store = m_store.acquire(); + if (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); - if (!m_store) + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -865,10 +889,12 @@ void IMAPFolder::deleteMessages(const int from, const int to) void IMAPFolder::deleteMessages(const std::vector <int>& nums) { + ref <IMAPStore> store = m_store.acquire(); + if (nums.empty()) throw exceptions::invalid_argument(); - if (!m_store) + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -924,10 +950,12 @@ void IMAPFolder::deleteMessages(const std::vector <int>& nums) 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 (!m_store) + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1012,7 +1040,9 @@ void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, void IMAPFolder::setMessageFlags(const std::vector <int>& nums, const int flags, const int mode) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1142,7 +1172,9 @@ void IMAPFolder::addMessage(ref <vmime::message> msg, const int flags, void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int flags, vmime::datetime* date, utility::progressListener* progress) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1243,8 +1275,8 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int notifyMessageCount(event); // Notify folders with the same path - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { @@ -1261,7 +1293,9 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int void IMAPFolder::expunge() { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1330,8 +1364,8 @@ void IMAPFolder::expunge() notifyMessageCount(event); // Notify folders with the same path - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { @@ -1349,13 +1383,15 @@ void IMAPFolder::expunge() void IMAPFolder::rename(const folder::path& newPath) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (m_path.isEmpty() || newPath.isEmpty()) throw exceptions::illegal_operation("Cannot rename root folder"); else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX") throw exceptions::illegal_operation("Cannot rename 'INBOX' folder"); - else if (!m_store->isValidFolderName(newPath.getLastComponent())) + else if (!store->isValidFolderName(newPath.getLastComponent())) throw exceptions::invalid_folder_name(); // Build the request text @@ -1392,8 +1428,8 @@ void IMAPFolder::rename(const folder::path& newPath) notifyFolder(event); // Notify folders with the same path and sub-folders - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == oldPath) { @@ -1424,7 +1460,9 @@ void IMAPFolder::rename(const folder::path& newPath) void IMAPFolder::copyMessage(const folder::path& dest, const int num) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1440,8 +1478,8 @@ void IMAPFolder::copyMessage(const folder::path& dest, const int num) std::vector <int> nums; nums.push_back(num); - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { @@ -1458,7 +1496,9 @@ void IMAPFolder::copyMessage(const folder::path& dest, const int num) void IMAPFolder::copyMessages(const folder::path& dest, const int from, const int to) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1486,8 +1526,8 @@ void IMAPFolder::copyMessages(const folder::path& dest, const int from, const in for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) nums[j] = i; - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { @@ -1504,7 +1544,9 @@ void IMAPFolder::copyMessages(const folder::path& dest, const int from, const in void IMAPFolder::copyMessages(const folder::path& dest, const std::vector <int>& nums) { - if (!m_store) + ref <IMAPStore> store = m_store.acquire(); + + if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -1515,8 +1557,8 @@ void IMAPFolder::copyMessages(const folder::path& dest, const std::vector <int>& // Notify message count changed const int count = nums.size(); - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { @@ -1556,6 +1598,8 @@ void IMAPFolder::copyMessages(const string& set, const folder::path& dest) void IMAPFolder::status(int& count, int& unseen) { + ref <IMAPStore> store = m_store.acquire(); + count = 0; unseen = 0; @@ -1567,16 +1611,16 @@ void IMAPFolder::status(int& count, int& unseen) command << " (MESSAGES UNSEEN)"; // Send the request - m_store->m_connection->send(true, command.str(), true); + m_connection->send(true, command.str(), true); // Get the response - utility::auto_ptr <IMAPParser::response> resp(m_store->m_connection->readResponse()); + 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("STATUS", - m_store->m_connection->getParser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = @@ -1588,7 +1632,7 @@ void IMAPFolder::status(int& count, int& unseen) if ((*it)->response_data() == NULL) { throw exceptions::command_error("STATUS", - m_store->m_connection->getParser()->lastLine(), "invalid response"); + m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::response_data* responseData = (*it)->response_data(); @@ -1644,8 +1688,8 @@ void IMAPFolder::status(int& count, int& unseen) notifyMessageCount(event); // Notify folders with the same path - for (std::list <IMAPFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; + it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { |