diff options
author | Vincent Richard <[email protected]> | 2004-12-15 22:17:03 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2004-12-15 22:17:03 +0000 |
commit | 78b3909d9b3e88589e1b28a362bbc54913bca959 (patch) | |
tree | 853146fc5746adf25d8ed859a3a299537088c4d4 /src/messaging/maildirMessage.cpp | |
parent | Added parsing bounds on 'component'. (diff) | |
download | vmime-78b3909d9b3e88589e1b28a362bbc54913bca959.tar.gz vmime-78b3909d9b3e88589e1b28a362bbc54913bca959.zip |
Working on 'maildir' implementation.
Diffstat (limited to 'src/messaging/maildirMessage.cpp')
-rw-r--r-- | src/messaging/maildirMessage.cpp | 250 |
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())); } |