diff options
author | Vincent Richard <[email protected]> | 2004-12-21 20:49:45 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2004-12-21 20:49:45 +0000 |
commit | 3c1221f064e5d06ad0cdcf65debacd706f8268b7 (patch) | |
tree | b8f89b31512f18cb6607d7871508271bda646368 /src/messaging/maildirFolder.cpp | |
parent | Done addMessage() operation for 'maildir'. (diff) | |
download | vmime-3c1221f064e5d06ad0cdcf65debacd706f8268b7.tar.gz vmime-3c1221f064e5d06ad0cdcf65debacd706f8268b7.zip |
Done copyMessage() operation for 'maildir'.
Diffstat (limited to 'src/messaging/maildirFolder.cpp')
-rw-r--r-- | src/messaging/maildirFolder.cpp | 242 |
1 files changed, 188 insertions, 54 deletions
diff --git a/src/messaging/maildirFolder.cpp b/src/messaging/maildirFolder.cpp index c950815e..fb511785 100644 --- a/src/messaging/maildirFolder.cpp +++ b/src/messaging/maildirFolder.cpp @@ -809,18 +809,66 @@ void maildirFolder::addMessage(utility::inputStream& is, const int size, // Don't throw now, it will fail later... } + // Actually add the message + copyMessageImpl(tmpDirPath, curDirPath, filename, is, size, progress); + + // Append the message to the cache list + messageInfos msgInfos; + msgInfos.path = filename; + msgInfos.type = messageInfos::TYPE_CUR; + + m_messageInfos.push_back(msgInfos); + m_messageCount++; + + if ((flags == message::FLAG_UNDEFINED) || !(flags & message::FLAG_SEEN)) + m_unreadMessageCount++; + + // Notification + std::vector <int> nums; + nums.push_back(m_messageCount); + + events::messageCountEvent event(this, events::messageCountEvent::TYPE_ADDED, nums); + + notifyMessageCount(event); + + // Notify folders with the same path + for (std::list <maildirFolder*>::iterator it = m_store->m_folders.begin() ; + it != m_store->m_folders.end() ; ++it) + { + if ((*it) != this && (*it)->getFullPath() == m_path) + { + (*it)->m_messageCount = m_messageCount; + (*it)->m_unreadMessageCount = m_unreadMessageCount; + + (*it)->m_messageInfos.resize(m_messageInfos.size()); + std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); + + events::messageCountEvent event(*it, events::messageCountEvent::TYPE_ADDED, nums); + + (*it)->notifyMessageCount(event); + } + } +} + + +void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, + const utility::file::path& curDirPath, const utility::file::path::component& filename, + utility::inputStream& is, const utility::stream::size_type size, progressionListener* progress) +{ + utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); + + utility::auto_ptr <utility::file> file = fsf->create(tmpDirPath / filename); + if (progress) progress->start(size); + // First, write the message into 'tmp'... try { - // Write the message into 'tmp' - utility::auto_ptr <utility::file> file = fsf->create(tmpDirPath / filename); - file->createFile(); - utility::fileWriter* fw = file->getFileWriter(); - utility::outputStream* os = fw->getOutputStream(); + utility::auto_ptr <utility::fileWriter> fw = file->getFileWriter(); + utility::auto_ptr <utility::outputStream> os = fw->getOutputStream(); utility::stream::value_type buffer[65536]; utility::stream::size_type total = 0; @@ -838,60 +886,52 @@ void maildirFolder::addMessage(utility::inputStream& is, const int size, if (progress) progress->progress(total, size); } - - delete (os); - delete (fw); - - // And move it to 'cur' - file->rename(curDirPath / filename); - - if (progress) - progress->stop(total); } catch (exception& e) { if (progress) progress->stop(size); + // Delete temporary file + try + { + utility::auto_ptr <utility::file> file = fsf->create(tmpDirPath / filename); + file->remove(); + } + catch (exceptions::filesystem_exception&) + { + // Ignore + } + throw exceptions::command_error("ADD", "", "", e); } - // Append the message to the cache list - messageInfos msgInfos; - msgInfos.path = filename; - msgInfos.type = messageInfos::TYPE_CUR; - - m_messageInfos.push_back(msgInfos); - m_messageCount++; - - if ((flags == message::FLAG_UNDEFINED) || !(flags & message::FLAG_SEEN)) - m_unreadMessageCount++; - - // Notification - std::vector <int> nums; - nums.push_back(m_messageCount); - - events::messageCountEvent event(this, events::messageCountEvent::TYPE_ADDED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list <maildirFolder*>::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) + // ...then, move it to 'cur' + try { - if ((*it) != this && (*it)->getFullPath() == m_path) - { - (*it)->m_messageCount = m_messageCount; - (*it)->m_unreadMessageCount = m_unreadMessageCount; - - events::messageCountEvent event(*it, events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->notifyMessageCount(event); + file->rename(curDirPath / filename); + } + catch (exception& e) + { + if (progress) + progress->stop(size); - (*it)->m_messageInfos.resize(m_messageInfos.size()); - std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); + // Delete temporary file + try + { + utility::auto_ptr <utility::file> file = fsf->create(tmpDirPath / filename); + file->remove(); + } + catch (exceptions::filesystem_exception&) + { + // Ignore } + + throw exceptions::command_error("ADD", "", "", e); } + + if (progress) + progress->stop(size); } @@ -915,7 +955,18 @@ void maildirFolder::copyMessages(const folder::path& dest, const int from, const else if (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); - // TODO + // Construct the list of message numbers + const int to2 = (to == -1) ? m_messageCount : to; + const int count = to - from + 1; + + std::vector <int> nums; + nums.resize(count); + + for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) + nums[j] = i; + + // Copy messages + copyMessagesImpl(dest, nums); } @@ -926,7 +977,90 @@ void maildirFolder::copyMessages(const folder::path& dest, const std::vector <in else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); - // TODO + // Copy messages + copyMessagesImpl(dest, nums); +} + + +void maildirFolder::copyMessagesImpl(const folder::path& dest, const std::vector <int>& nums) +{ + utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); + + utility::file::path curDirPath = maildirUtils::getFolderFSPath + (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); + + utility::file::path destCurDirPath = maildirUtils::getFolderFSPath + (m_store, dest, maildirUtils::FOLDER_PATH_CUR); + utility::file::path destTmpDirPath = maildirUtils::getFolderFSPath + (m_store, dest, maildirUtils::FOLDER_PATH_TMP); + + // Create destination directories + try + { + utility::auto_ptr <utility::file> destTmpDir = fsf->create(destTmpDirPath); + destTmpDir->createDirectory(true); + } + catch (exceptions::filesystem_exception&) + { + // Don't throw now, it will fail later... + } + + try + { + utility::auto_ptr <utility::file> destCurDir = fsf->create(destCurDirPath); + destCurDir->createDirectory(true); + } + catch (exceptions::filesystem_exception&) + { + // Don't throw now, it will fail later... + } + + // Copy messages + try + { + for (std::vector <int>::const_iterator it = + nums.begin() ; it != nums.end() ; ++it) + { + const int num = *it; + const messageInfos& msg = m_messageInfos[num - 1]; + const int flags = maildirUtils::extractFlags(msg.path); + + const utility::file::path::component filename = + maildirUtils::buildFilename(maildirUtils::generateId(), flags); + + utility::auto_ptr <utility::file> file = fsf->create(curDirPath / msg.path); + utility::auto_ptr <utility::fileReader> fr = file->getFileReader(); + utility::auto_ptr <utility::inputStream> is = fr->getInputStream(); + + copyMessageImpl(destTmpDirPath, destCurDirPath, + filename, *is, file->getLength(), NULL); + } + } + catch (exception& e) + { + notifyMessagesCopied(dest); + throw exceptions::command_error("COPY", "", "", e); + } + + notifyMessagesCopied(dest); +} + + +void maildirFolder::notifyMessagesCopied(const folder::path& dest) +{ + for (std::list <maildirFolder*>::iterator it = m_store->m_folders.begin() ; + it != m_store->m_folders.end() ; ++it) + { + if ((*it) != this && (*it)->getFullPath() == dest) + { + // We only need to update the first folder we found as calling + // status() will notify all the folders with the same path. + int count, unseen; + (*it)->status(count, unseen); + + return; + } + } } @@ -961,12 +1095,12 @@ void maildirFolder::status(int& count, int& unseen) (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; + (*it)->m_messageInfos.resize(m_messageInfos.size()); + std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); + events::messageCountEvent event(*it, events::messageCountEvent::TYPE_ADDED, nums); (*it)->notifyMessageCount(event); - - (*it)->m_messageInfos.resize(m_messageInfos.size()); - std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); } } } @@ -1046,12 +1180,12 @@ void maildirFolder::expunge() (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; + (*it)->m_messageInfos.resize(m_messageInfos.size()); + std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); + events::messageCountEvent event(*it, events::messageCountEvent::TYPE_REMOVED, nums); (*it)->notifyMessageCount(event); - - (*it)->m_messageInfos.resize(m_messageInfos.size()); - std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); } } } |