diff options
author | Vincent Richard <[email protected]> | 2010-05-18 13:52:27 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2010-05-18 13:52:27 +0000 |
commit | 9196d5c3421d828708f3667a94b2e074bfafdeca (patch) | |
tree | 154fe458b34c0c651c6ab6b2f5a375a3ba0bb599 | |
parent | Fixed parsing of header field value with no data on the first line (folding). (diff) | |
download | vmime-9196d5c3421d828708f3667a94b2e074bfafdeca.tar.gz vmime-9196d5c3421d828708f3667a94b2e074bfafdeca.zip |
Added helper function to construct parsed message from net message. Splitted IMAP source files.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | SConstruct | 3 | ||||
-rw-r--r-- | src/bodyPart.cpp | 9 | ||||
-rw-r--r-- | src/headerField.cpp | 3 | ||||
-rw-r--r-- | src/net/imap/IMAPMessage.cpp | 303 | ||||
-rw-r--r-- | src/net/imap/IMAPMessagePartContentHandler.cpp | 179 | ||||
-rw-r--r-- | src/net/imap/IMAPPart.cpp | 152 | ||||
-rw-r--r-- | src/net/imap/IMAPStructure.cpp | 85 | ||||
-rw-r--r-- | src/net/maildir/maildirMessage.cpp | 14 | ||||
-rw-r--r-- | src/net/pop3/POP3Message.cpp | 14 | ||||
-rw-r--r-- | vmime/bodyPart.hpp | 1 | ||||
-rw-r--r-- | vmime/contentHandler.hpp | 3 | ||||
-rw-r--r-- | vmime/net/imap/IMAPMessage.hpp | 19 | ||||
-rw-r--r-- | vmime/net/imap/IMAPMessagePartContentHandler.hpp | 73 | ||||
-rw-r--r-- | vmime/net/imap/IMAPPart.hpp | 88 | ||||
-rw-r--r-- | vmime/net/imap/IMAPStructure.hpp | 67 | ||||
-rw-r--r-- | vmime/net/maildir/maildirMessage.hpp | 2 | ||||
-rw-r--r-- | vmime/net/message.hpp | 12 | ||||
-rw-r--r-- | vmime/net/pop3/POP3Message.hpp | 2 |
19 files changed, 835 insertions, 199 deletions
@@ -2,6 +2,11 @@ VERSION 0.9.1svn ================ +2010-05-18 Vincent Richard <[email protected]> + + * net/*: added helper function vmime::net::message::getParsedMessage() + to construct a RFC-822 parsed message from a net message. + 2009-09-06 Vincent Richard <[email protected]> * Relicensed VMime under the GNU GPL license version 3. Dual licensing @@ -261,6 +261,9 @@ libvmime_messaging_proto_sources = [ 'net/imap/IMAPMessage.cpp', 'net/imap/IMAPMessage.hpp', 'net/imap/IMAPTag.cpp', 'net/imap/IMAPTag.hpp', 'net/imap/IMAPUtils.cpp', 'net/imap/IMAPUtils.hpp', + 'net/imap/IMAPMessagePartContentHandler.cpp', 'net/imap/IMAPMessagePartContentHandler.hpp', + 'net/imap/IMAPStructure.cpp', 'net/imap/IMAPStructure.hpp', + 'net/imap/IMAPPart.cpp', 'net/imap/IMAPPart.hpp', 'net/imap/IMAPParser.hpp', ] ], diff --git a/src/bodyPart.cpp b/src/bodyPart.cpp index 20bb1026..7d60461e 100644 --- a/src/bodyPart.cpp +++ b/src/bodyPart.cpp @@ -37,6 +37,15 @@ bodyPart::bodyPart() } +bodyPart::bodyPart(weak_ref <vmime::bodyPart> parentPart) + : m_header(vmime::create <header>()), + m_body(vmime::create <body>()), + m_parent(parentPart) +{ + m_body->setParentPart(thisRef().dynamicCast <bodyPart>()); +} + + void bodyPart::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { diff --git a/src/headerField.cpp b/src/headerField.cpp index cdde8ece..d1d42368 100644 --- a/src/headerField.cpp +++ b/src/headerField.cpp @@ -300,7 +300,8 @@ const std::vector <ref <const component> > headerField::getChildComponents() con { std::vector <ref <const component> > list; - list.push_back(m_value); + if (m_value) + list.push_back(m_value); return (list); } diff --git a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp index 29c2aeae..adfef011 100644 --- a/src/net/imap/IMAPMessage.cpp +++ b/src/net/imap/IMAPMessage.cpp @@ -27,6 +27,9 @@ #include "vmime/net/imap/IMAPStore.hpp" #include "vmime/net/imap/IMAPConnection.hpp" #include "vmime/net/imap/IMAPUtils.hpp" +#include "vmime/net/imap/IMAPStructure.hpp" +#include "vmime/net/imap/IMAPPart.hpp" +#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp" #include <sstream> #include <iterator> @@ -38,198 +41,6 @@ namespace net { namespace imap { -// -// IMAPpart -// - -class IMAPstructure; - -class IMAPpart : public part -{ -private: - - friend class vmime::creator; - - IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_mpart* mpart); - IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_1part* part); - -public: - - ref <const structure> getStructure() const; - ref <structure> getStructure(); - - ref <const IMAPpart> getParent() const { return m_parent.acquire(); } - - const mediaType& getType() const { return (m_mediaType); } - int getSize() const { return (m_size); } - int getNumber() const { return (m_number); } - - ref <const header> getHeader() const - { - if (m_header == NULL) - throw exceptions::unfetched_object(); - else - return m_header; - } - - - static ref <IMAPpart> create - (ref <IMAPpart> parent, const int number, const IMAPParser::body* body) - { - if (body->body_type_mpart()) - { - ref <IMAPpart> part = vmime::create <IMAPpart>(parent, number, body->body_type_mpart()); - part->m_structure = vmime::create <IMAPstructure>(part, body->body_type_mpart()->list()); - - return part; - } - else - { - return vmime::create <IMAPpart>(parent, number, body->body_type_1part()); - } - } - - - header& getOrCreateHeader() - { - if (m_header != NULL) - return (*m_header); - else - return (*(m_header = vmime::create <header>())); - } - -private: - - ref <IMAPstructure> m_structure; - weak_ref <IMAPpart> m_parent; - ref <header> m_header; - - int m_number; - int m_size; - mediaType m_mediaType; -}; - - - -// -// IMAPstructure -// - -class IMAPstructure : public structure -{ -public: - - IMAPstructure() - { - } - - IMAPstructure(const IMAPParser::body* body) - { - m_parts.push_back(IMAPpart::create(NULL, 0, body)); - } - - IMAPstructure(ref <IMAPpart> parent, const std::vector <IMAPParser::body*>& list) - { - int number = 0; - - for (std::vector <IMAPParser::body*>::const_iterator - it = list.begin() ; it != list.end() ; ++it, ++number) - { - m_parts.push_back(IMAPpart::create(parent, number, *it)); - } - } - - - ref <const part> getPartAt(const int x) const - { - return m_parts[x]; - } - - ref <part> getPartAt(const int x) - { - return m_parts[x]; - } - - int getPartCount() const - { - return m_parts.size(); - } - - - static ref <IMAPstructure> emptyStructure() - { - return (m_emptyStructure); - } - -private: - - static ref <IMAPstructure> m_emptyStructure; - - std::vector <ref <IMAPpart> > m_parts; -}; - - -ref <IMAPstructure> IMAPstructure::m_emptyStructure = vmime::create <IMAPstructure>(); - - - -IMAPpart::IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_mpart* mpart) - : m_parent(parent), m_header(NULL), m_number(number), m_size(0) -{ - m_mediaType = vmime::mediaType - ("multipart", mpart->media_subtype()->value()); -} - - -IMAPpart::IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_1part* part) - : m_parent(parent), m_header(NULL), m_number(number), m_size(0) -{ - if (part->body_type_text()) - { - m_mediaType = vmime::mediaType - ("text", part->body_type_text()-> - media_text()->media_subtype()->value()); - - m_size = part->body_type_text()->body_fields()->body_fld_octets()->value(); - } - else if (part->body_type_msg()) - { - m_mediaType = vmime::mediaType - ("message", part->body_type_msg()-> - media_message()->media_subtype()->value()); - } - else - { - m_mediaType = vmime::mediaType - (part->body_type_basic()->media_basic()->media_type()->value(), - part->body_type_basic()->media_basic()->media_subtype()->value()); - - m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value(); - } - - m_structure = NULL; -} - - -ref <const structure> IMAPpart::getStructure() const -{ - if (m_structure != NULL) - return (m_structure); - else - return (IMAPstructure::emptyStructure()); -} - - -ref <structure> IMAPpart::getStructure() -{ - if (m_structure != NULL) - return (m_structure); - else - return (IMAPstructure::emptyStructure()); -} - - - #ifndef VMIME_BUILDING_DOC // @@ -400,7 +211,22 @@ void IMAPMessage::fetchPartHeader(ref <part> p) extract(p, ossAdapter, NULL, 0, -1, true, true); - p.dynamicCast <IMAPpart>()->getOrCreateHeader().parse(oss.str()); + p.dynamicCast <IMAPPart>()->getOrCreateHeader().parse(oss.str()); +} + + +void IMAPMessage::fetchPartHeaderForStructure(ref <structure> str) +{ + for (int i = 0, n = str->getPartCount() ; i < n ; ++i) + { + ref <class part> part = str->getPartAt(i); + + // Fetch header of current part + fetchPartHeader(part); + + // Fetch header of sub-parts + fetchPartHeaderForStructure(part->getStructure()); + } } @@ -418,7 +244,7 @@ void IMAPMessage::extract(ref <const part> p, utility::outputStream& os, if (p != NULL) { - ref <const IMAPpart> currentPart = p.dynamicCast <const IMAPpart>(); + ref <const IMAPPart> currentPart = p.dynamicCast <const IMAPPart>(); std::vector <int> numbers; numbers.push_back(currentPart->getNumber()); @@ -446,8 +272,17 @@ void IMAPMessage::extract(ref <const part> p, utility::outputStream& os, command << "FETCH " << m_num << " BODY"; if (peek) command << ".PEEK"; command << "["; - command << section.str(); - if (headerOnly) command << ".MIME"; // "MIME" not "HEADER" for parts + + if (section.str().empty() && headerOnly) + { + command << "HEADER"; + } + else + { + command << section.str(); + if (headerOnly) command << ".MIME"; // "MIME" not "HEADER" for parts + } + command << "]"; if (start != 0 || length != -1) @@ -621,7 +456,7 @@ void IMAPMessage::processFetchResponse } case IMAPParser::msg_att_item::BODY_STRUCTURE: { - m_structure = vmime::create <IMAPstructure>((*it)->body()); + m_structure = vmime::create <IMAPStructure>((*it)->body()); break; } case IMAPParser::msg_att_item::RFC822_HEADER: @@ -796,6 +631,80 @@ void IMAPMessage::setFlags(const int flags, const int mode) } +void IMAPMessage::constructParsedMessage(ref <bodyPart> parentPart, ref <structure> str, int level) +{ + if (level == 0) + { + ref <class part> part = str->getPartAt(0); + + // Copy header + ref <const header> hdr = part->getHeader(); + parentPart->getHeader()->copyFrom(*hdr); + + // Initialize body + parentPart->getBody()->setContents + (vmime::create <IMAPMessagePartContentHandler> + (thisRef().dynamicCast <IMAPMessage>(), + part, parentPart->getBody()->getEncoding())); + + constructParsedMessage(parentPart, part->getStructure(), 1); + } + else + { + for (int i = 0, n = str->getPartCount() ; i < n ; ++i) + { + ref <class part> part = str->getPartAt(i); + + ref <bodyPart> childPart = vmime::create <bodyPart>(); + + // Copy header + ref <const header> hdr = part->getHeader(); + childPart->getHeader()->copyFrom(*hdr); + + // Initialize body + childPart->getBody()->setContents + (vmime::create <IMAPMessagePartContentHandler> + (thisRef().dynamicCast <IMAPMessage>(), + part, childPart->getBody()->getEncoding())); + + // Add child part + parentPart->getBody()->appendPart(childPart); + + // Construct sub parts + constructParsedMessage(childPart, part->getStructure(), ++level); + } + } +} + + +ref <vmime::message> IMAPMessage::getParsedMessage() +{ + // Fetch structure + ref <structure> structure = NULL; + + try + { + structure = getStructure(); + } + catch (exceptions::unfetched_object&) + { + fetch(m_folder.acquire(), IMAPFolder::FETCH_STRUCTURE); + structure = getStructure(); + } + + // Fetch header for each part + fetchPartHeaderForStructure(structure); + + // Construct message from structure + ref <vmime::message> msg = vmime::create <vmime::message>(); + + constructParsedMessage(msg, structure); + + return msg; +} + + } // imap } // net } // vmime + diff --git a/src/net/imap/IMAPMessagePartContentHandler.cpp b/src/net/imap/IMAPMessagePartContentHandler.cpp new file mode 100644 index 00000000..12d387c2 --- /dev/null +++ b/src/net/imap/IMAPMessagePartContentHandler.cpp @@ -0,0 +1,179 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/net/imap/imapmessagepartcontenthandler.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +IMAPMessagePartContentHandler::IMAPMessagePartContentHandler + (ref <IMAPMessage> msg, ref <class part> part, const vmime::encoding& encoding) + : m_message(msg), m_part(part), m_encoding(encoding) +{ +} + + +ref <contentHandler> IMAPMessagePartContentHandler::clone() const +{ + return create <IMAPMessagePartContentHandler> + (m_message.acquire().constCast <IMAPMessage>(), + m_part.acquire().constCast <part>(), + m_encoding); +} + + +void IMAPMessagePartContentHandler::generate + (utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength) const +{ + ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>(); + ref <part> part = m_part.acquire().constCast <class part>(); + + // Data is already encoded + if (isEncoded()) + { + // The data is already encoded but the encoding specified for + // the generation is different from the current one. We need + // to re-encode data: decode from input buffer to temporary + // buffer, and then re-encode to output stream... + if (m_encoding != enc) + { + // Extract part contents to temporary buffer + std::ostringstream oss; + utility::outputStreamAdapter tmp(oss); + + msg->extractPart(part, tmp, NULL); + + // Decode to another temporary buffer + utility::inputStreamStringProxyAdapter in(oss.str()); + + std::ostringstream oss2; + utility::outputStreamAdapter tmp2(oss2); + + ref <utility::encoder::encoder> theDecoder = m_encoding.getEncoder(); + theDecoder->decode(in, tmp2); + + // Reencode to output stream + string str = oss2.str(); + utility::inputStreamStringAdapter tempIn(str); + + ref <utility::encoder::encoder> theEncoder = enc.getEncoder(); + theEncoder->getProperties()["maxlinelength"] = maxLineLength; + theEncoder->encode(tempIn, os); + } + // No encoding to perform + else + { + msg->extractPart(part, os); + } + } + // Need to encode data before + else + { + // Extract part contents to temporary buffer + std::ostringstream oss; + utility::outputStreamAdapter tmp(oss); + + msg->extractPart(part, tmp, NULL); + + // Encode temporary buffer to output stream + ref <utility::encoder::encoder> theEncoder = enc.getEncoder(); + theEncoder->getProperties()["maxlinelength"] = maxLineLength; + + utility::inputStreamStringAdapter is(oss.str()); + + theEncoder->encode(is, os); + } +} + + +void IMAPMessagePartContentHandler::extract + (utility::outputStream& os, utility::progressListener* progress) const +{ + ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>(); + ref <part> part = m_part.acquire().constCast <class part>(); + + // No decoding to perform + if (!isEncoded()) + { + msg->extractPart(part, os, progress); + } + // Need to decode data + else + { + // Extract part contents to temporary buffer + std::ostringstream oss; + utility::outputStreamAdapter tmp(oss); + + msg->extractPart(part, tmp, NULL); + + // Encode temporary buffer to output stream + utility::inputStreamStringAdapter is(oss.str()); + utility::progressListenerSizeAdapter plsa(progress, getLength()); + + ref <utility::encoder::encoder> theDecoder = m_encoding.getEncoder(); + theDecoder->decode(is, os, &plsa); + } +} + + +void IMAPMessagePartContentHandler::extractRaw + (utility::outputStream& os, utility::progressListener* progress) const +{ + ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>(); + ref <part> part = m_part.acquire().constCast <class part>(); + + msg->extractPart(part, os, progress); +} + + +string::size_type IMAPMessagePartContentHandler::getLength() const +{ + return m_part.acquire()->getSize(); +} + + +bool IMAPMessagePartContentHandler::isEncoded() const +{ + return m_encoding != NO_ENCODING; +} + + +const vmime::encoding& IMAPMessagePartContentHandler::getEncoding() const +{ + return m_encoding; +} + + +bool IMAPMessagePartContentHandler::isEmpty() const +{ + return getLength() == 0; +} + + +} // imap +} // net +} // vmime + diff --git a/src/net/imap/IMAPPart.cpp b/src/net/imap/IMAPPart.cpp new file mode 100644 index 00000000..32021e83 --- /dev/null +++ b/src/net/imap/IMAPPart.cpp @@ -0,0 +1,152 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/net/imap/IMAPPart.hpp" +#include "vmime/net/imap/IMAPStructure.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +IMAPPart::IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_mpart* mpart) + : m_parent(parent), m_header(NULL), m_number(number), m_size(0) +{ + m_mediaType = vmime::mediaType + ("multipart", mpart->media_subtype()->value()); +} + + +IMAPPart::IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_1part* part) + : m_parent(parent), m_header(NULL), m_number(number), m_size(0) +{ + if (part->body_type_text()) + { + m_mediaType = vmime::mediaType + ("text", part->body_type_text()-> + media_text()->media_subtype()->value()); + + m_size = part->body_type_text()->body_fields()->body_fld_octets()->value(); + } + else if (part->body_type_msg()) + { + m_mediaType = vmime::mediaType + ("message", part->body_type_msg()-> + media_message()->media_subtype()->value()); + } + else + { + m_mediaType = vmime::mediaType + (part->body_type_basic()->media_basic()->media_type()->value(), + part->body_type_basic()->media_basic()->media_subtype()->value()); + + m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value(); + } + + m_structure = NULL; +} + + +ref <const structure> IMAPPart::getStructure() const +{ + if (m_structure != NULL) + return m_structure; + else + return IMAPStructure::emptyStructure(); +} + + +ref <structure> IMAPPart::getStructure() +{ + if (m_structure != NULL) + return m_structure; + else + return IMAPStructure::emptyStructure(); +} + + +ref <const IMAPPart> IMAPPart::getParent() const +{ + return m_parent.acquire(); +} + + +const mediaType& IMAPPart::getType() const +{ + return m_mediaType; +} + + +int IMAPPart::getSize() const +{ + return m_size; +} + + +int IMAPPart::getNumber() const +{ + return m_number; +} + + +ref <const header> IMAPPart::getHeader() const +{ + if (m_header == NULL) + throw exceptions::unfetched_object(); + else + return m_header; +} + + +// static +ref <IMAPPart> IMAPPart::create + (ref <IMAPPart> parent, const int number, const IMAPParser::body* body) +{ + if (body->body_type_mpart()) + { + ref <IMAPPart> part = vmime::create <IMAPPart>(parent, number, body->body_type_mpart()); + part->m_structure = vmime::create <IMAPStructure>(part, body->body_type_mpart()->list()); + + return part; + } + else + { + return vmime::create <IMAPPart>(parent, number, body->body_type_1part()); + } +} + + +header& IMAPPart::getOrCreateHeader() +{ + if (m_header != NULL) + return *m_header; + else + return *(m_header = vmime::create <header>()); +} + + +} // imap +} // net +} // vmime + diff --git a/src/net/imap/IMAPStructure.cpp b/src/net/imap/IMAPStructure.cpp new file mode 100644 index 00000000..357febe3 --- /dev/null +++ b/src/net/imap/IMAPStructure.cpp @@ -0,0 +1,85 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/net/imap/IMAPStructure.hpp" +#include "vmime/net/imap/IMAPPart.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +IMAPStructure::IMAPStructure() +{ +} + + +IMAPStructure::IMAPStructure(const IMAPParser::body* body) +{ + m_parts.push_back(IMAPPart::create(NULL, 0, body)); +} + + +IMAPStructure::IMAPStructure(ref <IMAPPart> parent, const std::vector <IMAPParser::body*>& list) +{ + int number = 0; + + for (std::vector <IMAPParser::body*>::const_iterator + it = list.begin() ; it != list.end() ; ++it, ++number) + { + m_parts.push_back(IMAPPart::create(parent, number, *it)); + } +} + + +ref <const part> IMAPStructure::getPartAt(const int x) const +{ + return m_parts[x]; +} + + +ref <part> IMAPStructure::getPartAt(const int x) +{ + return m_parts[x]; +} + + +int IMAPStructure::getPartCount() const +{ + return m_parts.size(); +} + + +// static +ref <IMAPStructure> IMAPStructure::emptyStructure() +{ + static ref <IMAPStructure> emptyStructure = vmime::create <IMAPStructure>(); + return emptyStructure; +} + + +} // imap +} // net +} // vmime + diff --git a/src/net/maildir/maildirMessage.cpp b/src/net/maildir/maildirMessage.cpp index 8999d847..51cd1bad 100644 --- a/src/net/maildir/maildirMessage.cpp +++ b/src/net/maildir/maildirMessage.cpp @@ -524,6 +524,20 @@ ref <header> maildirMessage::getOrCreateHeader() } +ref <vmime::message> maildirMessage::getParsedMessage() +{ + std::ostringstream oss; + utility::outputStreamAdapter os(oss); + + extract(os); + + vmime::ref <vmime::message> msg = vmime::create <vmime::message>(); + msg->parse(oss.str()); + + return msg; +} + + } // maildir } // net } // vmime diff --git a/src/net/pop3/POP3Message.cpp b/src/net/pop3/POP3Message.cpp index b38951b6..50f4f874 100644 --- a/src/net/pop3/POP3Message.cpp +++ b/src/net/pop3/POP3Message.cpp @@ -218,6 +218,20 @@ void POP3Message::setFlags(const int /* flags */, const int /* mode */) } +ref <vmime::message> POP3Message::getParsedMessage() +{ + std::ostringstream oss; + utility::outputStreamAdapter os(oss); + + extract(os); + + vmime::ref <vmime::message> msg = vmime::create <vmime::message>(); + msg->parse(oss.str()); + + return msg; +} + + } // pop3 } // net } // vmime diff --git a/vmime/bodyPart.hpp b/vmime/bodyPart.hpp index 47c11cb1..aa0f0408 100644 --- a/vmime/bodyPart.hpp +++ b/vmime/bodyPart.hpp @@ -46,6 +46,7 @@ class bodyPart : public component public: bodyPart(); + bodyPart(weak_ref <vmime::bodyPart> parentPart); /** Return the header section of this part. * diff --git a/vmime/contentHandler.hpp b/vmime/contentHandler.hpp index aa485f5c..38e4e245 100644 --- a/vmime/contentHandler.hpp +++ b/vmime/contentHandler.hpp @@ -87,7 +87,8 @@ public: virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; /** Returns the actual length of data. WARNING: this can return 0 if no - * length was specified when setting data of this object. + * length was specified when setting data of this object, or if the + * length is not known). * * @return length of data */ diff --git a/vmime/net/imap/IMAPMessage.hpp b/vmime/net/imap/IMAPMessage.hpp index 690e5e2a..edbf69ff 100644 --- a/vmime/net/imap/IMAPMessage.hpp +++ b/vmime/net/imap/IMAPMessage.hpp @@ -28,6 +28,8 @@ #include "vmime/net/message.hpp" #include "vmime/net/folder.hpp" +#include "vmime/net/imap/IMAPParser.hpp" + namespace vmime { namespace net { @@ -75,12 +77,29 @@ public: void fetchPartHeader(ref <part> p); + ref <vmime::message> getParsedMessage(); + private: void fetch(ref <IMAPFolder> folder, const int options); void processFetchResponse(const int options, const IMAPParser::msg_att* msgAtt); + /** Recursively fetch part header for all parts in the structure. + * + * @param str structure for which to fetch parts headers + */ + void fetchPartHeaderForStructure(ref <structure> str); + + /** Recursively contruct parsed message from structure. + * Called by getParsedMessage(). + * + * @param parentPart root body part (the message) + * @param str structure for which to construct part + * @param level current nesting level (0 is root) + */ + void constructParsedMessage(ref <bodyPart> parentPart, ref <structure> str, int level = 0); + void extract(ref <const part> p, utility::outputStream& os, utility::progressListener* progress, const int start, const int length, const bool headerOnly, const bool peek) const; diff --git a/vmime/net/imap/IMAPMessagePartContentHandler.hpp b/vmime/net/imap/IMAPMessagePartContentHandler.hpp new file mode 100644 index 00000000..0c4641e9 --- /dev/null +++ b/vmime/net/imap/IMAPMessagePartContentHandler.hpp @@ -0,0 +1,73 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/contentHandler.hpp" +#include "vmime/net/imap/IMAPMessage.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPMessagePartContentHandler : public contentHandler +{ +public: + + IMAPMessagePartContentHandler(ref <IMAPMessage> msg, ref <class part> part, const vmime::encoding& encoding); + + ref <contentHandler> clone() const; + + void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const; + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + + string::size_type getLength() const; + + bool isEncoded() const; + + const vmime::encoding& getEncoding() const; + + bool isEmpty() const; + +private: + + weak_ref <IMAPMessage> m_message; + weak_ref <part> m_part; + + vmime::encoding m_encoding; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED + diff --git a/vmime/net/imap/IMAPPart.hpp b/vmime/net/imap/IMAPPart.hpp new file mode 100644 index 00000000..d84db1bd --- /dev/null +++ b/vmime/net/imap/IMAPPart.hpp @@ -0,0 +1,88 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED + + +#include "vmime/net/message.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPStructure; + + +class IMAPPart : public part +{ +private: + + friend class vmime::creator; + + IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_mpart* mpart); + IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_1part* part); + +public: + + ref <const structure> getStructure() const; + ref <structure> getStructure(); + + ref <const IMAPPart> getParent() const; + + const mediaType& getType() const; + int getSize() const; + int getNumber() const; + + ref <const header> getHeader() const; + + + static ref <IMAPPart> create + (ref <IMAPPart> parent, const int number, const IMAPParser::body* body); + + + header& getOrCreateHeader(); + +private: + + ref <IMAPStructure> m_structure; + weak_ref <IMAPPart> m_parent; + ref <header> m_header; + + int m_number; + int m_size; + mediaType m_mediaType; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED + diff --git a/vmime/net/imap/IMAPStructure.hpp b/vmime/net/imap/IMAPStructure.hpp new file mode 100644 index 00000000..e43676c8 --- /dev/null +++ b/vmime/net/imap/IMAPStructure.hpp @@ -0,0 +1,67 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2009 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED + + +#include "vmime/net/message.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPPart; + + +class IMAPStructure : public structure +{ +public: + + IMAPStructure(); + IMAPStructure(const IMAPParser::body* body); + IMAPStructure(ref <IMAPPart> parent, const std::vector <IMAPParser::body*>& list); + + ref <const part> getPartAt(const int x) const; + ref <part> getPartAt(const int x); + int getPartCount() const; + + static ref <IMAPStructure> emptyStructure(); + +private: + + std::vector <ref <IMAPPart> > m_parts; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED + diff --git a/vmime/net/maildir/maildirMessage.hpp b/vmime/net/maildir/maildirMessage.hpp index ba3c88e1..cd66d43c 100644 --- a/vmime/net/maildir/maildirMessage.hpp +++ b/vmime/net/maildir/maildirMessage.hpp @@ -75,6 +75,8 @@ public: void fetchPartHeader(ref <part> p); + ref <vmime::message> getParsedMessage(); + private: void fetch(ref <maildirFolder> folder, const int options); diff --git a/vmime/net/message.hpp b/vmime/net/message.hpp index a0cc1daa..b6ebef83 100644 --- a/vmime/net/message.hpp +++ b/vmime/net/message.hpp @@ -31,6 +31,8 @@ #include "vmime/utility/progressListener.hpp" #include "vmime/utility/stream.hpp" +#include "vmime/message.hpp" + namespace vmime { namespace net { @@ -286,6 +288,16 @@ public: * @param p the part for which to fetch the header */ virtual void fetchPartHeader(ref <part> p) = 0; + + /** Get the RFC-822 message for this abstract message. + * Warning: This may require getting some data (ie: structure and headers) from + * the server, which is done automatically. Actual message contents (ie: body) + * will not be fetched if possible (IMAP allows it, whereas POP3 will require + * to fetch the whole message). + * + * @return a RFC-822-parsed message + */ + virtual ref <vmime::message> getParsedMessage() = 0; }; diff --git a/vmime/net/pop3/POP3Message.hpp b/vmime/net/pop3/POP3Message.hpp index 5dbea3fe..337cc5d5 100644 --- a/vmime/net/pop3/POP3Message.hpp +++ b/vmime/net/pop3/POP3Message.hpp @@ -77,6 +77,8 @@ public: void fetchPartHeader(ref <part> p); + ref <vmime::message> getParsedMessage(); + private: void fetch(ref <POP3Folder> folder, const int options); |