From aa4d426b4d3527d7e166df1a05058c9a4a0f6683 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 30 Apr 2021 00:33:56 +0200 Subject: initial/final commit --- vmime-master/src/vmime/messageBuilder.cpp | 333 ++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 vmime-master/src/vmime/messageBuilder.cpp (limited to 'vmime-master/src/vmime/messageBuilder.cpp') diff --git a/vmime-master/src/vmime/messageBuilder.cpp b/vmime-master/src/vmime/messageBuilder.cpp new file mode 100644 index 0000000..4de81bf --- /dev/null +++ b/vmime-master/src/vmime/messageBuilder.cpp @@ -0,0 +1,333 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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/messageBuilder.hpp" + +#include "vmime/dateTime.hpp" +#include "vmime/textPartFactory.hpp" + + +namespace vmime { + + +messageBuilder::messageBuilder() { + + // By default there is one text part of type "text/plain" + constructTextPart(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); +} + + +messageBuilder::~messageBuilder() { + +} + + +shared_ptr messageBuilder::construct() const { + + // Create a new message + shared_ptr msg = make_shared (); + + // Generate the header fields + msg->getHeader()->Subject()->setValue(m_subject); + + if (((m_to.isEmpty()) || (m_to.getAddressAt(0)->isEmpty() && !m_to.getAddressAt(0)->isGroup())) && + (m_cc.isEmpty() || m_cc.getAddressAt(0)->isEmpty()) && + (m_bcc.isEmpty() || m_bcc.getAddressAt(0)->isEmpty())) { + + throw exceptions::no_recipient(); + } + + if (!m_from.isEmpty()) { + msg->getHeader()->From()->setValue(m_from); + } + + if (!m_to.isEmpty()) { + msg->getHeader()->To()->setValue(m_to); + } + + if (!m_cc.isEmpty()) { + msg->getHeader()->Cc()->setValue(m_cc); + } + + if (!m_bcc.isEmpty()) { + msg->getHeader()->Bcc()->setValue(m_bcc); + } + + // Add a "Date" field + msg->getHeader()->Date()->setValue(datetime::now()); + + // Add a "Mime-Version" header field + msg->getHeader()->MimeVersion()->setValue(string(SUPPORTED_MIME_VERSION)); + + // If there is one or more attachments (or other parts that are + // not "text/...") and if there is more than one parts for the + // text part, we generate these text parts into a sub-part: + // + // [message] + // | + // +-- multipart/mixed + // | + // +-- multipart/alternative + // | | + // | +-- text part #1 (eg. plain text "text/plain") + // | +-- text part #2 (eg. HTML "text/html") + // | +-- ... + // | + // +-- application/octet-stream (attachment #1) + // | + // +-- ... (other attachments/parts) + // + if (!m_attach.empty() && m_textPart->getPartCount() > 1) { + + // Set parent part (message) to "multipart/mixed" + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED) + ); + + // Create a sub-part "multipart/alternative" for text parts + shared_ptr subPart = make_shared (); + msg->getBody()->appendPart(subPart); + + subPart->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE) + ); + + // Generate the text parts into this sub-part (normally, this + // sub-part will have the "multipart/alternative" content-type...) + m_textPart->generateIn(msg, subPart); + + } else { + + // Generate the text part(s) directly into the message + m_textPart->generateIn(msg, msg); + + // If any attachment, set message content-type to "multipart/mixed" + if (!m_attach.empty()) { + + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED) + ); + + // Else, set it to "multipart/alternative" if there are more than one text part. + } else if (m_textPart->getPartCount() > 1) { + + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE) + ); + } + } + + // Generate the attachments + if (!m_attach.empty()) { + + for (std::vector >::const_iterator a = m_attach.begin() ; + a != m_attach.end() ; ++a) { + + (*a)->generateIn(msg); + } + } + + // If there is only one part in the message, move it into the message + // (hence, the message will not be multipart...) + if (msg->getBody()->getPartCount() == 1) { + + const bodyPart& part = *msg->getBody()->getPartAt(0); + + // Make a full copy of the body, otherwise the copyFrom() will delete the body we're copying + shared_ptr bodyCopy = vmime::clone(part.getBody()); + + // First, copy (and replace) the header fields + const std::vector > fields = part.getHeader()->getFieldList(); + + for (std::vector >::const_iterator it = fields.begin() ; + it != fields.end() ; ++it) { + + *(msg->getHeader()->getField((*it)->getName())) = **it; + } + + // Second, copy the body contents and sub-parts (this also remove + // the body part we are copying...) + msg->getBody()->copyFrom(*bodyCopy); + } + + return msg; +} + + +void messageBuilder::attach(const shared_ptr & attach) { + + appendAttachment(attach); +} + + +void messageBuilder::appendAttachment(const shared_ptr & attach) { + + m_attach.push_back(attach); +} + + +void messageBuilder::constructTextPart(const mediaType& type) { + + shared_ptr part; + + try { + part = textPartFactory::getInstance()->create(type); + } catch (exceptions::no_factory_available& e) { + throw; + } + + m_textPart = part; +} + + +shared_ptr messageBuilder::getTextPart() { + + return m_textPart; +} + + +const mailbox& messageBuilder::getExpeditor() const { + + return m_from; +} + + +void messageBuilder::setExpeditor(const mailbox& expeditor) { + + m_from = expeditor; +} + + +const addressList& messageBuilder::getRecipients() const { + + return m_to; +} + + +addressList& messageBuilder::getRecipients() { + + return m_to; +} + + +void messageBuilder::setRecipients(const addressList& recipients) { + + m_to = recipients; +} + + +const addressList& messageBuilder::getCopyRecipients() const { + + return m_cc; +} + + +addressList& messageBuilder::getCopyRecipients() { + + return m_cc; +} + + +void messageBuilder::setCopyRecipients(const addressList& cc) { + + m_cc = cc; +} + + +const addressList& messageBuilder::getBlindCopyRecipients() const { + + return m_bcc; +} + + +addressList& messageBuilder::getBlindCopyRecipients() { + + return m_bcc; +} + + +void messageBuilder::setBlindCopyRecipients(const addressList& bcc) { + + m_bcc = bcc; +} + + +const text& messageBuilder::getSubject() const { + + return m_subject; +} + + +void messageBuilder::setSubject(const text& subject) { + + m_subject = subject; +} + + +void messageBuilder::removeAttachment(const size_t pos) { + + m_attach.erase(m_attach.begin() + pos); +} + + +const shared_ptr messageBuilder::getAttachmentAt(const size_t pos) const { + + return m_attach[pos]; +} + + +shared_ptr messageBuilder::getAttachmentAt(const size_t pos) { + + return m_attach[pos]; +} + + +size_t messageBuilder::getAttachmentCount() const { + + return m_attach.size(); +} + + +const std::vector > messageBuilder::getAttachmentList() const { + + std::vector > res; + + res.reserve(m_attach.size()); + + for (std::vector >::const_iterator it = m_attach.begin() ; + it != m_attach.end() ; ++it) { + + res.push_back(*it); + } + + return res; +} + + +const std::vector > messageBuilder::getAttachmentList() { + + return m_attach; +} + + +} // vmime -- cgit v1.2.3