aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/messaging/IMAPMessage.cpp55
-rw-r--r--src/messaging/IMAPMessage.hpp10
-rw-r--r--src/messaging/maildirFolder.cpp6
-rw-r--r--src/messaging/maildirMessage.cpp250
-rw-r--r--src/messaging/maildirMessage.hpp5
-rw-r--r--src/messaging/maildirUtils.cpp4
-rw-r--r--src/messaging/message.hpp4
7 files changed, 269 insertions, 65 deletions
diff --git a/src/messaging/IMAPMessage.cpp b/src/messaging/IMAPMessage.cpp
index 72f9ce31..d5ede663 100644
--- a/src/messaging/IMAPMessage.cpp
+++ b/src/messaging/IMAPMessage.cpp
@@ -33,30 +33,11 @@ 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()));
}
diff --git a/src/messaging/IMAPMessage.hpp b/src/messaging/IMAPMessage.hpp
index 0bf874b9..430a0fbd 100644
--- a/src/messaging/IMAPMessage.hpp
+++ b/src/messaging/IMAPMessage.hpp
@@ -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;
};
diff --git a/src/messaging/maildirFolder.cpp b/src/messaging/maildirFolder.cpp
index c5c1054a..854e7dfb 100644
--- a/src/messaging/maildirFolder.cpp
+++ b/src/messaging/maildirFolder.cpp
@@ -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);
diff --git a/src/messaging/maildirMessage.cpp b/src/messaging/maildirMessage.cpp
index 12ac8cdf..e87b73ab 100644
--- a/src/messaging/maildirMessage.cpp
+++ b/src/messaging/maildirMessage.cpp
@@ -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()));
}
diff --git a/src/messaging/maildirMessage.hpp b/src/messaging/maildirMessage.hpp
index 0b543bc2..f487b32d 100644
--- a/src/messaging/maildirMessage.hpp
+++ b/src/messaging/maildirMessage.hpp
@@ -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;
};
diff --git a/src/messaging/maildirUtils.cpp b/src/messaging/maildirUtils.cpp
index 4cf40c9c..e620ce0a 100644
--- a/src/messaging/maildirUtils.cpp
+++ b/src/messaging/maildirUtils.cpp
@@ -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);
}
diff --git a/src/messaging/message.hpp b/src/messaging/message.hpp
index 825e1021..fb6cfed1 100644
--- a/src/messaging/message.hpp
+++ b/src/messaging/message.hpp
@@ -120,10 +120,10 @@ protected:
structure() { }
structure(const structure&) { }
- virtual ~structure() { }
-
public:
+ virtual ~structure() { }
+
/** Return the part at the specified position.
*
* @param x position