aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attachmentHelper.cpp112
-rw-r--r--src/generatedMessageAttachment.cpp105
-rw-r--r--src/parsedMessageAttachment.cpp114
3 files changed, 311 insertions, 20 deletions
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>();
- msg->getHeader()->removeAllFields(vmime::fields::CONTENT_DISPOSITION);
- msg->getHeader()->removeAllFields(vmime::fields::CONTENT_TRANSFER_ENCODING);
+ if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
+ {
+ child->getHeader()->ContentType()->setValue
+ (msg->getHeader()->ContentType()->getValue());
+ }
- // Move parts from the root part to this new part
- const std::vector <ref <bodyPart> > partList =
- msg->getBody()->getPartList();
+ if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
+ {
+ child->getHeader()->ContentTransferEncoding()->setValue
+ (msg->getHeader()->ContentTransferEncoding()->getValue());
+ }
- msg->getBody()->removeAllParts();
+ child->getBody()->setContents(msg->getBody()->getContents());
+ msg->getBody()->setContents(vmime::create <emptyContentHandler>());
- for (unsigned int i = 0 ; i < partList.size() ; ++i)
- container->getBody()->appendPart(partList[i]);
+ msg->getBody()->appendPart(child);
+ }
// 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
+