aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/constants.cpp44
-rw-r--r--src/disposition.cpp314
-rw-r--r--src/headerFieldFactory.cpp3
3 files changed, 361 insertions, 0 deletions
diff --git a/src/constants.cpp b/src/constants.cpp
index 55de71fb..d4feec9f 100644
--- a/src/constants.cpp
+++ b/src/constants.cpp
@@ -176,6 +176,50 @@ namespace fields
const string::value_type* const X_MAILER = "X-Mailer";
const string::value_type* const X_PRIORITY = "X-Priority";
+
+ // RFC-3798: Message Disposition
+ const string::value_type* const ORIGINAL_MESSAGE_ID = "Original-Message-ID";
+ const string::value_type* const DISPOSITION_NOTIFICATION_TO = "Disposition-Notification-To";
+ const string::value_type* const DISPOSITION_NOTIFICATION_OPTIONS = "Disposition-Notification-Options";
+ const string::value_type* const DISPOSITION = "Disposition";
+ const string::value_type* const FAILURE = "Failure";
+ const string::value_type* const ERROR = "Error";
+ const string::value_type* const WARNING = "Warning";
+ const string::value_type* const ORIGINAL_RECIPIENT = "Original-Recipient";
+ const string::value_type* const FINAL_RECIPIENT = "Final-Recipient";
+ const string::value_type* const REPORTING_UA = "Reporting-UA";
+ const string::value_type* const MDN_GATEWAY = "MDN-Gateway";
+}
+
+
+// Constants for disposition action modes (RFC-3978).
+namespace dispositionActionModes
+{
+ const string::value_type* const MANUAL = "manual";
+ const string::value_type* const AUTOMATIC = "automatic";
+}
+
+
+// Constants for disposition sending modes (RFC-3798).
+namespace dispositionSendingModes
+{
+ const string::value_type* const SENT_MANUALLY = "MDN-sent-manually";
+ const string::value_type* const SENT_AUTOMATICALLY ="MDN-sent-automatically";
+}
+
+
+// Constants for disposition types (RFC-3798).
+namespace dispositionTypes
+{
+ const string::value_type* const DISPLAYED = "displayed";
+ const string::value_type* const DELETED = "deleted";
+}
+
+
+// Constants for disposition modifiers (RFC-3798).
+namespace dispositionModifiers
+{
+ const string::value_type* const ERROR = "error";
}
diff --git a/src/disposition.cpp b/src/disposition.cpp
new file mode 100644
index 00000000..b894f85e
--- /dev/null
+++ b/src/disposition.cpp
@@ -0,0 +1,314 @@
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "vmime/disposition.hpp"
+
+#include "vmime/parserHelpers.hpp"
+#include "vmime/utility/stringUtils.hpp"
+
+
+namespace vmime
+{
+
+
+disposition::disposition()
+{
+}
+
+
+disposition::disposition(const string& actionMode, const string& sendingMode,
+ const string& type, const string& modifier)
+ : m_actionMode(actionMode), m_sendingMode(sendingMode), m_type(type)
+{
+ m_modifiers.push_back(modifier);
+}
+
+
+disposition* disposition::clone() const
+{
+ disposition* disp = new disposition;
+
+ disp->m_actionMode = m_actionMode;
+ disp->m_sendingMode = m_sendingMode;
+ disp->m_type = m_type;
+ disp->m_modifiers.resize(m_modifiers.size());
+
+ std::copy(m_modifiers.begin(), m_modifiers.end(), disp->m_modifiers.begin());
+
+ return (disp);
+}
+
+
+void disposition::copyFrom(const component& other)
+{
+ const disposition& disp = dynamic_cast <const disposition&>(other);
+
+ m_actionMode = disp.m_actionMode;
+ m_sendingMode = disp.m_sendingMode;
+ m_type = disp.m_type;
+ m_modifiers.resize(disp.m_modifiers.size());
+
+ std::copy(disp.m_modifiers.begin(), disp.m_modifiers.end(), m_modifiers.begin());
+}
+
+
+disposition& disposition::operator=(const disposition& other)
+{
+ copyFrom(other);
+ return (*this);
+}
+
+
+const std::vector <const component*> disposition::getChildComponents() const
+{
+ return std::vector <const component*>();
+}
+
+
+void disposition::setActionMode(const string& mode)
+{
+ m_actionMode = mode;
+}
+
+
+const string& disposition::getActionMode() const
+{
+ return (m_actionMode);
+}
+
+
+void disposition::setSendingMode(const string& mode)
+{
+ m_sendingMode = mode;
+}
+
+
+const string& disposition::getSendingMode() const
+{
+ return (m_sendingMode);
+}
+
+
+void disposition::setType(const string& type)
+{
+ m_type = type;
+}
+
+
+const string& disposition::getType() const
+{
+ return (m_type);
+}
+
+
+void disposition::addModifier(const string& modifier)
+{
+ if (!hasModifier(modifier))
+ m_modifiers.push_back(utility::stringUtils::toLower(modifier));
+}
+
+
+void disposition::removeModifier(const string& modifier)
+{
+ const string modifierLC = utility::stringUtils::toLower(modifier);
+
+ for (std::vector <string>::iterator it = m_modifiers.begin() ;
+ it != m_modifiers.end() ; ++it)
+ {
+ if (*it == modifierLC)
+ {
+ m_modifiers.erase(it);
+ break;
+ }
+ }
+}
+
+
+void disposition::removeAllModifiers()
+{
+ m_modifiers.clear();
+}
+
+
+const bool disposition::hasModifier(const string& modifier) const
+{
+ const string modifierLC = utility::stringUtils::toLower(modifier);
+
+ for (std::vector <string>::const_iterator it = m_modifiers.begin() ;
+ it != m_modifiers.end() ; ++it)
+ {
+ if (*it == modifierLC)
+ return (true);
+ }
+
+ return (false);
+}
+
+
+const std::vector <string> disposition::getModifierList() const
+{
+ return (m_modifiers);
+}
+
+
+void disposition::parse(const string& buffer, const string::size_type position,
+ const string::size_type end, string::size_type* newPosition)
+{
+ // disposition-mode ";" disposition-type
+ // [ "/" disposition-modifier *( "," disposition-modifier ) ]
+ //
+ // disposition-mode = action-mode "/" sending-mode
+
+ string::size_type pos = position;
+
+ while (pos < end && parserHelpers::isSpace(buffer[pos]))
+ ++pos;
+
+ // -- disposition-mode
+ const string::size_type modeStart = pos;
+ string::size_type modeEnd = pos;
+
+ while (pos < end && buffer[pos] != ';')
+ {
+ ++modeEnd;
+ ++pos;
+ }
+
+ while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1]))
+ --modeEnd;
+
+ const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd);
+ const string::size_type slash = mode.find('/');
+
+ if (slash != string::npos)
+ {
+ m_actionMode = string(mode.begin(), mode.begin() + slash);
+ m_sendingMode = string(mode.begin() + slash + 1, mode.end());
+ }
+ else
+ {
+ m_actionMode = mode;
+ m_sendingMode.clear();
+ }
+
+ if (pos < end)
+ {
+ // Skip ';'
+ ++pos;
+ }
+
+ while (pos < end && parserHelpers::isSpace(buffer[pos]))
+ ++pos;
+
+ // -- disposition-type
+ const string::size_type typeStart = pos;
+ string::size_type typeEnd = pos;
+
+ while (pos < end && buffer[pos] != '/')
+ {
+ ++typeEnd;
+ ++pos;
+ }
+
+ while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1]))
+ --typeEnd;
+
+ m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd);
+
+ m_modifiers.clear();
+
+ if (pos < end) // modifiers follow
+ {
+ // Skip '/'
+ ++pos;
+
+ while (pos < end)
+ {
+ while (pos < end && parserHelpers::isSpace(buffer[pos]))
+ ++pos;
+
+ const string::size_type modifierStart = pos;
+ string::size_type modifierEnd = pos;
+
+ while (pos < end && buffer[pos] != ',')
+ {
+ ++modifierEnd;
+ ++pos;
+ }
+
+ while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1]))
+ --modifierEnd;
+
+ if (modifierEnd > modifierStart)
+ {
+ m_modifiers.push_back(string(buffer.begin() + modifierStart,
+ buffer.begin() + modifierEnd));
+ }
+
+ // Skip ','
+ if (pos < end)
+ ++pos;
+ }
+ }
+
+ if (newPosition)
+ *newPosition = pos;
+}
+
+
+void disposition::generate(utility::outputStream& os, const string::size_type maxLineLength,
+ const string::size_type curLinePos, string::size_type* newLinePos) const
+{
+ string::size_type pos = curLinePos;
+
+ const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode);
+ const string sendingMode = (m_sendingMode.empty() ? "MDN-sent-automatically" : m_sendingMode);
+
+ os << actionMode << "/" << sendingMode << ";";
+ pos += actionMode.length() + 1 + sendingMode.length() + 1;
+
+ if (pos > maxLineLength)
+ {
+ os << NEW_LINE_SEQUENCE;
+ pos = NEW_LINE_SEQUENCE_LENGTH;
+ }
+
+ const string type = (m_type.empty() ? "displayed" : m_type);
+
+ os << type;
+ pos += type.length();
+
+ if (m_modifiers.size() >= 1)
+ {
+ os << "/" << m_modifiers[0];
+ pos += 1 + m_modifiers[0].length();
+
+ for (std::vector <string>::size_type i = 1 ; i < m_modifiers.size() ; ++i)
+ {
+ os << "," << m_modifiers[i];
+ pos += 1 + m_modifiers[i].length();
+ }
+ }
+
+ if (newLinePos)
+ *newLinePos = pos;
+}
+
+
+}
diff --git a/src/headerFieldFactory.cpp b/src/headerFieldFactory.cpp
index 93e1b7fe..544a2ac2 100644
--- a/src/headerFieldFactory.cpp
+++ b/src/headerFieldFactory.cpp
@@ -56,6 +56,9 @@ headerFieldFactory::headerFieldFactory()
registerName <messageIdField>(vmime::fields::MESSAGE_ID);
registerName <defaultField>(vmime::fields::CONTENT_LOCATION);
registerName <messageIdField>(vmime::fields::IN_REPLY_TO);
+
+ registerName <messageIdField>(vmime::fields::ORIGINAL_MESSAGE_ID);
+ registerName <mailboxListField>(vmime::fields::DISPOSITION_NOTIFICATION_TO);
}