00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef PEEKABOT_CONFIG_HH_INCLUDED
00023 #define PEEKABOT_CONFIG_HH_INCLUDED
00024
00025
00026 #include <string>
00027 #include <istream>
00028 #include <ostream>
00029 #include <boost/utility.hpp>
00030 #include <boost/thread/recursive_mutex.hpp>
00031
00032 #include "AnyMap.hh"
00033 #include "LexicalMap.hh"
00034
00035
00036 namespace peekabot
00037 {
00038 class Config : public boost::noncopyable
00039 {
00040 public:
00041 Config();
00042
00043 ~Config();
00044
00045 template<class T>
00046 T get(const std::string &key) const
00047 {
00048 boost::recursive_mutex::scoped_lock lock(m_mutex);
00049
00050 if( m_generated.count(key) )
00051 return m_generated.get<T>(key);
00052 else if( m_overrides.count(key) )
00053 return m_overrides.get<T>(key);
00054 else if( m_persistent.count(key) )
00055 return m_persistent.get<T>(key);
00056 else if( m_defaults.count(key) )
00057 return m_defaults.get<T>(key);
00058 else
00059 throw std::runtime_error("Key '" + key + "' not found");
00060 }
00061
00062
00063 template<class T>
00064 T get(const std::string &key, const T &default_val) const
00065 {
00066 boost::recursive_mutex::scoped_lock lock(m_mutex);
00067
00068 if( m_generated.count(key) )
00069 return m_generated.get<T>(key);
00070 else if( m_overrides.count(key) )
00071 return m_overrides.get<T>(key);
00072 else if( m_persistent.count(key) )
00073 return m_persistent.get<T>(key);
00074 else if( m_defaults.count(key) )
00075 return m_defaults.get<T>(key);
00076 else
00077 return default_val;
00078 }
00079
00080
00081 template<class T>
00082 T get_non_generated(const std::string &key) const
00083 {
00084 boost::recursive_mutex::scoped_lock lock(m_mutex);
00085
00086 if( m_overrides.count(key) )
00087 return m_overrides.get<T>(key);
00088 else if( m_persistent.count(key) )
00089 return m_persistent.get<T>(key);
00090 else if( m_defaults.count(key) )
00091 return m_defaults.get<T>(key);
00092 else
00093 throw std::runtime_error("Key '" + key + "' not found");
00094 }
00095
00096
00097 template<class T>
00098 T get_non_generated(const std::string &key, const T &default_val) const
00099 {
00100 boost::recursive_mutex::scoped_lock lock(m_mutex);
00101
00102 if( m_overrides.count(key) )
00103 return m_overrides.get<T>(key);
00104 else if( m_persistent.count(key) )
00105 return m_persistent.get<T>(key);
00106 else if( m_defaults.count(key) )
00107 return m_defaults.get<T>(key);
00108 else
00109 return default_val;
00110 }
00111
00115 template<class T>
00116 inline T get_option(const std::string &key, const T &default_val) const
00117 {
00118 return get<T>(key, default_val);
00119 }
00120
00124 template<class T>
00125 inline T get_option(const std::string &key) const
00126 {
00127 return get<T>(key);
00128 }
00129
00130 template<class T>
00131 void set_persistent(const std::string &key, const T &val)
00132 {
00133 boost::recursive_mutex::scoped_lock lock(m_mutex);
00134 m_persistent.set(key, val);
00135 }
00136
00137 bool has(const std::string &key) const;
00138
00139
00140 template<class T>
00141 bool has_type(const std::string &key) const
00142 {
00143 boost::recursive_mutex::scoped_lock lock(m_mutex);
00144
00145 if( m_generated.count(key) )
00146 return m_generated.has_type<T>(key);
00147 else if( m_overrides.count(key) )
00148 return m_overrides.has_type<T>(key);
00149 else if( m_persistent.count(key) )
00150 return m_persistent.has_type<T>(key);
00151 else if( m_defaults.count(key) )
00152 return m_defaults.has_type<T>(key);
00153 else
00154 return false;
00155 }
00156
00157
00158 void load(const std::string &filename);
00159
00160 void save(const std::string &filename) const;
00161
00162
00163 AnyMap &get_generated();
00164
00165 const AnyMap &get_generated() const;
00166
00167 AnyMap &get_defaults();
00168
00169 const AnyMap &get_defaults() const;
00170
00171 LexicalMap &get_overrides();
00172
00173 const LexicalMap &get_overrides() const;
00174
00175 LexicalMap &get_persistent();
00176
00177 const LexicalMap &get_persistent() const;
00178
00179 private:
00180 void load_ini(LexicalMap &lm, std::istream &is);
00181
00182 void load_ini(LexicalMap &lm, const std::string &filename);
00183
00184 void save_ini(const LexicalMap &lm, std::ostream &os) const;
00185
00186 void save_ini(const LexicalMap &lm, const std::string &filename) const;
00187
00188 private:
00189 mutable boost::recursive_mutex m_mutex;
00190
00191 AnyMap m_generated;
00192 LexicalMap m_overrides;
00193 LexicalMap m_persistent;
00194 AnyMap m_defaults;
00195 };
00196 }
00197
00198
00199 #endif // PEEKABOT_CONFIG_HH_INCLUDED