Working on 'maildir' implementation.
This commit is contained in:
parent
50a6a9cdfa
commit
78b3909d9b
@ -32,31 +32,12 @@ namespace vmime {
|
|||||||
namespace messaging {
|
namespace messaging {
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// IMAPheader
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
class IMAPheader : public header
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
IMAPheader()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse(const string& str)
|
|
||||||
{
|
|
||||||
header::parse(str);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// IMAPpart
|
// IMAPpart
|
||||||
//
|
//
|
||||||
|
|
||||||
|
class IMAPstructure;
|
||||||
|
|
||||||
class IMAPpart : public part
|
class IMAPpart : public part
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -75,7 +56,13 @@ public:
|
|||||||
const int getSize() const { return (m_size); }
|
const int getSize() const { return (m_size); }
|
||||||
const int getNumber() const { return (m_number); }
|
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)
|
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)
|
if (m_header != NULL)
|
||||||
return (*m_header);
|
return (*m_header);
|
||||||
else
|
else
|
||||||
return (*(m_header = new IMAPheader()));
|
return (*(m_header = new header()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
IMAPstructure* m_structure;
|
IMAPstructure* m_structure;
|
||||||
IMAPpart* m_parent;
|
IMAPpart* m_parent;
|
||||||
IMAPheader* m_header;
|
header* m_header;
|
||||||
|
|
||||||
int m_number;
|
int m_number;
|
||||||
int m_size;
|
int m_size;
|
||||||
@ -112,7 +99,6 @@ private:
|
|||||||
// IMAPstructure
|
// IMAPstructure
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
class IMAPstructure : public structure
|
class IMAPstructure : public structure
|
||||||
{
|
{
|
||||||
private:
|
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
|
const class structure& IMAPpart::getStructure() const
|
||||||
{
|
{
|
||||||
if (m_structure != NULL)
|
if (m_structure != NULL)
|
||||||
@ -297,7 +274,7 @@ IMAPMessage::~IMAPMessage()
|
|||||||
if (m_folder)
|
if (m_folder)
|
||||||
m_folder->unregisterMessage(this);
|
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()
|
(*it)->section()->section_text1()->type()
|
||||||
== IMAPParser::section_text::HEADER_FIELDS)
|
== IMAPParser::section_text::HEADER_FIELDS)
|
||||||
{
|
{
|
||||||
IMAPheader tempHeader;
|
header tempHeader;
|
||||||
tempHeader.parse((*it)->nstring()->value());
|
tempHeader.parse((*it)->nstring()->value());
|
||||||
|
|
||||||
vmime::header& hdr = getOrCreateHeader();
|
vmime::header& hdr = getOrCreateHeader();
|
||||||
@ -706,12 +683,12 @@ void IMAPMessage::processFetchResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IMAPheader& IMAPMessage::getOrCreateHeader()
|
header& IMAPMessage::getOrCreateHeader()
|
||||||
{
|
{
|
||||||
if (m_header != NULL)
|
if (m_header != NULL)
|
||||||
return (*m_header);
|
return (*m_header);
|
||||||
else
|
else
|
||||||
return (*(m_header = new IMAPheader()));
|
return (*(m_header = new header()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,10 +30,6 @@ namespace vmime {
|
|||||||
namespace messaging {
|
namespace messaging {
|
||||||
|
|
||||||
|
|
||||||
class IMAPheader;
|
|
||||||
class IMAPstructure;
|
|
||||||
|
|
||||||
|
|
||||||
/** IMAP message implementation.
|
/** IMAP message implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -83,7 +79,7 @@ private:
|
|||||||
void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest);
|
void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest);
|
||||||
|
|
||||||
|
|
||||||
IMAPheader& getOrCreateHeader();
|
header& getOrCreateHeader();
|
||||||
|
|
||||||
|
|
||||||
void onFolderClosed();
|
void onFolderClosed();
|
||||||
@ -96,8 +92,8 @@ private:
|
|||||||
bool m_expunged;
|
bool m_expunged;
|
||||||
uid m_uid;
|
uid m_uid;
|
||||||
|
|
||||||
class IMAPheader* m_header;
|
header* m_header;
|
||||||
class IMAPstructure* m_structure;
|
structure* m_structure;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ void maildirFolder::scanFolder()
|
|||||||
while (nit->hasMoreElements())
|
while (nit->hasMoreElements())
|
||||||
{
|
{
|
||||||
utility::auto_ptr <utility::file> file = nit->nextElement();
|
utility::auto_ptr <utility::file> file = nit->nextElement();
|
||||||
newMessageFilenames.push_back(file->fullPath().getLastComponent());
|
newMessageFilenames.push_back(file->getFullPath().getLastComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current messages (cur/)
|
// Current messages (cur/)
|
||||||
@ -286,7 +286,7 @@ void maildirFolder::scanFolder()
|
|||||||
while (cit->hasMoreElements())
|
while (cit->hasMoreElements())
|
||||||
{
|
{
|
||||||
utility::auto_ptr <utility::file> file = cit->nextElement();
|
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)
|
// 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))
|
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);
|
maildirFolder* subFolder = new maildirFolder(subPath, m_store);
|
||||||
|
|
||||||
list.push_back(subFolder);
|
list.push_back(subFolder);
|
||||||
|
@ -29,9 +29,154 @@ namespace vmime {
|
|||||||
namespace messaging {
|
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)
|
maildirMessage::maildirMessage(maildirFolder* folder, const int num)
|
||||||
: m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED),
|
: 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);
|
m_folder->registerMessage(this);
|
||||||
}
|
}
|
||||||
@ -79,19 +224,28 @@ const bool maildirMessage::isExpunged() const
|
|||||||
|
|
||||||
const structure& maildirMessage::getStructure() const
|
const structure& maildirMessage::getStructure() const
|
||||||
{
|
{
|
||||||
// TODO
|
if (m_structure == NULL)
|
||||||
|
throw exceptions::unfetched_object();
|
||||||
|
|
||||||
|
return (*m_structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
structure& maildirMessage::getStructure()
|
structure& maildirMessage::getStructure()
|
||||||
{
|
{
|
||||||
// TODO
|
if (m_structure == NULL)
|
||||||
|
throw exceptions::unfetched_object();
|
||||||
|
|
||||||
|
return (*m_structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const header& maildirMessage::getHeader() const
|
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);
|
const utility::file::path path = folder->getMessageFSPath(m_num);
|
||||||
utility::auto_ptr <utility::file> file = fsf->create(path);
|
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)
|
if (options & folder::FETCH_FLAGS)
|
||||||
m_flags = maildirUtils::extractFlags(path.getLastComponent());
|
m_flags = maildirUtils::extractFlags(path.getLastComponent());
|
||||||
|
|
||||||
if (options & folder::FETCH_SIZE)
|
if (options & folder::FETCH_SIZE)
|
||||||
m_size = file->length();
|
m_size = file->getLength();
|
||||||
|
|
||||||
if (options & folder::FETCH_UID)
|
if (options & folder::FETCH_UID)
|
||||||
m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer();
|
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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +75,8 @@ private:
|
|||||||
|
|
||||||
void onFolderClosed();
|
void onFolderClosed();
|
||||||
|
|
||||||
|
header& getOrCreateHeader();
|
||||||
|
|
||||||
|
|
||||||
maildirFolder* m_folder;
|
maildirFolder* m_folder;
|
||||||
|
|
||||||
@ -83,6 +85,9 @@ private:
|
|||||||
int m_flags;
|
int m_flags;
|
||||||
bool m_expunged;
|
bool m_expunged;
|
||||||
uid m_uid;
|
uid m_uid;
|
||||||
|
|
||||||
|
header* m_header;
|
||||||
|
structure* m_structure;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,8 +75,8 @@ const bool maildirUtils::isSubfolderDirectory(const utility::file& file)
|
|||||||
// A directory which name does not start with '.'
|
// A directory which name does not start with '.'
|
||||||
// is listed as a sub-folder...
|
// is listed as a sub-folder...
|
||||||
if (file.isDirectory() &&
|
if (file.isDirectory() &&
|
||||||
file.fullPath().getLastComponent().getBuffer().length() >= 1 &&
|
file.getFullPath().getLastComponent().getBuffer().length() >= 1 &&
|
||||||
file.fullPath().getLastComponent().getBuffer()[0] != '.')
|
file.getFullPath().getLastComponent().getBuffer()[0] != '.')
|
||||||
{
|
{
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,10 @@ protected:
|
|||||||
structure() { }
|
structure() { }
|
||||||
structure(const structure&) { }
|
structure(const structure&) { }
|
||||||
|
|
||||||
virtual ~structure() { }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual ~structure() { }
|
||||||
|
|
||||||
/** Return the part at the specified position.
|
/** Return the part at the specified position.
|
||||||
*
|
*
|
||||||
* @param x position
|
* @param x position
|
||||||
|
Loading…
Reference in New Issue
Block a user