aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--SConstruct3
-rw-r--r--src/bodyPart.cpp9
-rw-r--r--src/headerField.cpp3
-rw-r--r--src/net/imap/IMAPMessage.cpp303
-rw-r--r--src/net/imap/IMAPMessagePartContentHandler.cpp179
-rw-r--r--src/net/imap/IMAPPart.cpp152
-rw-r--r--src/net/imap/IMAPStructure.cpp85
-rw-r--r--src/net/maildir/maildirMessage.cpp14
-rw-r--r--src/net/pop3/POP3Message.cpp14
-rw-r--r--vmime/bodyPart.hpp1
-rw-r--r--vmime/contentHandler.hpp3
-rw-r--r--vmime/net/imap/IMAPMessage.hpp19
-rw-r--r--vmime/net/imap/IMAPMessagePartContentHandler.hpp73
-rw-r--r--vmime/net/imap/IMAPPart.hpp88
-rw-r--r--vmime/net/imap/IMAPStructure.hpp67
-rw-r--r--vmime/net/maildir/maildirMessage.hpp2
-rw-r--r--vmime/net/message.hpp12
-rw-r--r--vmime/net/pop3/POP3Message.hpp2
19 files changed, 835 insertions, 199 deletions
diff --git a/ChangeLog b/ChangeLog
index 40317468..b824b4c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/SConstruct b/SConstruct
index d05f8bcb..99b21905 100644
--- a/SConstruct
+++ b/SConstruct
@@ -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);