Working on 'maildir' implementation.

This commit is contained in:
Vincent Richard 2004-12-04 20:25:48 +00:00
parent 31cd25b5b0
commit e4ed55e237
6 changed files with 184 additions and 30 deletions

View File

@ -500,9 +500,7 @@ void maildirFolder::deleteMessage(const int num)
if (m_messageInfos[num].type == messageInfos::TYPE_DELETED)
return;
m_messageInfos[num].type = messageInfos::TYPE_DELETED;
// Delete file from file system
// Mark message as deleted
try
{
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
@ -510,10 +508,17 @@ void maildirFolder::deleteMessage(const int num)
utility::file::path curDirPath = maildirUtils::getFolderFSPath
(m_store, m_path, maildirUtils::FOLDER_PATH_CUR);
utility::auto_ptr <utility::file> file = fsf->create
(curDirPath / m_messageInfos[num].path);
const utility::file::path::component path = m_messageInfos[num].path;
utility::auto_ptr <utility::file> file = fsf->create(curDirPath / path);
file->remove();
const utility::file::path::component newPath = maildirUtils::buildFilename
(maildirUtils::extractId(path),
maildirUtils::extractFlags(path) | message::FLAG_DELETED);
file->rename(curDirPath / newPath);
m_messageInfos[num].type = messageInfos::TYPE_DELETED;
m_messageInfos[num].path = newPath;
}
catch (exceptions::filesystem_exception& e)
{
@ -556,7 +561,7 @@ void maildirFolder::deleteMessages(const int from, const int to)
const int to2 = (to == -1) ? m_messageCount : to;
const int count = to - from + 1;
// Delete files from file system
// Mark messages as deleted
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
utility::file::path curDirPath = maildirUtils::getFolderFSPath
@ -566,14 +571,19 @@ void maildirFolder::deleteMessages(const int from, const int to)
{
if (m_messageInfos[i].type != messageInfos::TYPE_DELETED)
{
m_messageInfos[i].type = messageInfos::TYPE_DELETED;
try
{
utility::auto_ptr <utility::file> file = fsf->create
(curDirPath / m_messageInfos[i].path);
const utility::file::path::component path = m_messageInfos[i].path;
utility::auto_ptr <utility::file> file = fsf->create(curDirPath / path);
file->remove();
const utility::file::path::component newPath = maildirUtils::buildFilename
(maildirUtils::extractId(path),
maildirUtils::extractFlags(path) | message::FLAG_DELETED);
file->rename(curDirPath / newPath);
m_messageInfos[i].type = messageInfos::TYPE_DELETED;
m_messageInfos[i].path = newPath;
}
catch (exceptions::filesystem_exception& e)
{
@ -626,7 +636,7 @@ void maildirFolder::deleteMessages(const std::vector <int>& nums)
std::sort(list.begin(), list.end());
// Delete files from file system
// Mark messages as deleted
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
utility::file::path curDirPath = maildirUtils::getFolderFSPath
@ -639,14 +649,20 @@ void maildirFolder::deleteMessages(const std::vector <int>& nums)
if (m_messageInfos[num].type != messageInfos::TYPE_DELETED)
{
m_messageInfos[num].type = messageInfos::TYPE_DELETED;
try
{
const utility::file::path::component path = m_messageInfos[num].path;
utility::auto_ptr <utility::file> file = fsf->create
(curDirPath / m_messageInfos[num].path);
file->remove();
const utility::file::path::component newPath = maildirUtils::buildFilename
(maildirUtils::extractId(path),
maildirUtils::extractFlags(path) | message::FLAG_DELETED);
file->rename(curDirPath / newPath);
m_messageInfos[num].type = messageInfos::TYPE_DELETED;
m_messageInfos[num].path = newPath;
}
catch (exceptions::filesystem_exception& e)
{
@ -655,7 +671,6 @@ void maildirFolder::deleteMessages(const std::vector <int>& nums)
}
}
// Update local flags
for (std::vector <maildirMessage*>::iterator it =
m_messages.begin() ; it != m_messages.end() ; ++it)
@ -782,13 +797,39 @@ store* maildirFolder::getStore()
void maildirFolder::fetchMessages(std::vector <message*>& msg,
const int options, progressionListener* progress)
{
// TODO
if (!m_store)
throw exceptions::illegal_state("Store disconnected");
else if (!isOpen())
throw exceptions::illegal_state("Folder not open");
const int total = msg.size();
int current = 0;
if (progress)
progress->start(total);
for (std::vector <message*>::iterator it = msg.begin() ;
it != msg.end() ; ++it)
{
dynamic_cast <maildirMessage*>(*it)->fetch(this, options);
if (progress)
progress->progress(++current, total);
}
if (progress)
progress->stop(total);
}
void maildirFolder::fetchMessage(message* msg, const int options)
{
// TODO
if (!m_store)
throw exceptions::illegal_state("Store disconnected");
else if (!isOpen())
throw exceptions::illegal_state("Folder not open");
dynamic_cast <maildirMessage*>(msg)->fetch(this, options);
}
@ -799,5 +840,14 @@ const int maildirFolder::getFetchCapabilities() const
}
const utility::file::path maildirFolder::getMessageFSPath(const int number)
{
utility::file::path curDirPath = maildirUtils::getFolderFSPath
(m_store, m_path, maildirUtils::FOLDER_PATH_CUR);
return (curDirPath / m_messageInfos[number].path);
}
} // messaging
} // vmime

View File

@ -120,6 +120,8 @@ private:
void registerMessage(maildirMessage* msg);
void unregisterMessage(maildirMessage* msg);
const utility::file::path getMessageFSPath(const int number);
void onStoreDisconnected();
void onClose();

View File

@ -19,6 +19,10 @@
#include "maildirMessage.hpp"
#include "maildirFolder.hpp"
#include "maildirUtils.hpp"
#include "../exception.hpp"
#include "../platformDependant.hpp"
namespace vmime {
@ -26,7 +30,7 @@ namespace messaging {
maildirMessage::maildirMessage(maildirFolder* folder, const int num)
: m_folder(folder), m_num(num)
: m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED)
{
m_folder->registerMessage(this);
}
@ -47,61 +51,107 @@ void maildirMessage::onFolderClosed()
const int maildirMessage::getNumber() const
{
return (m_num);
}
const message::uid maildirMessage::getUniqueId() const
{
// TODO
}
const int maildirMessage::getSize() const
{
if (m_size == -1)
throw exceptions::unfetched_object();
return (m_size);
}
const bool maildirMessage::isExpunged() const
{
// TODO
}
const structure& maildirMessage::getStructure() const
{
// TODO
}
structure& maildirMessage::getStructure()
{
// TODO
}
const header& maildirMessage::getHeader() const
{
// TODO
}
const int maildirMessage::getFlags() const
{
if (m_flags == FLAG_UNDEFINED)
throw exceptions::unfetched_object();
return (m_flags);
}
void maildirMessage::setFlags(const int flags, const int mode)
{
// TODO
}
void maildirMessage::extract(utility::outputStream& os, progressionListener* progress, const int start, const int length) const
void maildirMessage::extract(utility::outputStream& os,
progressionListener* progress, const int start, const int length) const
{
// TODO
}
void maildirMessage::extractPart(const part& p, utility::outputStream& os, progressionListener* progress, const int start, const int length) const
void maildirMessage::extractPart(const part& p, utility::outputStream& os,
progressionListener* progress, const int start, const int length) const
{
// TODO
}
void maildirMessage::fetchPartHeader(part& p)
{
// TODO
}
void maildirMessage::fetch(maildirFolder* folder, const int options)
{
if (m_folder != folder)
throw exceptions::folder_not_found();
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
const utility::file::path path = folder->getMessageFSPath(m_num);
utility::auto_ptr <utility::file> file = fsf->create(path);
/*
TODO: FETCH_ENVELOPE
TODO: FETCH_STRUCTURE
TODO: FETCH_CONTENT_INFO
TODO: FETCH_FULL_HEADER
TODO: FETCH_UID
*/
if (options & folder::FETCH_FLAGS)
m_flags = maildirUtils::extractFlags(path.getLastComponent());
if (options & folder::FETCH_SIZE)
m_size = file->length();
}

View File

@ -69,7 +69,9 @@ public:
void fetchPartHeader(part& p);
protected:
private:
void fetch(maildirFolder* folder, const int options);
void onFolderClosed();

View File

@ -110,10 +110,11 @@ const int maildirUtils::extractFlags(const utility::file::path::component& comp)
{
switch (flagsString[i])
{
case 'S': case 's': flags |= message::FLAG_SEEN; break;
case 'R': case 'r': flags |= message::FLAG_REPLIED; break;
// TODO: more flags
case 'S': case 's': flags |= message::FLAG_SEEN; break;
case 'T': case 't': flags |= message::FLAG_DELETED; break;
case 'F': case 'f': flags |= message::FLAG_MARKED; break;
case 'P': case 'p': flags |= message::FLAG_PASSED; break;
}
}
@ -121,12 +122,33 @@ const int maildirUtils::extractFlags(const utility::file::path::component& comp)
}
/*
const utility::file::component maildirUtils::changeFlags
(const utility::file::component& comp, const int flags)
const utility::file::path::component maildirUtils::buildFlags(const int flags)
{
string str;
str.reserve(6);
if (flags & message::FLAG_REPLIED) str += "R";
if (flags & message::FLAG_SEEN) str += "S";
if (flags & message::FLAG_DELETED) str += "T";
if (flags & message::FLAG_MARKED) str += "F";
if (flags & message::FLAG_PASSED) str += "P";
return (utility::file::path::component(str));
}
const utility::file::path::component maildirUtils::buildFilename
(const utility::file::path::component& id, const int flags)
{
return (buildFilename(id, buildFlags(flags)));
}
const utility::file::path::component maildirUtils::buildFilename
(const utility::file::path::component& id, const utility::file::path::component& flags)
{
return (utility::path::component(id.getBuffer() + ":" + flags.getBuffer()));
}
*/

View File

@ -78,6 +78,7 @@ public:
* a maildir sub-folder. The name of the directory should not start
* with '.' to be listed as a sub-folder.
*
* @param file reference to a file-system directory
* @return true if the specified directory is a maildir sub-folder,
* false otherwise
*/
@ -87,6 +88,7 @@ public:
* Eg: for the filename "1071577232.28549.m03s:2,RS", it will
* return "1071577232.28549.m03s".
*
* @param filename filename part
* @return part of the filename that corresponds to the unique
* identifier of the message
*/
@ -96,10 +98,36 @@ public:
* Eg: for the filename "1071577232.28549.m03s:2,RS", it will
* return (message::FLAG_SEEN | message::FLAG_REPLIED).
*
* @param comp filename part
* @return message flags extracted from the specified filename
*/
static const int extractFlags(const utility::file::path::component& comp);
/** Return a string representing the specified message flags.
* Eg: for (message::FLAG_SEEN | message::FLAG_REPLIED), it will
* return "RS".
*
* @param flags set of flags
* @return message flags in a string representation
*/
static const utility::file::path::component buildFlags(const int flags);
/** Build a filename with the specified id and flags.
*
* @param id id part of the filename
* @param flags flags part of the filename
* @return message filename
*/
static const utility::file::path::component buildFilename(const utility::file::path::component& id, const utility::file::path::component& flags);
/** Build a filename with the specified id and flags.
*
* @param id id part of the filename
* @param flags set of flags
* @return message filename
*/
static const utility::file::path::component buildFilename(const utility::file::path::component& id, const int flags);
private:
static const vmime::word TMP_DIR;