aboutsummaryrefslogtreecommitdiffstats
path: root/src/propertySet.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/propertySet.hpp')
-rw-r--r--src/propertySet.hpp340
1 files changed, 340 insertions, 0 deletions
diff --git a/src/propertySet.hpp b/src/propertySet.hpp
new file mode 100644
index 00000000..eb0ee7d7
--- /dev/null
+++ b/src/propertySet.hpp
@@ -0,0 +1,340 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 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.
+//
+
+#ifndef VMIME_PROPERTY_HPP_INCLUDED
+#define VMIME_PROPERTY_HPP_INCLUDED
+
+
+#include <list>
+#include <functional>
+#include <algorithm>
+#include <sstream>
+
+#include "base.hpp"
+#include "exception.hpp"
+
+
+namespace vmime
+{
+
+
+class propertySet
+{
+private:
+
+ class property
+ {
+ public:
+
+ property(const string& name, const string& value) : m_name(name), m_value(value) { }
+ property(const string& name) : m_name(name) { }
+ property(const property& prop) : m_name(prop.m_name), m_value(prop.m_value) { }
+
+ const string& name() const { return (m_name); }
+ const string& value() const { return (m_value); }
+
+ template <class TYPE> void set(const TYPE& value);
+ template <class TYPE> const TYPE get() const;
+
+ private:
+
+ string m_name;
+ string m_value;
+ };
+
+
+ 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->set(m_name, value);
+ return (*this);
+ }
+
+ template <class TYPE>
+ void set(const TYPE& value)
+ {
+ m_set->set(m_name, value);
+ }
+
+ template <class TYPE>
+ const TYPE get() const
+ {
+ return (m_set->get <TYPE>(m_name));
+ }
+
+ operator string() const
+ {
+ return (m_set->get <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 get() const
+ {
+ return (m_set->get <TYPE>(m_name));
+ }
+
+ operator string() const
+ {
+ return (m_set->get <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);
+
+ void set(const string& props);
+
+ void empty();
+
+ void clear(const string& name);
+
+
+ const bool exists(const string& name) const
+ {
+ return (find(name) != NULL);
+ }
+
+ template <class TYPE>
+ const TYPE get(const string& name) const
+ {
+ const property* const prop = find(name);
+ if (!prop) throw exceptions::no_such_property(name);
+
+ return (prop->get <TYPE>());
+ }
+
+ template <class TYPE>
+ const TYPE get(const string& name, const TYPE defaultValue) const
+ {
+ const property* const prop = find(name);
+ return (prop ? prop->get <TYPE>() : defaultValue);
+ }
+
+ template <class TYPE>
+ void set(const string& name, const TYPE& value)
+ {
+ findOrCreate(name)->set(value);
+ }
+
+ propertyProxy operator[](const string& name)
+ {
+ return (propertyProxy(name, this));
+ }
+
+ const constPropertyProxy operator[](const string& name) const
+ {
+ return (constPropertyProxy(name, this));
+ }
+
+private:
+
+ void parse(const string& props);
+
+
+ class propFinder : public std::unary_function <property*, bool>
+ {
+ public:
+
+ propFinder(const string& name) : m_name(toLower(name)) { }
+
+ const bool operator()(property* const p) const
+ {
+ return (toLower(p->name()) == m_name);
+ }
+
+ private:
+
+ const std::string m_name;
+ };
+
+ property* find(const string& name) const
+ {
+ std::list <property*>::const_iterator it = std::find_if
+ (m_props.begin(), m_props.end(), propFinder(name));
+
+ return (it != m_props.end() ? *it : NULL);
+ }
+
+ property* findOrCreate(const string& name)
+ {
+ std::list <property*>::const_iterator it = std::find_if
+ (m_props.begin(), m_props.end(), propFinder(name));
+
+ if (it != m_props.end())
+ {
+ return (*it);
+ }
+ else
+ {
+ property* prop = new property(name, "");
+ m_props.push_back(prop);
+ return (prop);
+ }
+ }
+
+ typedef std::list <property*> list_type;
+ list_type m_props;
+
+public:
+
+ class iterator;
+
+ class const_iterator
+ {
+ friend class propertySet;
+
+ public:
+
+ const_iterator() { }
+ const_iterator(const const_iterator& it) : m_it(it.m_it) { }
+ const_iterator(const iterator& it) : m_it(it.m_it) { }
+
+ const_iterator& operator=(const const_iterator& it) { m_it = it.m_it; return (*this); }
+
+ const property& operator*() const { return (**m_it); }
+ const property* operator->() const { return (*m_it); }
+
+ const_iterator& operator++() { ++m_it; return (*this); }
+ const_iterator operator++(int) { return (m_it++); }
+
+ const_iterator& operator--() { --m_it; return (*this); }
+ const_iterator operator--(int) { return (m_it--); }
+
+ const bool operator==(const const_iterator& it) const { return (m_it == it.m_it); }
+ const bool operator!=(const const_iterator& it) const { return (m_it != it.m_it); }
+
+ private:
+
+ const_iterator(const list_type::const_iterator it) : m_it(it) { }
+
+ list_type::const_iterator m_it;
+ };
+
+ class iterator
+ {
+ friend class propertySet;
+ friend class propertySet::const_iterator;
+
+ public:
+
+ iterator() { }
+ iterator(const iterator& it) : m_it(it.m_it) { }
+
+ iterator& operator=(const iterator& it) { m_it = it.m_it; return (*this); }
+
+ property& operator*() const { return (**m_it); }
+ property* operator->() const { return (*m_it); }
+
+ iterator& operator++() { ++m_it; return (*this); }
+ iterator operator++(int) { return (m_it++); }
+
+ iterator& operator--() { --m_it; return (*this); }
+ iterator operator--(int) { return (m_it--); }
+
+ const bool operator==(const iterator& it) const { return (m_it == it.m_it); }
+ const bool operator!=(const iterator& it) const { return (m_it != it.m_it); }
+
+ private:
+
+ iterator(const list_type::iterator it) : m_it(it) { }
+
+ list_type::iterator m_it;
+ };
+
+ iterator begin() { return iterator(m_props.begin()); }
+ iterator end() { return iterator(m_props.end()); }
+
+ const_iterator begin() const { return const_iterator(m_props.begin()); }
+ const_iterator end() const { return const_iterator(m_props.end()); }
+};
+
+
+
+template <class TYPE>
+void propertySet::property::set(const TYPE& value)
+{
+ std::ostringstream oss;
+ oss << value;
+
+ m_value = oss.str();
+}
+
+
+template <class TYPE>
+const TYPE propertySet::property::get() 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::set(const string& value);
+template <> void propertySet::property::set(const bool& value);
+
+template <> const string propertySet::property::get() const;
+template <> const bool propertySet::property::get() const;
+
+
+} // vmime
+
+
+#endif // VMIME_PROPERTY_HPP_INCLUDED