aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
8 files changed, 561 insertions, 198 deletions
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