aboutsummaryrefslogtreecommitdiffstats
path: root/src/htmlTextPart.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-12-29 09:02:12 +0000
committerVincent Richard <[email protected]>2013-12-29 09:02:12 +0000
commit152c6bed75598a6ca5efb7914701157270155833 (patch)
tree8faced1d75a45c819630323da256248415992ed0 /src/htmlTextPart.cpp
parentMerge branch 'master' of https://github.com/kisli/vmime (diff)
downloadvmime-152c6bed75598a6ca5efb7914701157270155833.tar.gz
vmime-152c6bed75598a6ca5efb7914701157270155833.zip
Merged source and header files in directory structure. Got rid of SConstruct build.
Diffstat (limited to 'src/htmlTextPart.cpp')
-rw-r--r--src/htmlTextPart.cpp510
1 files changed, 0 insertions, 510 deletions
diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp
deleted file mode 100644
index 44459336..00000000
--- a/src/htmlTextPart.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 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/htmlTextPart.hpp"
-#include "vmime/exception.hpp"
-
-#include "vmime/contentTypeField.hpp"
-#include "vmime/contentDisposition.hpp"
-#include "vmime/text.hpp"
-
-#include "vmime/emptyContentHandler.hpp"
-#include "vmime/stringContentHandler.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-
-
-namespace vmime
-{
-
-
-htmlTextPart::htmlTextPart()
- : m_plainText(make_shared <emptyContentHandler>()),
- m_text(make_shared <emptyContentHandler>())
-{
-}
-
-
-htmlTextPart::~htmlTextPart()
-{
-}
-
-
-const mediaType htmlTextPart::getType() const
-{
- return mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML);
-}
-
-
-size_t htmlTextPart::getPartCount() const
-{
- return (m_plainText->isEmpty() ? 1 : 2);
-}
-
-
-void htmlTextPart::generateIn(shared_ptr <bodyPart> /* message */, shared_ptr <bodyPart> parent) const
-{
- // Plain text
- if (!m_plainText->isEmpty())
- {
- // -- Create a new part
- shared_ptr <bodyPart> part = make_shared <bodyPart>();
- parent->getBody()->appendPart(part);
-
- // -- Set contents
- part->getBody()->setContents(m_plainText,
- mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), m_charset,
- encoding::decide(m_plainText, m_charset, encoding::USAGE_TEXT));
- }
-
- // HTML text
- // -- Create a new part
- shared_ptr <bodyPart> htmlPart = make_shared <bodyPart>();
-
- // -- Set contents
- htmlPart->getBody()->setContents(m_text,
- mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML), m_charset,
- encoding::decide(m_text, m_charset, encoding::USAGE_TEXT));
-
- // Handle the case we have embedded objects
- if (!m_objects.empty())
- {
- // Create a "multipart/related" body part
- shared_ptr <bodyPart> relPart = make_shared <bodyPart>();
- parent->getBody()->appendPart(relPart);
-
- relPart->getHeader()->ContentType()->
- setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED));
-
- // Add the HTML part into this part
- relPart->getBody()->appendPart(htmlPart);
-
- // Also add objects into this part
- for (std::vector <shared_ptr <embeddedObject> >::const_iterator it = m_objects.begin() ;
- it != m_objects.end() ; ++it)
- {
- shared_ptr <bodyPart> objPart = make_shared <bodyPart>();
- relPart->getBody()->appendPart(objPart);
-
- string id = (*it)->getId();
-
- if (id.substr(0, 4) == "CID:")
- id = id.substr(4);
-
- objPart->getHeader()->ContentType()->setValue((*it)->getType());
- objPart->getHeader()->ContentId()->setValue(messageId("<" + id + ">"));
- objPart->getHeader()->ContentDisposition()->setValue(contentDisposition(contentDispositionTypes::INLINE));
- objPart->getHeader()->ContentTransferEncoding()->setValue((*it)->getEncoding());
- //encoding(encodingTypes::BASE64);
-
- objPart->getBody()->setContents((*it)->getData()->clone());
- }
- }
- else
- {
- // Add the HTML part into the parent part
- parent->getBody()->appendPart(htmlPart);
- }
-}
-
-
-void htmlTextPart::findEmbeddedParts(const bodyPart& part,
- std::vector <shared_ptr <const bodyPart> >& cidParts, std::vector <shared_ptr <const bodyPart> >& locParts)
-{
- for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i)
- {
- shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
-
- // For a part to be an embedded object, it must have either a
- // Content-Id field or a Content-Location field.
- if (p->getHeader()->hasField(fields::CONTENT_ID))
- cidParts.push_back(p);
-
- if (p->getHeader()->hasField(fields::CONTENT_LOCATION))
- locParts.push_back(p);
-
- findEmbeddedParts(*p, cidParts, locParts);
- }
-}
-
-
-void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id,
- const embeddedObject::ReferenceType refType)
-{
- // The object may already exists. This can happen if an object is
- // identified by both a Content-Id and a Content-Location. In this
- // case, there will be two embedded objects with two different IDs
- // but referencing the same content.
-
- mediaType type;
-
- shared_ptr <const headerField> ctf =
- part.getHeader()->findField(fields::CONTENT_TYPE);
-
- if (ctf)
- {
- type = *ctf->getValue <mediaType>();
- }
- else
- {
- // No "Content-type" field: assume "application/octet-stream".
- }
-
- m_objects.push_back(make_shared <embeddedObject>
- (vmime::clone(part.getBody()->getContents()),
- part.getBody()->getEncoding(), id, type, refType));
-}
-
-
-void htmlTextPart::parse(shared_ptr <const bodyPart> message, shared_ptr <const bodyPart> parent, shared_ptr <const bodyPart> textPart)
-{
- // Search for possible embedded objects in the _whole_ message.
- std::vector <shared_ptr <const bodyPart> > cidParts;
- std::vector <shared_ptr <const bodyPart> > locParts;
-
- findEmbeddedParts(*message, cidParts, locParts);
-
- // Extract HTML text
- std::ostringstream oss;
- utility::outputStreamAdapter adapter(oss);
-
- textPart->getBody()->getContents()->extract(adapter);
-
- const string data = oss.str();
-
- m_text = textPart->getBody()->getContents()->clone();
-
- // Find charset
- shared_ptr <const contentTypeField> ctf =
- textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
-
- if (ctf && ctf->hasCharset())
- m_charset = ctf->getCharset();
- else
- m_charset = charset();
-
- // Extract embedded objects. The algorithm is quite simple: for each previously
- // found inline part, we check if its CID/Location is contained in the HTML text.
- for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p)
- {
- const shared_ptr <const headerField> midField =
- (*p)->getHeader()->findField(fields::CONTENT_ID);
-
- const messageId mid = *midField->getValue <messageId>();
-
- if (data.find("CID:" + mid.getId()) != string::npos ||
- data.find("cid:" + mid.getId()) != string::npos)
- {
- // This part is referenced in the HTML text.
- // Add it to the embedded object list.
- addEmbeddedObject(**p, mid.getId(), embeddedObject::REFERENCED_BY_ID);
- }
- }
-
- for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = locParts.begin() ; p != locParts.end() ; ++p)
- {
- const shared_ptr <const headerField> locField =
- (*p)->getHeader()->findField(fields::CONTENT_LOCATION);
-
- const text loc = *locField->getValue <text>();
- const string locStr = loc.getWholeBuffer();
-
- if (data.find(locStr) != string::npos)
- {
- // This part is referenced in the HTML text.
- // Add it to the embedded object list.
- addEmbeddedObject(**p, locStr, embeddedObject::REFERENCED_BY_LOCATION);
- }
- }
-
- // Extract plain text, if any.
- if (!findPlainTextPart(*message, *parent, *textPart))
- {
- m_plainText = make_shared <emptyContentHandler>();
- }
-}
-
-
-bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart)
-{
- // We search for the nearest "multipart/alternative" part.
- const shared_ptr <const headerField> ctf =
- part.getHeader()->findField(fields::CONTENT_TYPE);
-
- if (ctf)
- {
- const mediaType type = *ctf->getValue <mediaType>();
-
- if (type.getType() == mediaTypes::MULTIPART &&
- type.getSubType() == mediaTypes::MULTIPART_ALTERNATIVE)
- {
- shared_ptr <const bodyPart> foundPart;
-
- for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i)
- {
- const shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
-
- if (p.get() == &parent || // if "text/html" is in "multipart/related"
- p.get() == &textPart) // if not...
- {
- foundPart = p;
- }
- }
-
- if (foundPart)
- {
- bool found = false;
-
- // Now, search for the alternative plain text part
- for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
- {
- const shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
-
- const shared_ptr <const headerField> ctf =
- p->getHeader()->findField(fields::CONTENT_TYPE);
-
- if (ctf)
- {
-
- const mediaType type = *ctf->getValue <mediaType>();
-
- if (type.getType() == mediaTypes::TEXT &&
- type.getSubType() == mediaTypes::TEXT_PLAIN)
- {
- m_plainText = p->getBody()->getContents()->clone();
- found = true;
- }
- }
- else
- {
- // No "Content-type" field.
- }
- }
-
- // If we don't have found the plain text part here, it means that
- // it does not exists (the MUA which built this message probably
- // did not include it...).
- return found;
- }
- }
- }
- else
- {
- // No "Content-type" field.
- }
-
- bool found = false;
-
- for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
- {
- found = findPlainTextPart(*part.getBody()->getPartAt(i), parent, textPart);
- }
-
- return found;
-}
-
-
-const charset& htmlTextPart::getCharset() const
-{
- return m_charset;
-}
-
-
-void htmlTextPart::setCharset(const charset& ch)
-{
- m_charset = ch;
-}
-
-
-shared_ptr <const contentHandler> htmlTextPart::getPlainText() const
-{
- return m_plainText;
-}
-
-
-void htmlTextPart::setPlainText(shared_ptr <contentHandler> plainText)
-{
- m_plainText = plainText->clone();
-}
-
-
-const shared_ptr <const contentHandler> htmlTextPart::getText() const
-{
- return m_text;
-}
-
-
-void htmlTextPart::setText(shared_ptr <contentHandler> text)
-{
- m_text = text->clone();
-}
-
-
-size_t htmlTextPart::getObjectCount() const
-{
- return m_objects.size();
-}
-
-
-shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::getObjectAt(const size_t pos) const
-{
- return m_objects[pos];
-}
-
-
-shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::findObject(const string& id) const
-{
- for (std::vector <shared_ptr <embeddedObject> >::const_iterator o = m_objects.begin() ;
- o != m_objects.end() ; ++o)
- {
- if ((*o)->matchesId(id))
- return *o;
- }
-
- return null;
-}
-
-
-bool htmlTextPart::hasObject(const string& id) const
-{
- for (std::vector <shared_ptr <embeddedObject> >::const_iterator o = m_objects.begin() ;
- o != m_objects.end() ; ++o)
- {
- if ((*o)->matchesId(id))
- return true;
- }
-
- return false;
-}
-
-
-shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
- (shared_ptr <contentHandler> data, const vmime::encoding& enc, const mediaType& type)
-{
- const messageId mid(messageId::generateId());
-
- shared_ptr <embeddedObject> obj = make_shared <embeddedObject>
- (data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID);
-
- m_objects.push_back(obj);
-
- return obj;
-}
-
-
-shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
- (shared_ptr <contentHandler> data, const mediaType& type)
-{
- return addObject(data, encoding::decide(data), type);
-}
-
-
-shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
- (const string& data, const mediaType& type)
-{
- shared_ptr <stringContentHandler> cts = make_shared <stringContentHandler>(data);
- return addObject(cts, encoding::decide(cts), type);
-}
-
-
-
-//
-// htmlTextPart::embeddedObject
-//
-
-htmlTextPart::embeddedObject::embeddedObject
- (shared_ptr <contentHandler> data, const encoding& enc,
- const string& id, const mediaType& type, const ReferenceType refType)
- : m_data(vmime::clone(data)),
- m_encoding(enc), m_id(id), m_type(type), m_refType(refType)
-{
-}
-
-
-shared_ptr <const contentHandler> htmlTextPart::embeddedObject::getData() const
-{
- return m_data;
-}
-
-
-const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const
-{
- return m_encoding;
-}
-
-
-const string htmlTextPart::embeddedObject::getId() const
-{
- return m_id;
-}
-
-
-const string htmlTextPart::embeddedObject::getReferenceId() const
-{
- if (m_refType == REFERENCED_BY_ID)
- return string("CID:") + m_id;
- else
- return m_id;
-}
-
-
-const mediaType htmlTextPart::embeddedObject::getType() const
-{
- return m_type;
-}
-
-
-htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const
-{
- return m_refType;
-}
-
-
-bool htmlTextPart::embeddedObject::matchesId(const string& id) const
-{
- if (m_refType == REFERENCED_BY_ID)
- return m_id == cleanId(id);
- else
- return m_id == id;
-}
-
-
-// static
-const string htmlTextPart::embeddedObject::cleanId(const string& id)
-{
- if (id.length() >= 4 &&
- (id[0] == 'c' || id[0] == 'C') &&
- (id[1] == 'i' || id[1] == 'I') &&
- (id[2] == 'd' || id[2] == 'D') &&
- id[3] == ':')
- {
- return id.substr(4);
- }
- else
- {
- return id;
- }
-}
-
-
-} // vmime