aboutsummaryrefslogtreecommitdiffstats
path: root/src/messaging/maildirMessage.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2004-12-15 22:17:03 +0000
committerVincent Richard <[email protected]>2004-12-15 22:17:03 +0000
commit78b3909d9b3e88589e1b28a362bbc54913bca959 (patch)
tree853146fc5746adf25d8ed859a3a299537088c4d4 /src/messaging/maildirMessage.cpp
parentAdded parsing bounds on 'component'. (diff)
downloadvmime-78b3909d9b3e88589e1b28a362bbc54913bca959.tar.gz
vmime-78b3909d9b3e88589e1b28a362bbc54913bca959.zip
Working on 'maildir' implementation.
Diffstat (limited to 'src/messaging/maildirMessage.cpp')
-rw-r--r--src/messaging/maildirMessage.cpp250
1 files changed, 238 insertions, 12 deletions
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()));
}