diff options
Diffstat (limited to 'vmime-master/src/vmime/relay.cpp')
-rw-r--r-- | vmime-master/src/vmime/relay.cpp | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/relay.cpp b/vmime-master/src/vmime/relay.cpp new file mode 100644 index 0000000..b0a6b60 --- /dev/null +++ b/vmime-master/src/vmime/relay.cpp @@ -0,0 +1,363 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard <vincent@vmime.org> +// +// 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/relay.hpp" +#include "vmime/text.hpp" +#include "vmime/parserHelpers.hpp" +#include "vmime/utility/outputStreamAdapter.hpp" + +#include <sstream> + + +namespace vmime { + + +relay::relay() { + +} + + +relay::relay(const relay& r) + : headerFieldValue() { + + copyFrom(r); +} + + +/* + + RFC #2822: + + received = "Received" ":" ; one per relay + ["from" domain] ; sending host + ["by" domain] ; receiving host + ["via" atom] ; physical path + *("with" atom) ; link/mail protocol + ["id" msg-id] ; receiver msg id + ["for" addr-spec] ; initial form +*/ + +void relay::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + + const char* const pend = buffer.data() + end; + const char* const pstart = buffer.data() + position; + const char* p = pend - 1; + + // Find the beginning of the date part + while (p >= pstart && *p != ';') { + --p; + } + + if (p >= pstart) { + + // Parse the date/time part + m_date.parse(ctx, buffer, position + (p - pstart) + 1, end); + + // Parse the components + std::istringstream iss( + string(buffer.begin() + position, buffer.begin() + position + (p - pstart)) + ); + + iss.imbue(std::locale::classic()); + + string word; + std::vector <string> previous; + + enum Parts { + Part_None, + Part_From, // The "from" part + Part_By, // The "by" part + Part_Via, // The "via" part + Part_With, // One "with" part + Part_Id, // The "id" part + Part_For, // The "for" part + Part_End + }; + + Parts part = Part_None; + bool cont = true; + bool inComment = false; + + while (cont) { + + Parts newPart = Part_None; + + if ((cont = !(iss >> word).fail())) { + + // A little hack for handling comments + if (inComment) { + + size_t par = word.find(')'); + + if (par != string::npos) { + + previous.push_back(string(word.begin(), word.begin() + par + 1)); + word.erase(word.begin(), word.begin() + par + 1); + inComment = false; + } + } + + bool keyword = false; + + if (!inComment) { + + if (utility::stringUtils::isStringEqualNoCase(word, "from", 4)) { + + newPart = Part_From; + keyword = true; + + } else if (utility::stringUtils::isStringEqualNoCase(word, "by", 2)) { + + newPart = Part_By; + keyword = true; + + } else if (utility::stringUtils::isStringEqualNoCase(word, "via", 2)) { + + newPart = Part_Via; + keyword = true; + + } else if (utility::stringUtils::isStringEqualNoCase(word, "with", 2)) { + + newPart = Part_With; + keyword = true; + + } else if (utility::stringUtils::isStringEqualNoCase(word, "id", 2)) { + + newPart = Part_Id; + keyword = true; + + } else if (utility::stringUtils::isStringEqualNoCase(word, "for", 2)) { + + newPart = Part_For; + keyword = true; + } + } + + if (!keyword) { + + if (word.find('(') != string::npos) { + inComment = true; + } + + previous.push_back(word); + } + } + + if (!cont || newPart != Part_None) { + + if (part != Part_None) { + + std::ostringstream value; + + for (std::vector <string>::const_iterator + it = previous.begin() ; it != previous.end() ; ++it) { + + if (it != previous.begin()) value << " "; + value << *it; + } + + switch (part) { + case Part_From: m_from = value.str(); break; + case Part_By: m_by = value.str(); break; + case Part_Via: m_via = value.str(); break; + case Part_With: m_with.push_back(value.str()); break; + case Part_Id: m_id = value.str(); break; + case Part_For: m_for = value.str(); break; + default: break; // Should never happen... + } + } + + previous.clear(); + part = newPart; + } + } + } + + setParsedBounds(position, end); + + if (newPosition) { + *newPosition = end; + } +} + + +void relay::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + + std::ostringstream oss; + int count = 0; + + if (m_from.length()) oss << (count++ > 0 ? " " : "") << "from " << m_from; + if (m_by.length()) oss << (count++ > 0 ? " " : "") << "by " << m_by; + if (m_via.length()) oss << (count++ > 0 ? " " : "") << "via " << m_via; + + for (std::vector <string>::const_iterator + it = m_with.begin() ; it != m_with.end() ; ++it) { + + oss << (count++ > 0 ? " " : "") << "with " << *it; + } + + if (m_id.length()) oss << (count++ > 0 ? " " : "") << "id " << m_id; + if (m_for.length()) oss << (count++ > 0 ? " " : "") << "for " << m_for; + + oss << "; "; + + vmime::utility::outputStreamAdapter dos(oss); + m_date.generate(ctx, dos, 0, NULL); + + text(oss.str()).encodeAndFold(ctx, os, curLinePos, newLinePos, text::FORCE_NO_ENCODING); +} + + +void relay::copyFrom(const component& other) { + + const relay& r = dynamic_cast <const relay&>(other); + + m_from = r.m_from; + m_via = r.m_via; + m_by = r.m_by; + m_id = r.m_id; + m_for = r.m_for; + + m_with.resize(r.m_with.size()); + std::copy(r.m_with.begin(), r.m_with.end(), m_with.begin()); + + m_date = r.m_date; +} + + +relay& relay::operator=(const relay& other) { + + copyFrom(other); + return *this; +} + + +shared_ptr <component> relay::clone() const { + + return make_shared <relay>(*this); +} + + +const string& relay::getFrom() const { + + return m_from; +} + + +void relay::setFrom(const string& from) { + + m_from = from; +} + + +const string& relay::getVia() const { + + return m_via; +} + + +void relay::setVia(const string& via) { + + m_via = via; +} + + +const string& relay::getBy() const { + + return m_by; +} + + +void relay::setBy(const string& by) { + + m_by = by; +} + + +const string& relay::getId() const { + + return m_id; +} + + +void relay::setId(const string& id) { + + m_id = id; +} + + +const string& relay::getFor() const { + + return m_for; +} + + +void relay::setFor(const string& for_) { + + m_for = for_; +} + + +const datetime& relay::getDate() const { + + return m_date; +} + + +void relay::setDate(const datetime& date) { + + m_date = date; +} + + +const std::vector <string>& relay::getWithList() const { + + return m_with; +} + + +std::vector <string>& relay::getWithList() { + + return m_with; +} + + +const std::vector <shared_ptr <component> > relay::getChildComponents() { + + // TODO: should fields inherit from 'component'? (using typeAdapter) + return std::vector <shared_ptr <component> >(); +} + + +} // vmime |