aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--SConstruct4
-rw-r--r--src/attachmentHelper.cpp118
-rw-r--r--src/generatedMessageAttachment.cpp105
-rw-r--r--src/parsedMessageAttachment.cpp114
-rw-r--r--tests/parser/attachmentHelperTest.cpp123
-rw-r--r--vmime/attachmentHelper.hpp7
-rw-r--r--vmime/bodyPartAttachment.hpp6
-rw-r--r--vmime/generatedMessageAttachment.hpp79
-rw-r--r--vmime/messageAttachment.hpp55
-rw-r--r--vmime/parsedMessageAttachment.hpp78
-rw-r--r--vmime/vmime.hpp1
12 files changed, 670 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index ab5cfb1c..54fe8aa3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
VERSION 0.8.1cvs
================
+2006-01-16 Vincent Richard <[email protected]>
+
+ * Added support for attachments of type "message/rfc822".
+
2006-01-15 Vincent Richard <[email protected]>
* IMAP: implemented multi-fetching. Now using "FETCH x:y" instead of
diff --git a/SConstruct b/SConstruct
index c0747d93..a1d623a2 100644
--- a/SConstruct
+++ b/SConstruct
@@ -105,6 +105,7 @@ libvmime_sources = [
'encoding.cpp', 'encoding.hpp',
'exception.cpp', 'exception.hpp',
'fileAttachment.cpp', 'fileAttachment.hpp',
+ 'generatedMessageAttachment.hpp', 'generatedMessageAttachment.cpp',
'header.cpp', 'header.hpp',
'headerFieldFactory.cpp', 'headerFieldFactory.hpp',
'headerField.cpp', 'headerField.hpp',
@@ -115,6 +116,7 @@ libvmime_sources = [
'mailboxGroup.cpp', 'mailboxGroup.hpp',
'mailboxList.cpp', 'mailboxList.hpp',
'mediaType.cpp', 'mediaType.hpp',
+ 'messageAttachment.hpp',
'messageBuilder.cpp', 'messageBuilder.hpp',
'message.cpp', 'message.hpp',
'messageId.cpp', 'messageId.hpp',
@@ -125,6 +127,7 @@ libvmime_sources = [
'path.cpp', 'path.hpp',
'parameter.cpp', 'parameter.hpp',
'parameterizedHeaderField.cpp', 'parameterizedHeaderField.hpp',
+ 'parsedMessageAttachment.cpp', 'parsedMessageAttachment.hpp',
'parserHelpers.hpp',
'plainTextPart.cpp', 'plainTextPart.hpp',
'platformDependant.cpp', 'platformDependant.hpp',
@@ -2254,7 +2257,6 @@ env.Alias('msvc', env.GenerateMSVC('foo_msvc', 'SConstruct'))
def appendAdditionalDistFiles():
# Generate autotools-related files
generateAutotools([], [], env)
-
# Generate MSVC-related files
generateMSVC([], [], env)
diff --git a/src/attachmentHelper.cpp b/src/attachmentHelper.cpp
index a4970dd0..c1a1f057 100644
--- a/src/attachmentHelper.cpp
+++ b/src/attachmentHelper.cpp
@@ -24,7 +24,11 @@
#include "vmime/attachmentHelper.hpp"
#include "vmime/bodyPartAttachment.hpp"
+#include "vmime/parsedMessageAttachment.hpp"
+#include "vmime/generatedMessageAttachment.hpp"
+
#include "vmime/disposition.hpp"
+#include "vmime/emptyContentHandler.hpp"
namespace vmime
@@ -88,7 +92,31 @@ ref <const attachment>
if (!isBodyPartAnAttachment(part))
return NULL;
- return vmime::create <bodyPartAttachment>(part);
+ mediaType type;
+
+ try
+ {
+ const contentTypeField& ctf = dynamic_cast<contentTypeField&>
+ (*part->getHeader()->findField(fields::CONTENT_TYPE));
+
+ type = *ctf.getValue().dynamicCast <const mediaType>();
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // No "Content-type" field: assume "application/octet-stream".
+ type = mediaType(mediaTypes::APPLICATION,
+ mediaTypes::APPLICATION_OCTET_STREAM);
+ }
+
+ if (type.getType() == mediaTypes::MESSAGE &&
+ type.getSubType() == mediaTypes::MESSAGE_RFC822)
+ {
+ return vmime::create <generatedMessageAttachment>(part);
+ }
+ else
+ {
+ return vmime::create <bodyPartAttachment>(part);
+ }
}
@@ -144,36 +172,72 @@ void attachmentHelper::addAttachment(ref <message> msg, ref <attachment> att)
if (part == NULL) // create it
{
- // Create a new container part for the parts that were in
- // the root part of the message
- ref <bodyPart> container = vmime::create <bodyPart>();
-
- try
+ if (msg->getBody()->getPartCount() != 0)
{
- container->getHeader()->ContentType()->
- setValue(msg->getHeader()->ContentType()->getValue());
+ // Create a new container part for the parts that were in
+ // the root part of the message
+ ref <bodyPart> container = vmime::create <bodyPart>();
+
+ try
+ {
+ if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
+ {
+ container->getHeader()->ContentType()->setValue
+ (msg->getHeader()->ContentType()->getValue());
+ }
+
+ if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
+ {
+ container->getHeader()->ContentTransferEncoding()->setValue
+ (msg->getHeader()->ContentTransferEncoding()->getValue());
+ }
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // Ignore
+ }
+
+ // Move parts from the root part to this new part
+ const std::vector <ref <bodyPart> > partList =
+ msg->getBody()->getPartList();
+
+ msg->getBody()->removeAllParts();
+
+ for (unsigned int i = 0 ; i < partList.size() ; ++i)
+ container->getBody()->appendPart(partList[i]);
+
+ msg->getBody()->appendPart(container);
}
- catch (exceptions::no_such_field&)
+ else
{
- // Ignore
+ // The message is a simple (RFC-822) message, and do not
+ // contains any MIME part. Move the contents from the
+ // root to a new child part.
+ ref <bodyPart> child = vmime::create <bodyPart>();
+
+ if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
+ {
+ child->getHeader()->ContentType()->setValue
+ (msg->getHeader()->ContentType()->getValue());
+ }
+
+ if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
+ {
+ child->getHeader()->ContentTransferEncoding()->setValue
+ (msg->getHeader()->ContentTransferEncoding()->getValue());
+ }
+
+ child->getBody()->setContents(msg->getBody()->getContents());
+ msg->getBody()->setContents(vmime::create <emptyContentHandler>());
+
+ msg->getBody()->appendPart(child);
}
- msg->getHeader()->removeAllFields(vmime::fields::CONTENT_DISPOSITION);
- msg->getHeader()->removeAllFields(vmime::fields::CONTENT_TRANSFER_ENCODING);
-
- // Move parts from the root part to this new part
- const std::vector <ref <bodyPart> > partList =
- msg->getBody()->getPartList();
-
- msg->getBody()->removeAllParts();
-
- for (unsigned int i = 0 ; i < partList.size() ; ++i)
- container->getBody()->appendPart(partList[i]);
-
// Set the root part to 'multipart/mixed'
msg->getHeader()->ContentType()->setValue(mpMixed);
- msg->getBody()->appendPart(container);
+ msg->getHeader()->removeAllFields(vmime::fields::CONTENT_DISPOSITION);
+ msg->getHeader()->removeAllFields(vmime::fields::CONTENT_TRANSFER_ENCODING);
part = msg;
}
@@ -206,5 +270,13 @@ ref <bodyPart> attachmentHelper::findBodyPart
}
+// static
+void attachmentHelper::addAttachment(ref <message> msg, ref <message> amsg)
+{
+ ref <attachment> att = vmime::create <parsedMessageAttachment>(amsg);
+ addAttachment(msg, att);
+}
+
+
} // vmime
diff --git a/src/generatedMessageAttachment.cpp b/src/generatedMessageAttachment.cpp
new file mode 100644
index 00000000..189fca58
--- /dev/null
+++ b/src/generatedMessageAttachment.cpp
@@ -0,0 +1,105 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 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 2 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/generatedMessageAttachment.hpp"
+
+
+namespace vmime
+{
+
+
+generatedMessageAttachment::generatedMessageAttachment(ref <const bodyPart> part)
+ : m_bpa(vmime::create <bodyPartAttachment>(part))
+{
+}
+
+
+const mediaType generatedMessageAttachment::getType() const
+{
+ return mediaType(mediaTypes::MESSAGE, mediaTypes::MESSAGE_RFC822);
+}
+
+
+const text generatedMessageAttachment::getDescription() const
+{
+ return m_bpa->getDescription();
+}
+
+
+const word generatedMessageAttachment::getName() const
+{
+ return m_bpa->getName();
+}
+
+
+const ref <const contentHandler> generatedMessageAttachment::getData() const
+{
+ return m_bpa->getData();
+}
+
+
+const encoding generatedMessageAttachment::getEncoding() const
+{
+ return m_bpa->getEncoding();
+}
+
+
+ref <const object> generatedMessageAttachment::getPart() const
+{
+ return m_bpa->getPart();
+}
+
+
+ref <const header> generatedMessageAttachment::getHeader() const
+{
+ return m_bpa->getHeader();
+}
+
+
+ref <message> generatedMessageAttachment::getMessage() const
+{
+ if (m_msg == NULL)
+ {
+ // Extract data
+ std::ostringstream oss;
+ utility::outputStreamAdapter os(oss);
+
+ getData()->extract(os);
+
+ // Parse message
+ m_msg = vmime::create <message>();
+ m_msg->parse(oss.str());
+ }
+
+ return m_msg;
+}
+
+
+void generatedMessageAttachment::generateIn(bodyPart& /* parent */) const
+{
+ // Not used (see 'parsedMessageAttachment')
+}
+
+
+} // vmime
+
diff --git a/src/parsedMessageAttachment.cpp b/src/parsedMessageAttachment.cpp
new file mode 100644
index 00000000..9153a239
--- /dev/null
+++ b/src/parsedMessageAttachment.cpp
@@ -0,0 +1,114 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 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 2 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/parsedMessageAttachment.hpp"
+
+#include "vmime/stringContentHandler.hpp"
+#include "vmime/contentDisposition.hpp"
+
+
+namespace vmime
+{
+
+
+parsedMessageAttachment::parsedMessageAttachment(ref <message> msg)
+ : m_msg(msg)
+{
+}
+
+
+const mediaType parsedMessageAttachment::getType() const
+{
+ return mediaType(mediaTypes::MESSAGE, mediaTypes::MESSAGE_RFC822);
+}
+
+
+const text parsedMessageAttachment::getDescription() const
+{
+ return text();
+}
+
+
+const word parsedMessageAttachment::getName() const
+{
+ return word();
+}
+
+
+const ref <const contentHandler> parsedMessageAttachment::getData() const
+{
+ if (m_data == NULL)
+ {
+ std::ostringstream oss;
+ utility::outputStreamAdapter os(oss);
+
+ m_msg->generate(os);
+
+ m_data = vmime::create <stringContentHandler>(oss.str());
+ }
+
+ return m_data;
+}
+
+
+const encoding parsedMessageAttachment::getEncoding() const
+{
+ return encoding(encodingTypes::EIGHT_BIT); // not important
+}
+
+
+ref <const object> parsedMessageAttachment::getPart() const
+{
+ return NULL;
+}
+
+
+ref <const header> parsedMessageAttachment::getHeader() const
+{
+ return NULL;
+}
+
+
+ref <message> parsedMessageAttachment::getMessage() const
+{
+ return m_msg;
+}
+
+
+void parsedMessageAttachment::generateIn(bodyPart& parent) const
+{
+ // Create and append a new part for this attachment
+ ref <bodyPart> part = vmime::create <bodyPart>();
+ parent.getBody()->appendPart(part);
+
+ // Set header fields
+ part->getHeader()->ContentType()->setValue(getType());
+ part->getHeader()->ContentDisposition()->setValue(contentDisposition(contentDispositionTypes::ATTACHMENT));
+
+ // Set contents
+ part->getBody()->setContents(getData());
+}
+
+
+} // vmime
+
diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp
index 5a62574c..c3550f48 100644
--- a/tests/parser/attachmentHelperTest.cpp
+++ b/tests/parser/attachmentHelperTest.cpp
@@ -33,10 +33,13 @@ VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testAddAttachment1)
VMIME_TEST(testAddAttachment2)
+ VMIME_TEST(testAddAttachment3)
VMIME_TEST(testIsBodyPartAnAttachment1)
VMIME_TEST(testIsBodyPartAnAttachment2)
VMIME_TEST(testIsBodyPartAnAttachment3)
VMIME_TEST(testGetBodyPartAttachment)
+ VMIME_TEST(testAddAttachmentMessage1)
+ VMIME_TEST(testGetBodyPartAttachmentMessage)
VMIME_TEST_LIST_END
@@ -64,6 +67,18 @@ VMIME_TEST_SUITE_BEGIN
return res + "]";
}
+ static const vmime::string extractBodyContents(vmime::ref <const vmime::bodyPart> part)
+ {
+ vmime::ref <const vmime::contentHandler> cth = part->getBody()->getContents();
+
+ vmime::string data;
+ vmime::utility::outputStreamStringAdapter os(data);
+
+ cth->extract(os);
+
+ return data;
+ }
+
void testAddAttachment1()
{
vmime::string data =
@@ -82,6 +97,7 @@ VMIME_TEST_SUITE_BEGIN
vmime::attachmentHelper::addAttachment(msg, att);
VASSERT_EQ("1", "multipart/mixed[text/plain,image/jpeg]", getStructure(msg));
+ VASSERT_EQ("2", "The text\r\n", extractBodyContents(msg->getBody()->getPartAt(0)));
}
void testAddAttachment2()
@@ -110,6 +126,31 @@ VMIME_TEST_SUITE_BEGIN
vmime::attachmentHelper::addAttachment(msg, att);
VASSERT_EQ("1", "multipart/mixed[text/plain,application/octet-stream,image/jpeg]", getStructure(msg));
+ VASSERT_EQ("2", "The text", extractBodyContents(msg->getBody()->getPartAt(0)));
+ VASSERT_EQ("3", "Blah", extractBodyContents(msg->getBody()->getPartAt(1)));
+ VASSERT_EQ("4", "test", extractBodyContents(msg->getBody()->getPartAt(2)));
+ }
+
+ // Initial part is encoded
+ void testAddAttachment3()
+ {
+ vmime::string data =
+"Content-Type: text/plain\r\n"
+"Content-Transfer-Encoding: base64\r\n"
+"\r\n"
+"TWVzc2FnZSBib2R5";
+
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
+ msg->parse(data);
+
+ vmime::ref <vmime::attachment> att = vmime::create <vmime::defaultAttachment>
+ (vmime::create <vmime::stringContentHandler>("test"),
+ vmime::mediaType("image/jpeg"));
+
+ vmime::attachmentHelper::addAttachment(msg, att);
+
+ VASSERT_EQ("1", "multipart/mixed[text/plain,image/jpeg]", getStructure(msg));
+ VASSERT_EQ("2", "Message body", extractBodyContents(msg->getBody()->getPartAt(0)));
}
// Content-Disposition: attachment
@@ -201,5 +242,87 @@ VMIME_TEST_SUITE_BEGIN
VASSERT_EQ("7", part->getHeader()->generate(), att->getHeader()->generate());
}
+ void testAddAttachmentMessage1()
+ {
+ const vmime::string data =
+"Subject: Test message\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"Message body";
+
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
+ msg->parse(data);
+
+ const vmime::string attData =
+"Subject: Attached message\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Transfer-Encoding: base64\r\n"
+"\r\n"
+"QXR0YWNoZWQgbWVzc2FnZSBib2R5";
+
+ vmime::ref <vmime::message> amsg = vmime::create <vmime::message>();
+ amsg->parse(attData);
+
+ vmime::attachmentHelper::addAttachment(msg, amsg);
+
+ VASSERT_EQ("1", "multipart/mixed[text/plain,message/rfc822]", getStructure(msg));
+ VASSERT_EQ("2", "Message body", extractBodyContents(msg->getBody()->getPartAt(0)));
+
+ // Ensure message has been encoded properly
+ vmime::ref <const vmime::bodyPart> attPart = msg->getBody()->getPartAt(1);
+ vmime::ref <const vmime::contentHandler> attCth = attPart->getBody()->getContents();
+
+ vmime::string attDataOut;
+ vmime::utility::outputStreamStringAdapter attDataOutOs(attDataOut);
+
+ attCth->extract(attDataOutOs);
+
+ vmime::ref <vmime::message> amsgOut = vmime::create <vmime::message>();
+ amsgOut->parse(attDataOut);
+
+ vmime::ref <vmime::header> hdr = amsgOut->getHeader();
+
+ VASSERT_EQ("3", "Attached message", hdr->Subject()->getValue().dynamicCast <vmime::text>()->generate());
+ VASSERT_EQ("4", "Attached message body", extractBodyContents(amsgOut));
+ }
+
+ void testGetBodyPartAttachmentMessage()
+ {
+ const vmime::string data =
+"Subject: Test message\r\n"
+"Content-Type: multipart/mixed; boundary=\"foo\"\r\n"
+"\r\n"
+"--foo\r\n"
+"Content-Type: message/rfc822\r\n"
+"\r\n"
+"Subject: Attached message\r\n"
+"\r\n"
+"Attached message body\r\n"
+"--foo\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"FooBar\r\n"
+"--foo--\r\n";
+
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
+ msg->parse(data);
+
+ vmime::ref <const vmime::attachment> att = vmime::attachmentHelper::
+ getBodyPartAttachment(msg->getBody()->getPartAt(0));
+
+ VASSERT("1", att != NULL);
+
+ vmime::ref <const vmime::messageAttachment> msgAtt =
+ att.dynamicCast <const vmime::messageAttachment>();
+
+ VASSERT("2", msgAtt != NULL);
+
+ vmime::ref <vmime::message> amsg = msgAtt->getMessage();
+ vmime::ref <vmime::header> hdr = amsg->getHeader();
+
+ VASSERT_EQ("3", "Attached message", hdr->Subject()->getValue().dynamicCast <vmime::text>()->generate());
+ VASSERT_EQ("4", "Attached message body", extractBodyContents(amsg));
+ }
+
VMIME_TEST_SUITE_END
diff --git a/vmime/attachmentHelper.hpp b/vmime/attachmentHelper.hpp
index 0e8d81d8..6f622a6d 100644
--- a/vmime/attachmentHelper.hpp
+++ b/vmime/attachmentHelper.hpp
@@ -78,6 +78,13 @@ public:
*/
static void addAttachment(ref <message> msg, ref <attachment> att);
+ /** Add a message attachment to the specified message.
+ *
+ * @param msg message into which to add the attachment
+ * @param amsg message to attach
+ */
+ static void addAttachment(ref <message> msg, ref <message> amsg);
+
protected:
static const std::vector <ref <const attachment> >
diff --git a/vmime/bodyPartAttachment.hpp b/vmime/bodyPartAttachment.hpp
index 7ac1914e..24e51423 100644
--- a/vmime/bodyPartAttachment.hpp
+++ b/vmime/bodyPartAttachment.hpp
@@ -25,6 +25,9 @@
#define VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
+#ifndef VMIME_BUILDING_DOC // implementation detail
+
+
#include "vmime/attachment.hpp"
#include "vmime/contentDispositionField.hpp"
@@ -72,5 +75,8 @@ private:
} // vmime
+#endif // VMIME_BUILDING_DOC
+
+
#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
diff --git a/vmime/generatedMessageAttachment.hpp b/vmime/generatedMessageAttachment.hpp
new file mode 100644
index 00000000..814340ca
--- /dev/null
+++ b/vmime/generatedMessageAttachment.hpp
@@ -0,0 +1,79 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 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 2 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_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED
+#define VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED
+
+
+#ifndef VMIME_BUILDING_DOC // implementation detail
+
+
+#include "vmime/messageAttachment.hpp"
+#include "vmime/bodyPartAttachment.hpp"
+
+
+namespace vmime
+{
+
+
+/** A message attachment that can be extracted from a message.
+ */
+class generatedMessageAttachment : public messageAttachment
+{
+public:
+
+ generatedMessageAttachment(ref <const bodyPart> part);
+
+ const mediaType getType() const;
+ const text getDescription() const;
+ const word getName() const;
+
+ const ref <const contentHandler> getData() const;
+
+ const encoding getEncoding() const;
+
+ ref <const object> getPart() const;
+
+ ref <const header> getHeader() const;
+
+ ref <message> getMessage() const;
+
+protected:
+
+ void generateIn(bodyPart& parent) const;
+
+private:
+
+ ref <bodyPartAttachment> m_bpa;
+ mutable ref <message> m_msg;
+};
+
+
+} // vmime
+
+
+#endif // !VMIME_BUILDING_DOC
+
+
+#endif // VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED
+
diff --git a/vmime/messageAttachment.hpp b/vmime/messageAttachment.hpp
new file mode 100644
index 00000000..03fffb0c
--- /dev/null
+++ b/vmime/messageAttachment.hpp
@@ -0,0 +1,55 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 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 2 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_MESSAGEATTACHMENT_HPP_INCLUDED
+#define VMIME_MESSAGEATTACHMENT_HPP_INCLUDED
+
+
+#include "vmime/attachment.hpp"
+#include "vmime/message.hpp"
+
+
+namespace vmime
+{
+
+
+/** Attachment of type message/rfc822.
+ */
+
+class messageAttachment : public attachment
+{
+public:
+
+ /** Return the message encapsulated in this attachment.
+ *
+ * @return encapsulated message
+ */
+ virtual ref <message> getMessage() const = 0;
+};
+
+
+} // vmime
+
+
+#endif // VMIME_MESSAGEATTACHMENT_HPP_INCLUDED
+
diff --git a/vmime/parsedMessageAttachment.hpp b/vmime/parsedMessageAttachment.hpp
new file mode 100644
index 00000000..2bb78a63
--- /dev/null
+++ b/vmime/parsedMessageAttachment.hpp
@@ -0,0 +1,78 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 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 2 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_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED
+#define VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED
+
+
+#ifndef VMIME_BUILDING_DOC // implementation detail
+
+
+#include "vmime/messageAttachment.hpp"
+
+
+namespace vmime
+{
+
+
+/** A message attachment that can be generated into a message.
+ */
+class parsedMessageAttachment : public messageAttachment
+{
+public:
+
+ parsedMessageAttachment(ref <message> msg);
+
+ const mediaType getType() const;
+ const text getDescription() const;
+ const word getName() const;
+
+ const ref <const contentHandler> getData() const;
+
+ const encoding getEncoding() const;
+
+ ref <const object> getPart() const;
+
+ ref <const header> getHeader() const;
+
+ ref <message> getMessage() const;
+
+protected:
+
+ void generateIn(bodyPart& parent) const;
+
+private:
+
+ ref <message> m_msg;
+ mutable ref <contentHandler> m_data;
+};
+
+
+} // vmime
+
+
+#endif // !VMIME_BUILDING_DOC
+
+
+#endif // VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED
+
diff --git a/vmime/vmime.hpp b/vmime/vmime.hpp
index cbae859e..9d2cddb7 100644
--- a/vmime/vmime.hpp
+++ b/vmime/vmime.hpp
@@ -74,6 +74,7 @@
#include "vmime/fileAttachment.hpp"
#include "vmime/defaultAttachment.hpp"
+#include "vmime/messageAttachment.hpp"
#include "vmime/plainTextPart.hpp"
#include "vmime/htmlTextPart.hpp"