libiqxmlrpc  0.12.4
 All Classes Namespaces Files Functions Typedefs Enumerations
value_type.h
Go to the documentation of this file.
1 // Libiqxmlrpc - an object-oriented XML-RPC solution.
2 // Copyright (C) 2011 Anton Dedov
3 
5 #ifndef _iqxmlrpc_value_type_h_
6 #define _iqxmlrpc_value_type_h_
7 
8 #include "except.h"
9 #include "util.h"
10 
11 #include <iterator>
12 #include <map>
13 #include <string>
14 #include <time.h>
15 #include <vector>
16 
17 #ifdef _MSC_VER
18 #pragma warning(push)
19 #pragma warning(disable: 4275)
20 #endif
21 
23 namespace iqxmlrpc {
24 
25 class Value;
26 class Value_type_visitor;
27 typedef util::ExplicitPtr<Value*> Value_ptr;
28 
29 template <class T> class Scalar;
30 typedef Scalar<int> Int;
31 typedef Scalar<bool> Bool;
32 typedef Scalar<double> Double;
34 
35 
37 class LIBIQXMLRPC_API Value_type {
38 public:
39  virtual ~Value_type() {}
40 
41  virtual Value_type* clone() const = 0;
42  virtual const std::string& type_name() const = 0;
43  virtual void apply_visitor(Value_type_visitor&) const = 0;
44 };
45 
46 
48 
49 class LIBIQXMLRPC_API Nil: public Value_type {
50  int nope;
51 
52 public:
53  Value_type* clone() const;
54  const std::string& type_name() const;
55  void apply_visitor(Value_type_visitor&) const;
56 };
57 
58 
60 template <class T>
61 class LIBIQXMLRPC_API Scalar: public Value_type {
62 protected:
63  T value_;
64 
65 public:
66  Scalar( const T& t ): value_(t) {}
67  Scalar<T>* clone() const { return new Scalar<T>(value_); }
68 
69  void apply_visitor(Value_type_visitor&) const;
70  const std::string& type_name() const;
71 
72  const T& value() const { return value_; }
73  T& value() { return value_; }
74 };
75 
76 #ifdef _MSC_VER
77 #pragma warning(push)
78 #pragma warning(disable: 4251)
79 #endif
80 
82 class LIBIQXMLRPC_API Array: public Value_type {
83  typedef std::vector<Value*> Val_vector;
84  typedef Val_vector::iterator iterator;
85 
86  class Array_inserter;
87  friend class Array_inserter;
88 
89 public:
90  typedef Value value_type;
91  typedef value_type* pointer;
92  typedef const value_type* const_pointer;
93  typedef value_type& reference;
94  typedef const value_type& const_reference;
95 
96  class const_iterator;
97  friend class Array::const_iterator;
98 
100  class Out_of_range: public Exception {
101  public:
102  Out_of_range():
103  Exception( "Array: index out of range." ) {}
104  };
105 
106 private:
107  Val_vector values;
108 
109 public:
110  Array( const Array& );
111  Array() {}
112  ~Array();
113 
114  Array& operator =( const Array& );
115 
116  void swap(Array&) throw();
117  Array* clone() const;
118  const std::string& type_name() const;
119  void apply_visitor(Value_type_visitor&) const;
120 
121  size_t size() const { return values.size(); }
122 
123  const Value& operator []( unsigned i ) const
124  {
125  try {
126  return (*values.at(i));
127  }
128  catch( const std::out_of_range& )
129  {
130  throw Out_of_range();
131  }
132  }
133 
134  Value& operator []( unsigned i )
135  {
136  try {
137  return (*values.at(i));
138  }
139  catch( const std::out_of_range& )
140  {
141  throw Out_of_range();
142  }
143  }
144 
145  void push_back( const Value& );
146  void push_back( Value_ptr );
147 
148  void clear();
149 
151  template <class In>
152  void assign( In first, In last );
153 
154  Array::const_iterator begin() const;
155  Array::const_iterator end() const;
156 };
157 
158 
160 class LIBIQXMLRPC_API Array::const_iterator:
161  public std::iterator<std::bidirectional_iterator_tag, Value>
162 {
163  Array::Val_vector::const_iterator i;
164 
165 public:
166  const_iterator( Array::Val_vector::const_iterator i_ ):
167  i(i_) {}
168  ~const_iterator() {}
169 
170  const Value& operator *() const { return *(*i); }
171  const Value* operator ->() const { return *i; }
172 
173  const_iterator operator ++( int ) { return const_iterator(i++); }
174  const_iterator operator --( int ) { return const_iterator(i--); }
175 
176  const_iterator& operator ++() { ++i; return *this; }
177  const_iterator& operator --() { --i; return *this; }
178 
179  bool operator ==( const const_iterator& ci ) const
180  {
181  return i == ci.i;
182  }
183 
184  bool operator !=( const const_iterator& ci ) const
185  {
186  return !(*this == ci );
187  }
188 };
189 
190 inline Array::const_iterator Array::begin() const
191 {
192  return values.begin();
193 }
194 
195 
196 inline Array::const_iterator Array::end() const
197 {
198  return values.end();
199 }
200 
201 
203 class LIBIQXMLRPC_API Struct: public Value_type {
204 public:
207  class No_field: public Exception {
208  public:
209  No_field( const std::string& f ):
210  Exception( "Struct: field '" + f + "' not exist." ) {}
211  };
212 
213 private:
214  typedef std::map<std::string, Value*> Value_stor;
215  class Struct_inserter;
216  friend class Struct_inserter;
217 
218  Value_stor values;
219 
220 public:
221  typedef Value_stor::const_iterator const_iterator;
222  typedef Value_stor::iterator iterator;
223 
224  Struct( const Struct& );
225  Struct() {}
226  ~Struct();
227 
228  Struct& operator =( const Struct& );
229 
230  void swap(Struct&) throw();
231  Struct* clone() const;
232  const std::string& type_name() const;
233  void apply_visitor(Value_type_visitor&) const;
234 
235  size_t size() const;
236  bool has_field( const std::string& ) const;
237 
238  const Value& operator []( const std::string& ) const;
239  Value& operator []( const std::string& );
240 
241  void clear();
242  void insert( const std::string&, Value_ptr );
243  void insert( const std::string&, const Value& );
244 
245  const_iterator begin() const { return values.begin(); }
246  const_iterator end() const { return values.end(); }
247 
248  const_iterator find( const std::string& key ) const { return values.find(key); }
249  iterator find( const std::string& key ) { return values.find(key); }
250 
251  void erase( const std::string& key ) { values.erase(key); }
252 };
253 
254 #ifdef _MSC_VER
255 #pragma warning(disable: 4251)
256 #endif
257 
259 class LIBIQXMLRPC_API Binary_data: public Value_type {
260 public:
262  class Malformed_base64: public Exception {
263  public:
265  Exception( "Malformed base64 format." ) {}
266  };
267 
268 private:
269  static const char base64_alpha[64];
270 
271  std::string data;
272  mutable std::string base64;
273 
274 public:
276  static Binary_data* from_base64( const std::string& );
278  static Binary_data* from_data( const std::string& );
280  static Binary_data* from_data( const char*, size_t size );
281 
283  const std::string& get_base64() const;
285  const std::string& get_data() const;
286 
287  Value_type* clone() const;
288  const std::string& type_name() const;
289  void apply_visitor( Value_type_visitor& ) const;
290 
291 private:
292  class End_of_data {};
293 
294  Binary_data( const std::string&, bool raw );
295 
296  void add_base64_char( int idx ) const;
297  void encode() const;
298 
299  char get_idx( char );
300  void decode_four( const std::string& );
301  void decode();
302 };
303 
304 
306 class LIBIQXMLRPC_API Date_time: public Value_type {
307 public:
309  class Malformed_iso8601: public Exception {
310  public:
312  Exception( "Malformed date-time format." ) {}
313  };
314 
315 private:
316  struct tm tm_;
317  mutable std::string cache;
318 
319 public:
320  Date_time( const struct tm* );
321  explicit Date_time( const std::string& dateTime_iso8601 );
322  explicit Date_time( bool localtime );
323 
324  const struct tm& get_tm() const { return tm_; }
325  const std::string& to_string() const;
326 
327  Value_type* clone() const;
328  const std::string& type_name() const;
329  void apply_visitor(Value_type_visitor&) const;
330 };
331 
332 } // namespace iqxmlrpc
333 
334 #endif
335 // vim:ts=2:sw=2:et