diff options
Diffstat (limited to 'vmime-master/src/vmime/propertySet.hpp')
-rw-r--r-- | vmime-master/src/vmime/propertySet.hpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/propertySet.hpp b/vmime-master/src/vmime/propertySet.hpp new file mode 100644 index 0000000..20eb9de --- /dev/null +++ b/vmime-master/src/vmime/propertySet.hpp @@ -0,0 +1,461 @@ +// +// 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. +// + +#ifndef VMIME_PROPERTY_HPP_INCLUDED +#define VMIME_PROPERTY_HPP_INCLUDED + +#include <list> +#include <functional> +#include <algorithm> +#include <sstream> + +#include "vmime/base.hpp" +#include "vmime/exception.hpp" + +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { + + +/** Manage a list of (name,value) pairs. + */ +class VMIME_EXPORT propertySet : public object { + +public: + + /** A property holds a (name,value) pair. + */ + class property : public object { + + public: + + property(const string& name, const string& value); + property(const string& name); + property(const property& prop); + + /** Return the name of the property. + * + * @return property name + */ + const string& getName() const; + +#ifndef _MSC_VER + + // Visual Studio errors on linking with these 2 functions, + // whereas GCC and CLang need them. + + /** Return the value of the property as a string. + * + * @return current value of the property + */ + const string& getValue() const; + + /** Set the value of the property as a string. + * + * @param value new value for property + */ + void setValue(const string& value); + +#endif // !_MSC_VER + + /** Set the value of the property as a generic type. + * + * @param value new value for property + */ + template <class TYPE> void setValue(const TYPE& value) { + + std::ostringstream oss; + oss.imbue(std::locale::classic()); // no formatting + + oss << value; + + m_value = oss.str(); + } + + /** Get the value of the property as a generic type. + * + * @throw exceptions::invalid_property_type if the specified + * type is incompatible with the string value (cannot be + * converted using std::istringstream) + * @return current value of the property + */ + template <class TYPE> TYPE getValue() const { + + TYPE val = TYPE(); + + std::istringstream iss(m_value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + if (iss.fail()) { + throw exceptions::invalid_property_type(); + } + + return (val); + } + + +#ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION + + template <> + void propertySet::property::setValue(const string& value) { + + m_value = value; + } + + template <> + void propertySet::property::setValue(const bool& value) { + + m_value = value ? "true" : "false"; + } + + template <> + string propertySet::property::getValue() const { + + return (m_value); + } + + template <> + bool propertySet::property::getValue() const { + + if (utility::stringUtils::toLower(m_value) == "true") { + + return true; + + } else { + + int val = 0; + + std::istringstream iss(m_value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + return !iss.fail() && val != 0; + } + } + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + private: + + const string m_name; + string m_value; + }; + +protected: + + class propertyProxy { + + public: + + propertyProxy(const string& name, propertySet* set) + : m_name(name), + m_set(set) { + + } + + template <class TYPE> + propertyProxy& operator=(const TYPE& value) { + + m_set->setProperty(m_name, value); + return *this; + } + + template <class TYPE> + void setValue(const TYPE& value) { + + m_set->setProperty(m_name, value); + } + + template <class TYPE> + const TYPE getValue() const { + + return m_set->getProperty <TYPE>(m_name); + } + + operator string() const { + + return m_set->getProperty <string>(m_name); + } + + private: + + const string m_name; + propertySet* m_set; + }; + + class constPropertyProxy { + + public: + + constPropertyProxy(const string& name, const propertySet* set) + : m_name(name), + m_set(set) { + + } + + template <class TYPE> + const TYPE getValue() const { + + return m_set->getProperty <TYPE>(m_name); + } + + operator string() const { + + return m_set->getProperty <string>(m_name); + } + + private: + + const string m_name; + const propertySet* m_set; + }; + +public: + + propertySet(); + propertySet(const string& props); + propertySet(const propertySet& set); + + ~propertySet(); + + propertySet& operator=(const propertySet& set); + + /** Parse a string and extract one or more properties. + * The string format is: name[=value](;name[=value])*. + * + * @param props string representing a list of properties + */ + void setFromString(const string& props); + + /** Remove all properties from the list. + */ + void removeAllProperties(); + + /** Remove the specified property. + * + * @param name name of the property to remove + */ + void removeProperty(const string& name); + + /** Test whether the specified property is set. + * + * @param name name of the property to test + * @return true if the property is set (has a value), + * false otherwise + */ + bool hasProperty(const string& name) const; + + /** Get the value of the specified property. + * + * @throw exceptions::no_such_property if the property does not exist + * @param name property name + * @return value of the specified property + */ + template <class TYPE> + const TYPE getProperty(const string& name) const { + + const shared_ptr <property> prop = find(name); + if (!prop) throw exceptions::no_such_property(name); + + return (prop->template getValue <TYPE>()); + } + + /** Get the value of the specified property. + * A default value can be returned if the property is not set. + * + * @param name property name + * @param defaultValue value to return if the specified property + * does not exist + * @return value of the specified property or default value + * if if does not exist + */ + template <class TYPE> + const TYPE getProperty(const string& name, const TYPE defaultValue) const { + + const shared_ptr <property> prop = find(name); + return prop ? prop->template getValue <TYPE>() : defaultValue; + } + + /** Change the value of the specified property or create + * a new property set to the specified a value. + * + * @param name property name + * @param value property value + */ + template <class TYPE> + void setProperty(const string& name, const TYPE& value) { + findOrCreate(name)->setValue(value); + } + + /** Return a proxy object to access the specified property + * suitable for reading or writing. If the property does not + * exist and the value is changed, a new property will + * be created. + * + * @param name property name + * @return proxy object for the specified property + */ + propertyProxy operator[](const string& name); + + /** Return a proxy object to access the specified property + * suitable for reading only. + * + * @throw exceptions::no_such_property if the property does not exist + * @return read-only proxy object for the specified property + */ + const constPropertyProxy operator[](const string& name) const; + +private: + + void parse(const string& props); + + + class propFinder : public std::unary_function <shared_ptr <property>, bool> { + + public: + + propFinder(const string& name) : m_name(utility::stringUtils::toLower(name)) { } + + bool operator()(const shared_ptr <property>& p) const { + + return (utility::stringUtils::toLower(p->getName()) == m_name); + } + + private: + + const string m_name; + }; + + shared_ptr <property> find(const string& name) const; + shared_ptr <property> findOrCreate(const string& name); + + typedef std::list <shared_ptr <property> > list_type; + list_type m_props; + +public: + + template <typename TYPE> + static TYPE valueFromString(const string& value) { + + TYPE v = TYPE(); + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> v; + + return v; + } + + template <typename TYPE> + static string valueToString(const TYPE& value) { + + std::ostringstream oss(value); + oss.imbue(std::locale::classic()); // no formatting + + oss << value; + + return oss.str(); + } + +#ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION + + template <> + static string valueFromString(const string& value) { + + return value; + } + + template <> + static string valueToString(const string& value) { + + return value; + } + + template <> + static bool valueFromString(const string& value) { + + if (utility::stringUtils::toLower(value) == "true") { + + return true; + + } else { + + int val = 0; + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + return !iss.fail() && val != 0; + } + } + + template <> + static string valueToString(const bool& value) { + + return value ? "true" : "false"; + } + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + /** Return the property list. + * + * @return list of properties + */ + const std::vector <shared_ptr <const property> > getPropertyList() const; + + /** Return the property list. + * + * @return list of properties + */ + const std::vector <shared_ptr <property> > getPropertyList(); +}; + + +#ifndef VMIME_INLINE_TEMPLATE_SPECIALIZATION + +template <> VMIME_EXPORT void propertySet::property::setValue <string>(const string& value); +template <> VMIME_EXPORT void propertySet::property::setValue(const bool& value); + +template <> VMIME_EXPORT string propertySet::property::getValue() const; +template <> VMIME_EXPORT bool propertySet::property::getValue() const; + +template <> VMIME_EXPORT string propertySet::valueFromString(const string& value); +template <> VMIME_EXPORT string propertySet::valueToString(const string& value); + +template <> VMIME_EXPORT bool propertySet::valueFromString(const string& value); +template <> VMIME_EXPORT string propertySet::valueToString(const bool& value); + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + +} // vmime + + +#endif // VMIME_PROPERTY_HPP_INCLUDED |