1 |
#ifndef JSON_SPIRIT_VALUE
|
2 |
#define JSON_SPIRIT_VALUE
|
3 |
|
4 |
// Copyright John W. Wilkinson 2007 - 2009.
|
5 |
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
6 |
|
7 |
// json spirit version 4.03
|
8 |
|
9 |
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
10 |
# pragma once
|
11 |
#endif
|
12 |
|
13 |
#include <vector>
|
14 |
#include <map>
|
15 |
#include <string>
|
16 |
#include <cassert>
|
17 |
#include <sstream>
|
18 |
#include <stdexcept>
|
19 |
#include <boost/config.hpp>
|
20 |
#include <boost/cstdint.hpp>
|
21 |
#include <boost/shared_ptr.hpp>
|
22 |
#include <boost/variant.hpp>
|
23 |
|
24 |
namespace json_spirit
|
25 |
{
|
26 |
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
|
27 |
|
28 |
template< class Config > // Config determines whether the value uses std::string or std::wstring and
|
29 |
// whether JSON Objects are represented as vectors or maps
|
30 |
class Value_impl
|
31 |
{
|
32 |
public:
|
33 |
|
34 |
typedef Config Config_type;
|
35 |
typedef typename Config::String_type String_type;
|
36 |
typedef typename Config::Object_type Object;
|
37 |
typedef typename Config::Array_type Array;
|
38 |
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
|
39 |
|
40 |
Value_impl(); // creates null value
|
41 |
Value_impl( Const_str_ptr value );
|
42 |
Value_impl( const String_type& value );
|
43 |
Value_impl( const Object& value );
|
44 |
Value_impl( const Array& value );
|
45 |
Value_impl( bool value );
|
46 |
Value_impl( int value );
|
47 |
Value_impl( boost::int64_t value );
|
48 |
Value_impl( boost::uint64_t value );
|
49 |
Value_impl( double value );
|
50 |
|
51 |
Value_impl( const Value_impl& other );
|
52 |
|
53 |
bool operator==( const Value_impl& lhs ) const;
|
54 |
|
55 |
Value_impl& operator=( const Value_impl& lhs );
|
56 |
|
57 |
Value_type type() const;
|
58 |
|
59 |
bool is_uint64() const;
|
60 |
bool is_null() const;
|
61 |
|
62 |
const String_type& get_str() const;
|
63 |
const Object& get_obj() const;
|
64 |
const Array& get_array() const;
|
65 |
bool get_bool() const;
|
66 |
int get_int() const;
|
67 |
boost::int64_t get_int64() const;
|
68 |
boost::uint64_t get_uint64() const;
|
69 |
double get_real() const;
|
70 |
|
71 |
Object& get_obj();
|
72 |
Array& get_array();
|
73 |
|
74 |
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
|
75 |
// or double d = value.get_value< double >();
|
76 |
|
77 |
static const Value_impl null;
|
78 |
|
79 |
private:
|
80 |
|
81 |
void check_type( const Value_type vtype ) const;
|
82 |
|
83 |
typedef boost::variant< String_type,
|
84 |
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
|
85 |
bool, boost::int64_t, double > Variant;
|
86 |
|
87 |
Value_type type_;
|
88 |
Variant v_;
|
89 |
bool is_uint64_;
|
90 |
};
|
91 |
|
92 |
// vector objects
|
93 |
|
94 |
template< class Config >
|
95 |
struct Pair_impl
|
96 |
{
|
97 |
typedef typename Config::String_type String_type;
|
98 |
typedef typename Config::Value_type Value_type;
|
99 |
|
100 |
Pair_impl( const String_type& name, const Value_type& value );
|
101 |
|
102 |
bool operator==( const Pair_impl& lhs ) const;
|
103 |
|
104 |
String_type name_;
|
105 |
Value_type value_;
|
106 |
};
|
107 |
|
108 |
template< class String >
|
109 |
struct Config_vector
|
110 |
{
|
111 |
typedef String String_type;
|
112 |
typedef Value_impl< Config_vector > Value_type;
|
113 |
typedef Pair_impl < Config_vector > Pair_type;
|
114 |
typedef std::vector< Value_type > Array_type;
|
115 |
typedef std::vector< Pair_type > Object_type;
|
116 |
|
117 |
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
118 |
{
|
119 |
obj.push_back( Pair_type( name , value ) );
|
120 |
|
121 |
return obj.back().value_;
|
122 |
}
|
123 |
|
124 |
static String_type get_name( const Pair_type& pair )
|
125 |
{
|
126 |
return pair.name_;
|
127 |
}
|
128 |
|
129 |
static Value_type get_value( const Pair_type& pair )
|
130 |
{
|
131 |
return pair.value_;
|
132 |
}
|
133 |
};
|
134 |
|
135 |
// typedefs for ASCII
|
136 |
|
137 |
typedef Config_vector< std::string > Config;
|
138 |
|
139 |
typedef Config::Value_type Value;
|
140 |
typedef Config::Pair_type Pair;
|
141 |
typedef Config::Object_type Object;
|
142 |
typedef Config::Array_type Array;
|
143 |
|
144 |
// typedefs for Unicode
|
145 |
|
146 |
#ifndef BOOST_NO_STD_WSTRING
|
147 |
|
148 |
typedef Config_vector< std::wstring > wConfig;
|
149 |
|
150 |
typedef wConfig::Value_type wValue;
|
151 |
typedef wConfig::Pair_type wPair;
|
152 |
typedef wConfig::Object_type wObject;
|
153 |
typedef wConfig::Array_type wArray;
|
154 |
#endif
|
155 |
|
156 |
// map objects
|
157 |
|
158 |
template< class String >
|
159 |
struct Config_map
|
160 |
{
|
161 |
typedef String String_type;
|
162 |
typedef Value_impl< Config_map > Value_type;
|
163 |
typedef std::vector< Value_type > Array_type;
|
164 |
typedef std::map< String_type, Value_type > Object_type;
|
165 |
typedef typename Object_type::value_type Pair_type;
|
166 |
|
167 |
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
168 |
{
|
169 |
return obj[ name ] = value;
|
170 |
}
|
171 |
|
172 |
static String_type get_name( const Pair_type& pair )
|
173 |
{
|
174 |
return pair.first;
|
175 |
}
|
176 |
|
177 |
static Value_type get_value( const Pair_type& pair )
|
178 |
{
|
179 |
return pair.second;
|
180 |
}
|
181 |
};
|
182 |
|
183 |
// typedefs for ASCII
|
184 |
|
185 |
typedef Config_map< std::string > mConfig;
|
186 |
|
187 |
typedef mConfig::Value_type mValue;
|
188 |
typedef mConfig::Object_type mObject;
|
189 |
typedef mConfig::Array_type mArray;
|
190 |
|
191 |
// typedefs for Unicode
|
192 |
|
193 |
#ifndef BOOST_NO_STD_WSTRING
|
194 |
|
195 |
typedef Config_map< std::wstring > wmConfig;
|
196 |
|
197 |
typedef wmConfig::Value_type wmValue;
|
198 |
typedef wmConfig::Object_type wmObject;
|
199 |
typedef wmConfig::Array_type wmArray;
|
200 |
|
201 |
#endif
|
202 |
|
203 |
///////////////////////////////////////////////////////////////////////////////////////////////
|
204 |
//
|
205 |
// implementation
|
206 |
|
207 |
template< class Config >
|
208 |
const Value_impl< Config > Value_impl< Config >::null;
|
209 |
|
210 |
template< class Config >
|
211 |
Value_impl< Config >::Value_impl()
|
212 |
: type_( null_type )
|
213 |
, is_uint64_( false )
|
214 |
{
|
215 |
}
|
216 |
|
217 |
template< class Config >
|
218 |
Value_impl< Config >::Value_impl( const Const_str_ptr value )
|
219 |
: type_( str_type )
|
220 |
, v_( String_type( value ) )
|
221 |
, is_uint64_( false )
|
222 |
{
|
223 |
}
|
224 |
|
225 |
template< class Config >
|
226 |
Value_impl< Config >::Value_impl( const String_type& value )
|
227 |
: type_( str_type )
|
228 |
, v_( value )
|
229 |
, is_uint64_( false )
|
230 |
{
|
231 |
}
|
232 |
|
233 |
template< class Config >
|
234 |
Value_impl< Config >::Value_impl( const Object& value )
|
235 |
: type_( obj_type )
|
236 |
, v_( value )
|
237 |
, is_uint64_( false )
|
238 |
{
|
239 |
}
|
240 |
|
241 |
template< class Config >
|
242 |
Value_impl< Config >::Value_impl( const Array& value )
|
243 |
: type_( array_type )
|
244 |
, v_( value )
|
245 |
, is_uint64_( false )
|
246 |
{
|
247 |
}
|
248 |
|
249 |
template< class Config >
|
250 |
Value_impl< Config >::Value_impl( bool value )
|
251 |
: type_( bool_type )
|
252 |
, v_( value )
|
253 |
, is_uint64_( false )
|
254 |
{
|
255 |
}
|
256 |
|
257 |
template< class Config >
|
258 |
Value_impl< Config >::Value_impl( int value )
|
259 |
: type_( int_type )
|
260 |
, v_( static_cast< boost::int64_t >( value ) )
|
261 |
, is_uint64_( false )
|
262 |
{
|
263 |
}
|
264 |
|
265 |
template< class Config >
|
266 |
Value_impl< Config >::Value_impl( boost::int64_t value )
|
267 |
: type_( int_type )
|
268 |
, v_( value )
|
269 |
, is_uint64_( false )
|
270 |
{
|
271 |
}
|
272 |
|
273 |
template< class Config >
|
274 |
Value_impl< Config >::Value_impl( boost::uint64_t value )
|
275 |
: type_( int_type )
|
276 |
, v_( static_cast< boost::int64_t >( value ) )
|
277 |
, is_uint64_( true )
|
278 |
{
|
279 |
}
|
280 |
|
281 |
template< class Config >
|
282 |
Value_impl< Config >::Value_impl( double value )
|
283 |
: type_( real_type )
|
284 |
, v_( value )
|
285 |
, is_uint64_( false )
|
286 |
{
|
287 |
}
|
288 |
|
289 |
template< class Config >
|
290 |
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
|
291 |
: type_( other.type() )
|
292 |
, v_( other.v_ )
|
293 |
, is_uint64_( other.is_uint64_ )
|
294 |
{
|
295 |
}
|
296 |
|
297 |
template< class Config >
|
298 |
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
|
299 |
{
|
300 |
Value_impl tmp( lhs );
|
301 |
|
302 |
std::swap( type_, tmp.type_ );
|
303 |
std::swap( v_, tmp.v_ );
|
304 |
std::swap( is_uint64_, tmp.is_uint64_ );
|
305 |
|
306 |
return *this;
|
307 |
}
|
308 |
|
309 |
template< class Config >
|
310 |
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
|
311 |
{
|
312 |
if( this == &lhs ) return true;
|
313 |
|
314 |
if( type() != lhs.type() ) return false;
|
315 |
|
316 |
return v_ == lhs.v_;
|
317 |
}
|
318 |
|
319 |
template< class Config >
|
320 |
Value_type Value_impl< Config >::type() const
|
321 |
{
|
322 |
return type_;
|
323 |
}
|
324 |
|
325 |
template< class Config >
|
326 |
bool Value_impl< Config >::is_uint64() const
|
327 |
{
|
328 |
return is_uint64_;
|
329 |
}
|
330 |
|
331 |
template< class Config >
|
332 |
bool Value_impl< Config >::is_null() const
|
333 |
{
|
334 |
return type() == null_type;
|
335 |
}
|
336 |
|
337 |
template< class Config >
|
338 |
void Value_impl< Config >::check_type( const Value_type vtype ) const
|
339 |
{
|
340 |
if( type() != vtype )
|
341 |
{
|
342 |
std::ostringstream os;
|
343 |
|
344 |
os << "value type is " << type() << " not " << vtype;
|
345 |
|
346 |
throw std::runtime_error( os.str() );
|
347 |
}
|
348 |
}
|
349 |
|
350 |
template< class Config >
|
351 |
const typename Config::String_type& Value_impl< Config >::get_str() const
|
352 |
{
|
353 |
check_type( str_type );
|
354 |
|
355 |
return *boost::get< String_type >( &v_ );
|
356 |
}
|
357 |
|
358 |
template< class Config >
|
359 |
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
|
360 |
{
|
361 |
check_type( obj_type );
|
362 |
|
363 |
return *boost::get< Object >( &v_ );
|
364 |
}
|
365 |
|
366 |
template< class Config >
|
367 |
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
|
368 |
{
|
369 |
check_type( array_type );
|
370 |
|
371 |
return *boost::get< Array >( &v_ );
|
372 |
}
|
373 |
|
374 |
template< class Config >
|
375 |
bool Value_impl< Config >::get_bool() const
|
376 |
{
|
377 |
check_type( bool_type );
|
378 |
|
379 |
return boost::get< bool >( v_ );
|
380 |
}
|
381 |
|
382 |
template< class Config >
|
383 |
int Value_impl< Config >::get_int() const
|
384 |
{
|
385 |
check_type( int_type );
|
386 |
|
387 |
return static_cast< int >( get_int64() );
|
388 |
}
|
389 |
|
390 |
template< class Config >
|
391 |
boost::int64_t Value_impl< Config >::get_int64() const
|
392 |
{
|
393 |
check_type( int_type );
|
394 |
|
395 |
return boost::get< boost::int64_t >( v_ );
|
396 |
}
|
397 |
|
398 |
template< class Config >
|
399 |
boost::uint64_t Value_impl< Config >::get_uint64() const
|
400 |
{
|
401 |
check_type( int_type );
|
402 |
|
403 |
return static_cast< boost::uint64_t >( get_int64() );
|
404 |
}
|
405 |
|
406 |
template< class Config >
|
407 |
double Value_impl< Config >::get_real() const
|
408 |
{
|
409 |
if( type() == int_type )
|
410 |
{
|
411 |
return is_uint64() ? static_cast< double >( get_uint64() )
|
412 |
: static_cast< double >( get_int64() );
|
413 |
}
|
414 |
|
415 |
check_type( real_type );
|
416 |
|
417 |
return boost::get< double >( v_ );
|
418 |
}
|
419 |
|
420 |
template< class Config >
|
421 |
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
|
422 |
{
|
423 |
check_type( obj_type );
|
424 |
|
425 |
return *boost::get< Object >( &v_ );
|
426 |
}
|
427 |
|
428 |
template< class Config >
|
429 |
typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
|
430 |
{
|
431 |
check_type( array_type );
|
432 |
|
433 |
return *boost::get< Array >( &v_ );
|
434 |
}
|
435 |
|
436 |
template< class Config >
|
437 |
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
|
438 |
: name_( name )
|
439 |
, value_( value )
|
440 |
{
|
441 |
}
|
442 |
|
443 |
template< class Config >
|
444 |
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
|
445 |
{
|
446 |
if( this == &lhs ) return true;
|
447 |
|
448 |
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
|
449 |
}
|
450 |
|
451 |
// converts a C string, ie. 8 bit char array, to a string object
|
452 |
//
|
453 |
template < class String_type >
|
454 |
String_type to_str( const char* c_str )
|
455 |
{
|
456 |
String_type result;
|
457 |
|
458 |
for( const char* p = c_str; *p != 0; ++p )
|
459 |
{
|
460 |
result += *p;
|
461 |
}
|
462 |
|
463 |
return result;
|
464 |
}
|
465 |
|
466 |
//
|
467 |
|
468 |
namespace internal_
|
469 |
{
|
470 |
template< typename T >
|
471 |
struct Type_to_type
|
472 |
{
|
473 |
};
|
474 |
|
475 |
template< class Value >
|
476 |
int get_value( const Value& value, Type_to_type< int > )
|
477 |
{
|
478 |
return value.get_int();
|
479 |
}
|
480 |
|
481 |
template< class Value >
|
482 |
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
|
483 |
{
|
484 |
return value.get_int64();
|
485 |
}
|
486 |
|
487 |
template< class Value >
|
488 |
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
|
489 |
{
|
490 |
return value.get_uint64();
|
491 |
}
|
492 |
|
493 |
template< class Value >
|
494 |
double get_value( const Value& value, Type_to_type< double > )
|
495 |
{
|
496 |
return value.get_real();
|
497 |
}
|
498 |
|
499 |
template< class Value >
|
500 |
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
|
501 |
{
|
502 |
return value.get_str();
|
503 |
}
|
504 |
|
505 |
template< class Value >
|
506 |
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
|
507 |
{
|
508 |
return value.get_array();
|
509 |
}
|
510 |
|
511 |
template< class Value >
|
512 |
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
|
513 |
{
|
514 |
return value.get_obj();
|
515 |
}
|
516 |
|
517 |
template< class Value >
|
518 |
bool get_value( const Value& value, Type_to_type< bool > )
|
519 |
{
|
520 |
return value.get_bool();
|
521 |
}
|
522 |
}
|
523 |
|
524 |
template< class Config >
|
525 |
template< typename T >
|
526 |
T Value_impl< Config >::get_value() const
|
527 |
{
|
528 |
return internal_::get_value( *this, internal_::Type_to_type< T >() );
|
529 |
}
|
530 |
}
|
531 |
|
532 |
#endif
|