diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/attachmentHelper.cpp | 112 | ||||
| -rw-r--r-- | src/generatedMessageAttachment.cpp | 105 | ||||
| -rw-r--r-- | src/parsedMessageAttachment.cpp | 114 |
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 + |
