aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/src/vmime/relay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vmime-master/src/vmime/relay.cpp')
-rw-r--r--vmime-master/src/vmime/relay.cpp363
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