// // VMime library (http://vmime.sourceforge.net) // Copyright (C) 2002-2004 Vincent Richard // // 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. // #ifndef VMIME_PROPERTY_HPP_INCLUDED #define VMIME_PROPERTY_HPP_INCLUDED #include #include #include #include #include "base.hpp" #include "exception.hpp" #include "utility/stringUtils.hpp" namespace vmime { /** Manage a list of (name,value) pairs. */ class propertySet { protected: class property { 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; /** 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); /** Set the value of the property as a generic type. * * @param value new value for property */ template void setValue(const TYPE& value); /** 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 const TYPE getValue() const; private: const string m_name; string m_value; }; class propertyProxy { public: propertyProxy(const string& name, propertySet* set) : m_name(name), m_set(set) { } template propertyProxy& operator=(const TYPE& value) { m_set->setProperty(m_name, value); return (*this); } template void setValue(const TYPE& value) { m_set->setProperty(m_name, value); } template const TYPE getValue() const { return (m_set->getProperty (m_name)); } operator string() const { return (m_set->getProperty (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 const TYPE getValue() const { return (m_set->getProperty (m_name)); } operator string() const { return (m_set->getProperty (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 */ const 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 const TYPE getProperty(const string& name) const { const property* const prop = find(name); if (!prop) throw exceptions::no_such_property(name); return (prop->getValue ()); } /** 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 const TYPE getProperty(const string& name, const TYPE defaultValue) const { const property* const prop = find(name); return (prop ? prop->getValue () : 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 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 { public: propFinder(const string& name) : m_name(stringUtils::toLower(name)) { } const bool operator()(property* const p) const { return (stringUtils::toLower(p->getName()) == m_name); } private: const std::string m_name; }; property* find(const string& name) const; property* findOrCreate(const string& name); typedef std::list list_type; list_type m_props; public: /** Return the property list. * * @return list of properties */ const std::vector getPropertyList() const; /** Return the property list. * * @return list of properties */ const std::vector getPropertyList(); }; template void propertySet::property::setValue(const TYPE& value) { std::ostringstream oss; oss << value; m_value = oss.str(); } template const TYPE propertySet::property::getValue() const { TYPE val = TYPE(); std::istringstream iss(m_value); iss >> val; if (iss.fail()) throw exceptions::invalid_property_type(); return (val); } template <> void propertySet::property::setValue(const string& value); template <> void propertySet::property::setValue(const bool& value); template <> const string propertySet::property::getValue() const; template <> const bool propertySet::property::getValue() const; } // vmime #endif // VMIME_PROPERTY_HPP_INCLUDED