GCS  0.2.3
gu_config.hpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2014 Codership Oy <info@codership.com>
2 
10 #ifndef _gu_config_hpp_
11 #define _gu_config_hpp_
12 
13 #include "gu_string_utils.hpp"
14 #include "gu_exception.hpp"
15 #include "gu_utils.hpp"
16 #include "gu_throw.hpp"
17 #include "gu_logger.hpp"
18 #include <map>
19 
20 #include <climits>
21 
22 namespace gu
23 {
24  class Config;
25 }
26 
27 extern "C" const char* gu_str2ll (const char* str, long long* ll);
28 
30 {
31 public:
32 
33  static const char PARAM_SEP; // parameter separator
34  static const char KEY_VALUE_SEP; // key-value separator
35  static const char ESCAPE; // escape symbol
36 
37  Config ();
38 
39  bool
40  has (const std::string& key) const
41  {
42  return (params_.find(key) != params_.end());
43  }
44 
45  bool
46  is_set (const std::string& key) const
47  {
48  param_map_t::const_iterator const i(params_.find(key));
49 
50  if (i != params_.end())
51  {
52  return i->second.is_set();
53  }
54  else
55  {
56  throw NotFound();
57  }
58  }
59 
60  /* adds parameter to the known parameter list */
61  void
62  add (const std::string& key)
63  {
64  if (!has(key)) { params_[key] = Parameter(); }
65  }
66 
67  /* adds parameter to the known parameter list and sets its value */
68  void
69  add (const std::string& key, const std::string& value)
70  {
71  if (!has(key)) { params_[key] = Parameter(value); }
72  }
73 
74  /* sets a known parameter to some value, otherwise throws NotFound */
75  void
76  set (const std::string& key, const std::string& value)
77  {
78  param_map_t::iterator const i(params_.find(key));
79 
80  if (i != params_.end())
81  {
82  i->second.set(value);
83  }
84  else
85  {
86 #ifndef NDEBUG
87  log_error << key << " not recognized.";
88 #endif
89  throw NotFound();
90  }
91  }
92 
93  void
94  set (const std::string& key, const char* value)
95  {
96  set(key, std::string(value));
97  }
98 
99  /* Parse a string of semicolumn separated key=value pairs into a vector.
100  * Throws Exception in case of parsing error. */
101  static void
102  parse (std::vector<std::pair<std::string, std::string> >& params_vector,
103  const std::string& params_string);
104 
105  /* Parse a string of semicolumn separated key=value pairs and
106  * set the values.
107  * Throws NotFound if key was not explicitly added before. */
108  void
109  parse (const std::string& params_string);
110 
111  /* General template for integer types */
112  template <typename T> void
113  set (const std::string& key, T val)
114  {
115  set_longlong (key, val);
116  }
117 
119  const std::string&
120  get (const std::string& key) const
121  {
122  param_map_t::const_iterator const i(params_.find(key));
123  if (i == params_.end()) throw NotFound();
124  if (i->second.is_set()) return i->second.value();
125  log_debug << key << " not set.";
126  throw NotSet();
127  }
128 
129  const std::string&
130  get (const std::string& key, const std::string& def) const
131  {
132  try { return get(key); }
133  catch (NotSet&) { return def ; }
134  }
135 
137  template <typename T> inline T
138  get (const std::string& key) const
139  {
140  return from_config <T> (get(key));
141  }
142 
143  template <typename T> inline T
144  get(const std::string& key, const T& def) const
145  {
146  try { return get<T>(key); }
147  catch (NotSet&) { return def; }
148  }
149 
150  void print (std::ostream& os, bool include_not_set = false) const;
153  template <typename T> static inline T
154  from_config (const std::string& value)
155  {
156  const char* str = value.c_str();
157  long long ret;
158  const char* endptr = gu_str2ll (str, &ret);
159 
160  check_conversion (str, endptr, "integer");
161 
162  switch (sizeof(T))
163  {
164  case 1: return overflow_char (ret);
165  case 2: return overflow_short (ret);
166  case 4: return overflow_int (ret);
167  default: return ret;
168  }
169  }
170 
171  /* iterator stuff */
172 
173  class Parameter
174  {
175  public:
176 
177  explicit
178  Parameter(const std::string& value) : value_(value), set_(true) {}
179  Parameter() : value_(), set_(false) {}
180 
181  const std::string& value() const { return value_; }
182  bool is_set() const { return set_ ; }
183 
184  void set(const std::string& value)
185  {
186  value_ = value;
187  set_ = true;
188  }
189 
190  private:
191 
192  std::string value_;
193  bool set_;
194  };
195 
196  typedef std::map <std::string, Parameter> param_map_t;
197  typedef param_map_t::const_iterator const_iterator;
198 
199  const_iterator begin() const { return params_.begin(); }
200  const_iterator end() const { return params_.end(); }
201 
202 private:
203 
204  static void
205  check_conversion (const char* ptr, const char* endptr, const char* type);
206 
207  static char
208  overflow_char(long long ret);
209 
210  static short
211  overflow_short(long long ret);
212 
213  static int
214  overflow_int(long long ret);
215 
216  void set_longlong (const std::string& key, long long value);
217 
218  param_map_t params_;
219 };
220 
221 
222 extern "C" const char* gu_str2dbl (const char* str, double* dbl);
223 extern "C" const char* gu_str2bool (const char* str, bool* bl);
224 extern "C" const char* gu_str2ptr (const char* str, void** ptr);
225 
226 namespace gu
227 {
228  std::ostream& operator<<(std::ostream&, const gu::Config&);
229 
232  template <> inline double
233  Config::from_config (const std::string& value)
234  {
235  const char* str = value.c_str();
236  double ret;
237  const char* endptr = gu_str2dbl (str, &ret);
238 
239  check_conversion (str, endptr, "double");
240 
241  return ret;
242  }
243 
244  template <> inline bool
245  Config::from_config (const std::string& value)
246  {
247  const char* str = value.c_str();
248  bool ret;
249  const char* endptr = gu_str2bool (str, &ret);
250 
251  check_conversion (str, endptr, "boolean");
252 
253  return ret;
254  }
255 
256  template <> inline void*
257  Config::from_config (const std::string& value)
258  {
259  const char* str = value.c_str();
260  void* ret;
261  const char* endptr = gu_str2ptr (str, &ret);
262 
263  check_conversion (str, endptr, "pointer");
264 
265  return ret;
266  }
267 
268  template <> inline void
269  Config::set (const std::string& key, const void* value)
270  {
271  set (key, to_string<const void*>(value));
272  }
273 
274  template <> inline void
275  Config::set (const std::string& key, double val)
276  {
277  set (key, to_string<double>(val));
278  }
279 
280  template <> inline void
281  Config::set (const std::string& key, bool val)
282  {
283  const char* val_str(val ? "YES" : "NO"); // YES/NO is most generic
284  set (key, val_str);
285  }
286 }
287 #endif /* _gu_config_hpp_ */
288 
Definition: gu_config.hpp:173
static T from_config(const std::string &value)
Definition: gu_config.hpp:154
std::string to_string< double >(const double &x, std::ios_base &(*f)(std::ios_base &))
Definition: gu_utils.hpp:48
Definition: gu_exception.hpp:17
Definition: gu_exception.hpp:16
Definition: gu_config.hpp:29