Working on 'maildir' implementation.

This commit is contained in:
Vincent Richard 2004-12-15 22:17:03 +00:00
parent 50a6a9cdfa
commit 78b3909d9b
7 changed files with 269 additions and 65 deletions

View File

@ -32,31 +32,12 @@ namespace vmime {
namespace messaging {
//
// IMAPheader
//
class IMAPheader : public header
{
public:
IMAPheader()
{
}
void parse(const string& str)
{
header::parse(str);
}
};
//
// IMAPpart
//
class IMAPstructure;
class IMAPpart : public part
{
private:
@ -75,7 +56,13 @@ public:
const int getSize() const { return (m_size); }
const int getNumber() const { return (m_number); }
const header& getHeader() const;
const header& getHeader() const
{
if (m_header == NULL)
throw exceptions::unfetched_object();
else
return (*m_header);
}
static IMAPpart* create(IMAPpart* parent, const int number, const IMAPParser::body* body)
@ -87,19 +74,19 @@ public:
}
IMAPheader& getOrCreateHeader()
header& getOrCreateHeader()
{
if (m_header != NULL)
return (*m_header);
else
return (*(m_header = new IMAPheader()));
return (*(m_header = new header()));
}
private:
IMAPstructure* m_structure;
IMAPpart* m_parent;
IMAPheader* m_header;
header* m_header;
int m_number;
int m_size;
@ -112,7 +99,6 @@ private:
// IMAPstructure
//
class IMAPstructure : public structure
{
private:
@ -213,15 +199,6 @@ IMAPpart::IMAPpart(IMAPpart* parent, const int number, const IMAPParser::body_ty
}
const class header& IMAPpart::getHeader() const
{
if (m_header == NULL)
throw exceptions::unfetched_object();
else
return (*m_header);
}
const class structure& IMAPpart::getStructure() const
{
if (m_structure != NULL)
@ -297,7 +274,7 @@ IMAPMessage::~IMAPMessage()
if (m_folder)
m_folder->unregisterMessage(this);
delete dynamic_cast <IMAPheader*>(m_header);
delete dynamic_cast <header*>(m_header);
}
@ -674,7 +651,7 @@ void IMAPMessage::processFetchResponse
(*it)->section()->section_text1()->type()
== IMAPParser::section_text::HEADER_FIELDS)
{
IMAPheader tempHeader;
header tempHeader;
tempHeader.parse((*it)->nstring()->value());
vmime::header& hdr = getOrCreateHeader();
@ -706,12 +683,12 @@ void IMAPMessage::processFetchResponse
}
IMAPheader& IMAPMessage::getOrCreateHeader()
header& IMAPMessage::getOrCreateHeader()
{
if (m_header != NULL)
return (*m_header);
else
return (*(m_header = new IMAPheader()));
return (*(m_header = new header()));
}

View File

@ -30,10 +30,6 @@ namespace vmime {
namespace messaging {
class IMAPheader;
class IMAPstructure;
/** IMAP message implementation.
*/
@ -83,7 +79,7 @@ private:
void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest);
IMAPheader& getOrCreateHeader();
header& getOrCreateHeader();
void onFolderClosed();
@ -96,8 +92,8 @@ private:
bool m_expunged;
uid m_uid;
class IMAPheader* m_header;
class IMAPstructure* m_structure;
header* m_header;
structure* m_structure;
};

View File

@ -276,7 +276,7 @@ void maildirFolder::scanFolder()
while (nit->hasMoreElements())
{
utility::auto_ptr <utility::file> file = nit->nextElement();
newMessageFilenames.push_back(file->fullPath().getLastComponent());
newMessageFilenames.push_back(file->getFullPath().getLastComponent());
}
// Current messages (cur/)
@ -286,7 +286,7 @@ void maildirFolder::scanFolder()
while (cit->hasMoreElements())
{
utility::auto_ptr <utility::file> file = cit->nextElement();
curMessageFilenames.push_back(file->fullPath().getLastComponent());
curMessageFilenames.push_back(file->getFullPath().getLastComponent());
}
// Update/delete existing messages (found in previous scan)
@ -465,7 +465,7 @@ void maildirFolder::listFolders(std::vector <folder*>& list, const bool recursiv
if (maildirUtils::isSubfolderDirectory(*file))
{
const utility::path subPath = m_path / file->fullPath().getLastComponent();
const utility::path subPath = m_path / file->getFullPath().getLastComponent();
maildirFolder* subFolder = new maildirFolder(subPath, m_store);
list.push_back(subFolder);

View File

@ -29,9 +29,154 @@ namespace vmime {
namespace messaging {
//
// maildirPart
//
class maildirStructure;
class maildirPart : public part
{
public:
maildirPart(maildirPart* parent, const int number, const bodyPart& part);
const structure& getStructure() const;
structure& getStructure();
const maildirPart* getParent() const { return (m_parent); }
const mediaType& getType() const { return (m_mediaType); }
const int getSize() const { return (m_size); }
const int getNumber() const { return (m_number); }
const header& getHeader() const
{
if (m_header == NULL)
throw exceptions::unfetched_object();
else
return (*m_header);
}
header& getOrCreateHeader()
{
if (m_header != NULL)
return (*m_header);
else
return (*(m_header = new header()));
}
private:
maildirStructure* m_structure;
maildirPart* m_parent;
header* m_header;
int m_number;
int m_size;
mediaType m_mediaType;
int m_headerParsedOffset;
int m_headerParsedLength;
int m_bodyParsedOffset;
int m_bodyParsedLength;
};
//
// maildirStructure
//
class maildirStructure : public structure
{
private:
maildirStructure()
{
}
public:
maildirStructure(maildirPart* parent, const bodyPart& part)
{
int number = 1;
const body* bdy = part.getBody();
for (int i = 0 ; i < bdy->getPartCount() ; ++i, ++number)
m_parts.push_back(new maildirPart(parent, number, *bdy->getPartAt(i)));
}
const part& operator[](const int x) const
{
return (*m_parts[x - 1]);
}
part& operator[](const int x)
{
return (*m_parts[x - 1]);
}
const int getCount() const
{
return (m_parts.size());
}
static maildirStructure* emptyStructure()
{
return (&m_emptyStructure);
}
private:
static maildirStructure m_emptyStructure;
std::vector <maildirPart*> m_parts;
};
maildirStructure maildirStructure::m_emptyStructure;
maildirPart::maildirPart(maildirPart* parent, const int number, const bodyPart& part)
: m_parent(parent), m_number(number)
{
m_structure = new maildirStructure(this, part);
m_headerParsedOffset = part.getHeader()->getParsedOffset();
m_headerParsedLength = part.getHeader()->getParsedLength();
m_bodyParsedOffset = part.getBody()->getParsedOffset();
m_bodyParsedLength = part.getBody()->getParsedLength();
}
const structure& maildirPart::getStructure() const
{
return (*m_structure);
}
structure& maildirPart::getStructure()
{
return (*m_structure);
}
//
// maildirMessage
//
maildirMessage::maildirMessage(maildirFolder* folder, const int num)
: m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED),
m_expunged(false)
m_expunged(false), m_header(NULL), m_structure(NULL)
{
m_folder->registerMessage(this);
}
@ -79,19 +224,28 @@ const bool maildirMessage::isExpunged() const
const structure& maildirMessage::getStructure() const
{
// TODO
if (m_structure == NULL)
throw exceptions::unfetched_object();
return (*m_structure);
}
structure& maildirMessage::getStructure()
{
// TODO
if (m_structure == NULL)
throw exceptions::unfetched_object();
return (*m_structure);
}
const header& maildirMessage::getHeader() const
{
// TODO
if (m_header == NULL)
throw exceptions::unfetched_object();
return (*m_header);
}
@ -143,21 +297,93 @@ void maildirMessage::fetch(maildirFolder* folder, const int options)
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
*/
if (options & folder::FETCH_FLAGS)
m_flags = maildirUtils::extractFlags(path.getLastComponent());
if (options & folder::FETCH_SIZE)
m_size = file->length();
m_size = file->getLength();
if (options & folder::FETCH_UID)
m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer();
if (options & (folder::FETCH_ENVELOPE | folder::FETCH_CONTENT_INFO |
folder::FETCH_FULL_HEADER | folder::FETCH_STRUCTURE))
{
string contents;
utility::auto_ptr <utility::fileReader> reader = file->getFileReader();
utility::auto_ptr <utility::inputStream> is = reader->getInputStream();
// Need whole message contents for structure
if (options & folder::FETCH_STRUCTURE)
{
utility::stream::value_type buffer[16384];
contents.reserve(file->getLength());
while (!is->eof())
{
const utility::stream::size_type read = is->read(buffer, sizeof(buffer));
contents.append(buffer, read);
}
}
// Need only header
else
{
utility::stream::value_type buffer[1024];
contents.reserve(4096);
while (!is->eof())
{
const utility::stream::size_type read = is->read(buffer, sizeof(buffer));
contents.append(buffer, read);
const string::size_type sep1 = contents.rfind("\r\n\r\n");
const string::size_type sep2 = contents.rfind("\n\n");
if (sep1 != string::npos)
{
contents.erase(contents.begin() + sep1 + 4, contents.end());
break;
}
else if (sep2 != string::npos)
{
contents.erase(contents.begin() + sep2 + 2, contents.end());
break;
}
}
}
vmime::message msg;
msg.parse(contents);
// Extract structure
if (options & folder::FETCH_STRUCTURE)
{
if (m_structure)
delete (m_structure);
m_structure = new maildirStructure(NULL, msg);
}
// Extract some header fields or whole header
if (options & (folder::FETCH_ENVELOPE |
folder::FETCH_CONTENT_INFO |
folder::FETCH_FULL_HEADER))
{
getOrCreateHeader().copyFrom(*(msg.getHeader()));
}
}
}
header& maildirMessage::getOrCreateHeader()
{
if (m_header != NULL)
return (*m_header);
else
return (*(m_header = new header()));
}

View File

@ -75,6 +75,8 @@ private:
void onFolderClosed();
header& getOrCreateHeader();
maildirFolder* m_folder;
@ -83,6 +85,9 @@ private:
int m_flags;
bool m_expunged;
uid m_uid;
header* m_header;
structure* m_structure;
};

View File

@ -75,8 +75,8 @@ const bool maildirUtils::isSubfolderDirectory(const utility::file& file)
// A directory which name does not start with '.'
// is listed as a sub-folder...
if (file.isDirectory() &&
file.fullPath().getLastComponent().getBuffer().length() >= 1 &&
file.fullPath().getLastComponent().getBuffer()[0] != '.')
file.getFullPath().getLastComponent().getBuffer().length() >= 1 &&
file.getFullPath().getLastComponent().getBuffer()[0] != '.')
{
return (true);
}

View File

@ -120,10 +120,10 @@ protected:
structure() { }
structure(const structure&) { }
virtual ~structure() { }
public:
virtual ~structure() { }
/** Return the part at the specified position.
*
* @param x position