Working on 'maildir' implementation.
This commit is contained in:
parent
50a6a9cdfa
commit
78b3909d9b
@ -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()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -120,10 +120,10 @@ protected:
|
||||
structure() { }
|
||||
structure(const structure&) { }
|
||||
|
||||
virtual ~structure() { }
|
||||
|
||||
public:
|
||||
|
||||
virtual ~structure() { }
|
||||
|
||||
/** Return the part at the specified position.
|
||||
*
|
||||
* @param x position
|
||||
|
Loading…
Reference in New Issue
Block a user