query_params.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2005 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_QUERY_PARAMS_H
31 #define TNT_QUERY_PARAMS_H
32 
33 #include <cxxtools/query_params.h>
34 #include <tnt/scope.h>
35 #include <locale>
36 #include <stdexcept>
37 #include <sstream>
38 #include <vector>
39 
40 namespace tnt
41 {
42  class QueryParams;
43 
44  class ConversionError : public std::runtime_error
45  {
46  public:
47  explicit ConversionError(const std::string& msg)
48  : std::runtime_error(msg)
49  { }
50 
51  static void doThrow(const std::string& argname, unsigned argnum, const char* typeto, const std::string& value);
52  };
53 
55  namespace qhelper
56  {
57  template <typename Type>
58  class QArg
59  {
60  public:
61  static Type arg(const QueryParams& q, const std::string& name, unsigned n, const Type& def);
62  static Type argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName);
63  };
64 
65  template <>
66  class QArg<std::string>
67  {
68  public:
69  static std::string arg(const QueryParams& q, const std::string& name, unsigned n, const std::string& def);
70  static std::string argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName);
71  };
72 
73  template <>
74  class QArg<char>
75  {
76  public:
77  static char arg(const QueryParams& q, const std::string& name, unsigned n, char);
78  static char argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName);
79  };
80 
81  template <>
82  class QArg<bool>
83  {
84  public:
85  static bool arg(const QueryParams& q, const std::string& name, unsigned n, bool);
86  static bool argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName);
87  };
88 
89  template <typename Type>
90  class QAdd
91  {
92  public:
93  static void add(QueryParams& q, const std::string& name, const Type& value);
94  };
95 
96  template <>
97  class QAdd<std::string>
98  {
99  public:
100  static void add(QueryParams& q, const std::string& name, const std::string& value);
101  };
102 
103  template <>
104  class QAdd<char>
105  {
106  public:
107  static void add(QueryParams& q, const std::string& name, char value);
108  };
109 
110  template <>
111  class QAdd<bool>
112  {
113  public:
114  static void add(QueryParams& q, const std::string& name, bool value);
115  };
116 
117  }
119 
122  {
123  Scope* _paramScope;
124  std::locale _locale;
125 
126  public:
129  : _paramScope(0),
130  _locale(std::locale::classic())
131  { }
132 
134  : cxxtools::QueryParams(src),
135  _paramScope(src._paramScope),
136  _locale(src._locale)
137  {
138  if (_paramScope)
139  _paramScope->addRef();
140  }
141 
142  explicit QueryParams(const std::string& url)
143  : cxxtools::QueryParams(url),
144  _paramScope(0),
145  _locale(std::locale::classic())
146  { }
147 
149  {
150  if (this == &src)
151  return *this;
152 
154  if (_paramScope != src._paramScope)
155  {
156  if (_paramScope->release() == 0)
157  delete _paramScope;
158  _paramScope = src._paramScope;
159  if (_paramScope)
160  _paramScope->addRef();
161  }
162  _locale = src._locale;
163  return *this;
164  }
165 
167  {
168  if (_paramScope && _paramScope->release() == 0)
169  delete _paramScope;
170  }
171 
173  {
174  if (!_paramScope)
175  _paramScope = new Scope();
176  return *_paramScope;
177  }
178 
180  const std::locale& locale() const { return _locale; }
181 
183  void locale(const std::locale& loc) { _locale = loc; }
184 
185  template <typename Type>
186  Type arg(const std::string& name, const Type& def = Type()) const
187  { return qhelper::QArg<Type>::arg(*this, name, 0, def); }
188 
189  template <typename Type>
190  Type argt(const std::string& name, const char* typeName = 0) const
191  { return qhelper::QArg<Type>::argt(*this, name, 0, typeName); }
192 
193  template <typename Type>
194  Type argn(const std::string& name, size_type n, const Type& def = Type()) const
195  { return qhelper::QArg<Type>::arg(*this, name, n, def); }
196 
197  template <typename Type>
198  Type argnt(const std::string& name, size_type n, const char* typeName = 0) const
199  { return qhelper::QArg<Type>::argt(*this, name, n, typeName); }
200 
201  template <typename Type>
202  Type argt(const std::string& name, size_type n, const char* typeName = 0) const
203  { return qhelper::QArg<Type>::argt(*this, name, n, typeName); }
204 
205  template <typename Type>
206  Type arg(size_type n, const Type& def = Type()) const
207  { return qhelper::QArg<Type>::arg(*this, std::string(), n, def); }
208 
209  template <typename Type>
210  Type argt(size_type n, const char* typeName = 0) const
211  { return qhelper::QArg<Type>::argt(*this, std::string(), n, typeName); }
212 
213  template <typename Type>
214  typename std::vector<Type> args(const std::string& name, const Type& def = Type()) const
215  {
216  typename std::vector<Type> ret(paramcount(name));
217  for (typename std::vector<Type>::size_type n = 0; n < ret.size(); ++n)
218  ret[n] = qhelper::QArg<Type>::arg(*this, name, n, def);
219  return ret;
220  }
221 
222  template <typename Type>
223  typename std::vector<Type> argst(const std::string& name, const char* typeName) const
224  {
225  typename std::vector<Type> ret(paramcount(name));
226  for (typename std::vector<Type>::size_type n = 0; n < ret.size(); ++n)
227  ret[n] = qhelper::QArg<Type>::argt(*this, name, n, typeName);
228  return ret;
229  }
230 
231  template <typename Type>
232  QueryParams& add(const std::string& name, const Type& value)
233  { qhelper::QAdd<Type>::add(*this, name, value); return *this; }
234 
235  QueryParams& add(const std::string& name, const char* value)
236  {
237  cxxtools::QueryParams::add(name, value);
238  return *this;
239  }
240 
242  {
244  return *this;
245  }
246  };
247 
248  namespace qhelper
249  {
250  template <typename Type>
251  Type QArg<Type>::arg(const QueryParams& q, const std::string& name, unsigned n, const Type& def)
252  {
253  std::string v = q.param(name, n);
254  std::istringstream s(v);
255  s.imbue(q.locale());
256  Type ret;
257  s >> ret;
258  if (!s)
259  return def;
260  return ret;
261  }
262 
263  template <typename Type>
264  Type QArg<Type>::argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName)
265  {
266  std::string v = q.param(name, n);
267  std::istringstream s(v);
268  s.imbue(q.locale());
269  Type ret;
270  s >> ret;
271  if (!s)
272  ConversionError::doThrow(name, n, typeName, v);
273  return ret;
274  }
275 
276  inline std::string QArg<std::string>::arg(const QueryParams& q, const std::string& name, unsigned n, const std::string& def)
277  { return q.param(name, n, def); }
278 
279  inline std::string QArg<std::string>::argt(const QueryParams& q, const std::string& name, unsigned n, const char*)
280  { return q.param(name, n); }
281 
282  inline char QArg<char>::arg(const QueryParams& q, const std::string& name, unsigned n, char def)
283  {
284  std::string v = q.param(name, n);
285  return v.empty() ? def : v[0];
286  }
287 
288  inline char QArg<char>::argt(const QueryParams& q, const std::string& name, unsigned n, const char* typeName)
289  {
290  std::string v = q.param(name, n);
291  if (v.empty())
292  ConversionError::doThrow(name, n, typeName, v);
293  return v[0];
294  }
295 
296  inline bool QArg<bool>::argt(const QueryParams& q, const std::string& name, unsigned n, const char* /* typeName */)
297  {
298  std::string v = q.param(name, n);
299  return !v.empty();
300  }
301 
302  inline bool QArg<bool>::arg(const QueryParams& q, const std::string& name, unsigned n, bool)
303  {
304  std::string v = q.param(name, n);
305  return !v.empty();
306  }
307 
308  template <typename Type>
309  void QAdd<Type>::add(QueryParams& q, const std::string& name, const Type& value)
310  {
311  std::ostringstream s;
312  s.imbue(q.locale());
313  s << value;
314  static_cast<cxxtools::QueryParams&>(q).add(name, s.str());
315  }
316 
317  inline void QAdd<std::string>::add(QueryParams& q, const std::string& name, const std::string& value)
318  { static_cast<cxxtools::QueryParams&>(q).add(name, value); }
319 
320  inline void QAdd<char>::add(QueryParams& q, const std::string& name, char value)
321  { static_cast<cxxtools::QueryParams&>(q).add(name, std::string(1, value)); }
322 
323  inline void QAdd<bool>::add(QueryParams& q, const std::string& name, bool value)
324  { static_cast<cxxtools::QueryParams&>(q).add(name, value ? std::string(1, '1') : std::string()); }
325  }
326 }
327 
328 #endif // TNT_QUERY_PARAMS_H
329