aboutsummaryrefslogtreecommitdiffstats
path: root/src/messaging/maildirFolder.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2004-12-21 20:49:45 +0000
committerVincent Richard <[email protected]>2004-12-21 20:49:45 +0000
commit3c1221f064e5d06ad0cdcf65debacd706f8268b7 (patch)
treeb8f89b31512f18cb6607d7871508271bda646368 /src/messaging/maildirFolder.cpp
parentDone addMessage() operation for 'maildir'. (diff)
downloadvmime-3c1221f064e5d06ad0cdcf65debacd706f8268b7.tar.gz
vmime-3c1221f064e5d06ad0cdcf65debacd706f8268b7.zip
Done copyMessage() operation for 'maildir'.
Diffstat (limited to 'src/messaging/maildirFolder.cpp')
-rw-r--r--src/messaging/maildirFolder.cpp242
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());
}
}
}