s_nakamoto
15 years ago
13 changed files with 1968 additions and 0 deletions
@ -0,0 +1,24 @@ |
|||||||
|
The MIT License |
||||||
|
|
||||||
|
Copyright (c) 2007 - 2009 John W. Wilkinson |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person |
||||||
|
obtaining a copy of this software and associated documentation |
||||||
|
files (the "Software"), to deal in the Software without |
||||||
|
restriction, including without limitation the rights to use, |
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following |
||||||
|
conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be |
||||||
|
included in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||||
|
OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,18 @@ |
|||||||
|
#ifndef JSON_SPIRIT |
||||||
|
#define JSON_SPIRIT |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
#include "json_spirit_reader.h" |
||||||
|
#include "json_spirit_writer.h" |
||||||
|
#include "json_spirit_utils.h" |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,54 @@ |
|||||||
|
#ifndef JSON_SPIRIT_ERROR_POSITION |
||||||
|
#define JSON_SPIRIT_ERROR_POSITION |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <string> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
// An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
|
||||||
|
// Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
|
||||||
|
// functions that return a bool.
|
||||||
|
//
|
||||||
|
struct Error_position |
||||||
|
{ |
||||||
|
Error_position(); |
||||||
|
Error_position( unsigned int line, unsigned int column, const std::string& reason ); |
||||||
|
bool operator==( const Error_position& lhs ) const; |
||||||
|
unsigned int line_; |
||||||
|
unsigned int column_; |
||||||
|
std::string reason_; |
||||||
|
}; |
||||||
|
|
||||||
|
inline Error_position::Error_position() |
||||||
|
: line_( 0 ) |
||||||
|
, column_( 0 ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) |
||||||
|
: line_( line ) |
||||||
|
, column_( column ) |
||||||
|
, reason_( reason ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
inline bool Error_position::operator==( const Error_position& lhs ) const |
||||||
|
{ |
||||||
|
if( this == &lhs ) return true; |
||||||
|
|
||||||
|
return ( reason_ == lhs.reason_ ) && |
||||||
|
( line_ == lhs.line_ ) && |
||||||
|
( column_ == lhs.column_ ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,137 @@ |
|||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#include "json_spirit_reader.h" |
||||||
|
#include "json_spirit_reader_template.h" |
||||||
|
|
||||||
|
using namespace json_spirit; |
||||||
|
|
||||||
|
bool json_spirit::read( const std::string& s, Value& value ) |
||||||
|
{ |
||||||
|
return read_string( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( const std::string& s, Value& value ) |
||||||
|
{ |
||||||
|
read_string_or_throw( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::istream& is, Value& value ) |
||||||
|
{ |
||||||
|
return read_stream( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::istream& is, Value& value ) |
||||||
|
{ |
||||||
|
read_stream_or_throw( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) |
||||||
|
{ |
||||||
|
return read_range( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) |
||||||
|
{ |
||||||
|
begin = read_range_or_throw( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
bool json_spirit::read( const std::wstring& s, wValue& value ) |
||||||
|
{ |
||||||
|
return read_string( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) |
||||||
|
{ |
||||||
|
read_string_or_throw( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::wistream& is, wValue& value ) |
||||||
|
{ |
||||||
|
return read_stream( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::wistream& is, wValue& value ) |
||||||
|
{ |
||||||
|
read_stream_or_throw( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) |
||||||
|
{ |
||||||
|
return read_range( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) |
||||||
|
{ |
||||||
|
begin = read_range_or_throw( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
bool json_spirit::read( const std::string& s, mValue& value ) |
||||||
|
{ |
||||||
|
return read_string( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( const std::string& s, mValue& value ) |
||||||
|
{ |
||||||
|
read_string_or_throw( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::istream& is, mValue& value ) |
||||||
|
{ |
||||||
|
return read_stream( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::istream& is, mValue& value ) |
||||||
|
{ |
||||||
|
read_stream_or_throw( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) |
||||||
|
{ |
||||||
|
return read_range( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) |
||||||
|
{ |
||||||
|
begin = read_range_or_throw( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
bool json_spirit::read( const std::wstring& s, wmValue& value ) |
||||||
|
{ |
||||||
|
return read_string( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) |
||||||
|
{ |
||||||
|
read_string_or_throw( s, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::wistream& is, wmValue& value ) |
||||||
|
{ |
||||||
|
return read_stream( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) |
||||||
|
{ |
||||||
|
read_stream_or_throw( is, value ); |
||||||
|
} |
||||||
|
|
||||||
|
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) |
||||||
|
{ |
||||||
|
return read_range( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) |
||||||
|
{ |
||||||
|
begin = read_range_or_throw( begin, end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,62 @@ |
|||||||
|
#ifndef JSON_SPIRIT_READER |
||||||
|
#define JSON_SPIRIT_READER |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
#include "json_spirit_error_position.h" |
||||||
|
#include <iostream> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
// functions to reads a JSON values
|
||||||
|
|
||||||
|
bool read( const std::string& s, Value& value ); |
||||||
|
bool read( std::istream& is, Value& value ); |
||||||
|
bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); |
||||||
|
|
||||||
|
void read_or_throw( const std::string& s, Value& value ); |
||||||
|
void read_or_throw( std::istream& is, Value& value ); |
||||||
|
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
bool read( const std::wstring& s, wValue& value ); |
||||||
|
bool read( std::wistream& is, wValue& value ); |
||||||
|
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); |
||||||
|
|
||||||
|
void read_or_throw( const std::wstring& s, wValue& value ); |
||||||
|
void read_or_throw( std::wistream& is, wValue& value ); |
||||||
|
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
bool read( const std::string& s, mValue& value ); |
||||||
|
bool read( std::istream& is, mValue& value ); |
||||||
|
bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); |
||||||
|
|
||||||
|
void read_or_throw( const std::string& s, mValue& value ); |
||||||
|
void read_or_throw( std::istream& is, mValue& value ); |
||||||
|
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
bool read( const std::wstring& s, wmValue& value ); |
||||||
|
bool read( std::wistream& is, wmValue& value ); |
||||||
|
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); |
||||||
|
|
||||||
|
void read_or_throw( const std::wstring& s, wmValue& value ); |
||||||
|
void read_or_throw( std::wistream& is, wmValue& value ); |
||||||
|
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); |
||||||
|
|
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,612 @@ |
|||||||
|
#ifndef JSON_SPIRIT_READER_TEMPLATE |
||||||
|
#define JSON_SPIRIT_READER_TEMPLATE |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
#include "json_spirit_error_position.h" |
||||||
|
|
||||||
|
//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
|
||||||
|
|
||||||
|
#include <boost/bind.hpp> |
||||||
|
#include <boost/function.hpp> |
||||||
|
#include <boost/version.hpp> |
||||||
|
|
||||||
|
#if BOOST_VERSION >= 103800 |
||||||
|
#include <boost/spirit/include/classic_core.hpp> |
||||||
|
#include <boost/spirit/include/classic_confix.hpp> |
||||||
|
#include <boost/spirit/include/classic_escape_char.hpp> |
||||||
|
#include <boost/spirit/include/classic_multi_pass.hpp> |
||||||
|
#include <boost/spirit/include/classic_position_iterator.hpp> |
||||||
|
#define spirit_namespace boost::spirit::classic |
||||||
|
#else |
||||||
|
#include <boost/spirit/core.hpp> |
||||||
|
#include <boost/spirit/utility/confix.hpp> |
||||||
|
#include <boost/spirit/utility/escape_char.hpp> |
||||||
|
#include <boost/spirit/iterator/multi_pass.hpp> |
||||||
|
#include <boost/spirit/iterator/position_iterator.hpp> |
||||||
|
#define spirit_namespace boost::spirit |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); |
||||||
|
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); |
||||||
|
|
||||||
|
template< class Iter_type > |
||||||
|
bool is_eq( Iter_type first, Iter_type last, const char* c_str ) |
||||||
|
{ |
||||||
|
for( Iter_type i = first; i != last; ++i, ++c_str ) |
||||||
|
{ |
||||||
|
if( *c_str == 0 ) return false; |
||||||
|
|
||||||
|
if( *i != *c_str ) return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Char_type > |
||||||
|
Char_type hex_to_num( const Char_type c ) |
||||||
|
{ |
||||||
|
if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; |
||||||
|
if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; |
||||||
|
if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Char_type, class Iter_type > |
||||||
|
Char_type hex_str_to_char( Iter_type& begin ) |
||||||
|
{ |
||||||
|
const Char_type c1( *( ++begin ) ); |
||||||
|
const Char_type c2( *( ++begin ) ); |
||||||
|
|
||||||
|
return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Char_type, class Iter_type > |
||||||
|
Char_type unicode_str_to_char( Iter_type& begin ) |
||||||
|
{ |
||||||
|
const Char_type c1( *( ++begin ) ); |
||||||
|
const Char_type c2( *( ++begin ) ); |
||||||
|
const Char_type c3( *( ++begin ) ); |
||||||
|
const Char_type c4( *( ++begin ) ); |
||||||
|
|
||||||
|
return ( hex_to_num( c1 ) << 12 ) + |
||||||
|
( hex_to_num( c2 ) << 8 ) + |
||||||
|
( hex_to_num( c3 ) << 4 ) + |
||||||
|
hex_to_num( c4 ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type > |
||||||
|
void append_esc_char_and_incr_iter( String_type& s, |
||||||
|
typename String_type::const_iterator& begin, |
||||||
|
typename String_type::const_iterator end ) |
||||||
|
{ |
||||||
|
typedef typename String_type::value_type Char_type; |
||||||
|
|
||||||
|
const Char_type c2( *begin ); |
||||||
|
|
||||||
|
switch( c2 ) |
||||||
|
{ |
||||||
|
case 't': s += '\t'; break; |
||||||
|
case 'b': s += '\b'; break; |
||||||
|
case 'f': s += '\f'; break; |
||||||
|
case 'n': s += '\n'; break; |
||||||
|
case 'r': s += '\r'; break; |
||||||
|
case '\\': s += '\\'; break; |
||||||
|
case '/': s += '/'; break; |
||||||
|
case '"': s += '"'; break; |
||||||
|
case 'x': |
||||||
|
{ |
||||||
|
if( end - begin >= 3 ) // expecting "xHH..."
|
||||||
|
{ |
||||||
|
s += hex_str_to_char< Char_type >( begin ); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'u': |
||||||
|
{ |
||||||
|
if( end - begin >= 5 ) // expecting "uHHHH..."
|
||||||
|
{ |
||||||
|
s += unicode_str_to_char< Char_type >( begin ); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type > |
||||||
|
String_type substitute_esc_chars( typename String_type::const_iterator begin, |
||||||
|
typename String_type::const_iterator end ) |
||||||
|
{ |
||||||
|
typedef typename String_type::const_iterator Iter_type; |
||||||
|
|
||||||
|
if( end - begin < 2 ) return String_type( begin, end ); |
||||||
|
|
||||||
|
String_type result; |
||||||
|
|
||||||
|
result.reserve( end - begin ); |
||||||
|
|
||||||
|
const Iter_type end_minus_1( end - 1 ); |
||||||
|
|
||||||
|
Iter_type substr_start = begin; |
||||||
|
Iter_type i = begin; |
||||||
|
|
||||||
|
for( ; i < end_minus_1; ++i ) |
||||||
|
{ |
||||||
|
if( *i == '\\' ) |
||||||
|
{ |
||||||
|
result.append( substr_start, i ); |
||||||
|
|
||||||
|
++i; // skip the '\'
|
||||||
|
|
||||||
|
append_esc_char_and_incr_iter( result, i, end ); |
||||||
|
|
||||||
|
substr_start = i + 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
result.append( substr_start, end ); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type > |
||||||
|
String_type get_str_( typename String_type::const_iterator begin, |
||||||
|
typename String_type::const_iterator end ) |
||||||
|
{ |
||||||
|
assert( end - begin >= 2 ); |
||||||
|
|
||||||
|
typedef typename String_type::const_iterator Iter_type; |
||||||
|
|
||||||
|
Iter_type str_without_quotes( ++begin ); |
||||||
|
Iter_type end_without_quotes( --end ); |
||||||
|
|
||||||
|
return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); |
||||||
|
} |
||||||
|
|
||||||
|
inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) |
||||||
|
{ |
||||||
|
return get_str_< std::string >( begin, end ); |
||||||
|
} |
||||||
|
|
||||||
|
inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) |
||||||
|
{ |
||||||
|
return get_str_< std::wstring >( begin, end ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type, class Iter_type > |
||||||
|
String_type get_str( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
const String_type tmp( begin, end ); // convert multipass iterators to string iterators
|
||||||
|
|
||||||
|
return get_str( tmp.begin(), tmp.end() ); |
||||||
|
} |
||||||
|
|
||||||
|
// this class's methods get called by the spirit parse resulting
|
||||||
|
// in the creation of a JSON object or array
|
||||||
|
//
|
||||||
|
// NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
|
||||||
|
//
|
||||||
|
template< class Value_type, class Iter_type > |
||||||
|
class Semantic_actions |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
typedef typename Value_type::Config_type Config_type; |
||||||
|
typedef typename Config_type::String_type String_type; |
||||||
|
typedef typename Config_type::Object_type Object_type; |
||||||
|
typedef typename Config_type::Array_type Array_type; |
||||||
|
typedef typename String_type::value_type Char_type; |
||||||
|
|
||||||
|
Semantic_actions( Value_type& value ) |
||||||
|
: value_( value ) |
||||||
|
, current_p_( 0 ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void begin_obj( Char_type c ) |
||||||
|
{ |
||||||
|
assert( c == '{' ); |
||||||
|
|
||||||
|
begin_compound< Object_type >(); |
||||||
|
} |
||||||
|
|
||||||
|
void end_obj( Char_type c ) |
||||||
|
{ |
||||||
|
assert( c == '}' ); |
||||||
|
|
||||||
|
end_compound(); |
||||||
|
} |
||||||
|
|
||||||
|
void begin_array( Char_type c ) |
||||||
|
{ |
||||||
|
assert( c == '[' ); |
||||||
|
|
||||||
|
begin_compound< Array_type >(); |
||||||
|
} |
||||||
|
|
||||||
|
void end_array( Char_type c ) |
||||||
|
{ |
||||||
|
assert( c == ']' ); |
||||||
|
|
||||||
|
end_compound(); |
||||||
|
} |
||||||
|
|
||||||
|
void new_name( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
assert( current_p_->type() == obj_type ); |
||||||
|
|
||||||
|
name_ = get_str< String_type >( begin, end ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_str( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
add_to_current( get_str< String_type >( begin, end ) ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_true( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
assert( is_eq( begin, end, "true" ) ); |
||||||
|
|
||||||
|
add_to_current( true ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_false( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
assert( is_eq( begin, end, "false" ) ); |
||||||
|
|
||||||
|
add_to_current( false ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_null( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
assert( is_eq( begin, end, "null" ) ); |
||||||
|
|
||||||
|
add_to_current( Value_type() ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_int( boost::int64_t i ) |
||||||
|
{ |
||||||
|
add_to_current( i ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_uint64( boost::uint64_t ui ) |
||||||
|
{ |
||||||
|
add_to_current( ui ); |
||||||
|
} |
||||||
|
|
||||||
|
void new_real( double d ) |
||||||
|
{ |
||||||
|
add_to_current( d ); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
Semantic_actions& operator=( const Semantic_actions& ); |
||||||
|
// to prevent "assignment operator could not be generated" warning
|
||||||
|
|
||||||
|
Value_type* add_first( const Value_type& value ) |
||||||
|
{ |
||||||
|
assert( current_p_ == 0 ); |
||||||
|
|
||||||
|
value_ = value; |
||||||
|
current_p_ = &value_; |
||||||
|
return current_p_; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Array_or_obj > |
||||||
|
void begin_compound() |
||||||
|
{ |
||||||
|
if( current_p_ == 0 ) |
||||||
|
{ |
||||||
|
add_first( Array_or_obj() ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
stack_.push_back( current_p_ ); |
||||||
|
|
||||||
|
Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
|
||||||
|
|
||||||
|
current_p_ = add_to_current( new_array_or_obj ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void end_compound() |
||||||
|
{ |
||||||
|
if( current_p_ != &value_ ) |
||||||
|
{ |
||||||
|
current_p_ = stack_.back(); |
||||||
|
|
||||||
|
stack_.pop_back(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Value_type* add_to_current( const Value_type& value ) |
||||||
|
{ |
||||||
|
if( current_p_ == 0 ) |
||||||
|
{ |
||||||
|
return add_first( value ); |
||||||
|
} |
||||||
|
else if( current_p_->type() == array_type ) |
||||||
|
{ |
||||||
|
current_p_->get_array().push_back( value ); |
||||||
|
|
||||||
|
return ¤t_p_->get_array().back(); |
||||||
|
} |
||||||
|
|
||||||
|
assert( current_p_->type() == obj_type ); |
||||||
|
|
||||||
|
return &Config_type::add( current_p_->get_obj(), name_, value ); |
||||||
|
} |
||||||
|
|
||||||
|
Value_type& value_; // this is the object or array that is being created
|
||||||
|
Value_type* current_p_; // the child object or array that is currently being constructed
|
||||||
|
|
||||||
|
std::vector< Value_type* > stack_; // previous child objects and arrays
|
||||||
|
|
||||||
|
String_type name_; // of current name/value pair
|
||||||
|
}; |
||||||
|
|
||||||
|
template< typename Iter_type > |
||||||
|
void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) |
||||||
|
{ |
||||||
|
throw Error_position( i.get_position().line, i.get_position().column, reason ); |
||||||
|
} |
||||||
|
|
||||||
|
template< typename Iter_type > |
||||||
|
void throw_error( Iter_type i, const std::string& reason ) |
||||||
|
{ |
||||||
|
throw reason; |
||||||
|
} |
||||||
|
|
||||||
|
// the spirit grammer
|
||||||
|
//
|
||||||
|
template< class Value_type, class Iter_type > |
||||||
|
class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; |
||||||
|
|
||||||
|
Json_grammer( Semantic_actions_t& semantic_actions ) |
||||||
|
: actions_( semantic_actions ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_value( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "not a value" ); |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_array( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "not an array" ); |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_object( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "not an object" ); |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_pair( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "not a pair" ); |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_colon( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "no colon in pair" ); |
||||||
|
} |
||||||
|
|
||||||
|
static void throw_not_string( Iter_type begin, Iter_type end ) |
||||||
|
{ |
||||||
|
throw_error( begin, "not a string" ); |
||||||
|
} |
||||||
|
|
||||||
|
template< typename ScannerT > |
||||||
|
class definition |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
definition( const Json_grammer& self ) |
||||||
|
{ |
||||||
|
using namespace spirit_namespace; |
||||||
|
|
||||||
|
typedef typename Value_type::String_type::value_type Char_type; |
||||||
|
|
||||||
|
// first we convert the semantic action class methods to functors with the
|
||||||
|
// parameter signature expected by spirit
|
||||||
|
|
||||||
|
typedef boost::function< void( Char_type ) > Char_action; |
||||||
|
typedef boost::function< void( Iter_type, Iter_type ) > Str_action; |
||||||
|
typedef boost::function< void( double ) > Real_action; |
||||||
|
typedef boost::function< void( boost::int64_t ) > Int_action; |
||||||
|
typedef boost::function< void( boost::uint64_t ) > Uint64_action; |
||||||
|
|
||||||
|
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); |
||||||
|
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); |
||||||
|
Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); |
||||||
|
Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); |
||||||
|
Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); |
||||||
|
Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); |
||||||
|
Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); |
||||||
|
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); |
||||||
|
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); |
||||||
|
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); |
||||||
|
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); |
||||||
|
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); |
||||||
|
|
||||||
|
// actual grammer
|
||||||
|
|
||||||
|
json_ |
||||||
|
= value_ | eps_p[ &throw_not_value ] |
||||||
|
; |
||||||
|
|
||||||
|
value_ |
||||||
|
= string_[ new_str ] |
||||||
|
| number_ |
||||||
|
| object_ |
||||||
|
| array_ |
||||||
|
| str_p( "true" ) [ new_true ] |
||||||
|
| str_p( "false" )[ new_false ] |
||||||
|
| str_p( "null" ) [ new_null ] |
||||||
|
; |
||||||
|
|
||||||
|
object_ |
||||||
|
= ch_p('{')[ begin_obj ] |
||||||
|
>> !members_ |
||||||
|
>> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) |
||||||
|
; |
||||||
|
|
||||||
|
members_ |
||||||
|
= pair_ >> *( ',' >> pair_ ) |
||||||
|
; |
||||||
|
|
||||||
|
pair_ |
||||||
|
= string_[ new_name ] |
||||||
|
>> ( ':' | eps_p[ &throw_not_colon ] ) |
||||||
|
>> ( value_ | eps_p[ &throw_not_value ] ) |
||||||
|
; |
||||||
|
|
||||||
|
array_ |
||||||
|
= ch_p('[')[ begin_array ] |
||||||
|
>> !elements_ |
||||||
|
>> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) |
||||||
|
; |
||||||
|
|
||||||
|
elements_ |
||||||
|
= value_ >> *( ',' >> value_ ) |
||||||
|
; |
||||||
|
|
||||||
|
string_ |
||||||
|
= lexeme_d // this causes white space inside a string to be retained
|
||||||
|
[ |
||||||
|
confix_p |
||||||
|
( |
||||||
|
'"', |
||||||
|
*lex_escape_ch_p, |
||||||
|
'"' |
||||||
|
) |
||||||
|
] |
||||||
|
; |
||||||
|
|
||||||
|
number_ |
||||||
|
= strict_real_p[ new_real ] |
||||||
|
| int64_p [ new_int ] |
||||||
|
| uint64_p [ new_uint64 ] |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; |
||||||
|
|
||||||
|
const spirit_namespace::rule< ScannerT >& start() const { return json_; } |
||||||
|
}; |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
|
||||||
|
|
||||||
|
Semantic_actions_t& actions_; |
||||||
|
}; |
||||||
|
|
||||||
|
template< class Iter_type, class Value_type > |
||||||
|
Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) |
||||||
|
{ |
||||||
|
Semantic_actions< Value_type, Iter_type > semantic_actions( value ); |
||||||
|
|
||||||
|
const spirit_namespace::parse_info< Iter_type > info = |
||||||
|
spirit_namespace::parse( begin, end, |
||||||
|
Json_grammer< Value_type, Iter_type >( semantic_actions ), |
||||||
|
spirit_namespace::space_p ); |
||||||
|
|
||||||
|
if( !info.hit ) |
||||||
|
{ |
||||||
|
assert( false ); // in theory exception should already have been thrown
|
||||||
|
throw_error( info.stop, "error" ); |
||||||
|
} |
||||||
|
|
||||||
|
return info.stop; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Iter_type, class Value_type > |
||||||
|
void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) |
||||||
|
{ |
||||||
|
typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; |
||||||
|
|
||||||
|
const Posn_iter_t posn_begin( begin, end ); |
||||||
|
const Posn_iter_t posn_end( end, end ); |
||||||
|
|
||||||
|
read_range_or_throw( posn_begin, posn_end, value ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Iter_type, class Value_type > |
||||||
|
bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
begin = read_range_or_throw( begin, end, value ); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
catch( ... ) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type, class Value_type > |
||||||
|
void read_string_or_throw( const String_type& s, Value_type& value ) |
||||||
|
{ |
||||||
|
add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type, class Value_type > |
||||||
|
bool read_string( const String_type& s, Value_type& value ) |
||||||
|
{ |
||||||
|
typename String_type::const_iterator begin = s.begin(); |
||||||
|
|
||||||
|
return read_range( begin, s.end(), value ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Istream_type > |
||||||
|
struct Multi_pass_iters |
||||||
|
{ |
||||||
|
typedef typename Istream_type::char_type Char_type; |
||||||
|
typedef std::istream_iterator< Char_type, Char_type > istream_iter; |
||||||
|
typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; |
||||||
|
|
||||||
|
Multi_pass_iters( Istream_type& is ) |
||||||
|
{ |
||||||
|
is.unsetf( std::ios::skipws ); |
||||||
|
|
||||||
|
begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); |
||||||
|
end_ = spirit_namespace::make_multi_pass( istream_iter() ); |
||||||
|
} |
||||||
|
|
||||||
|
Mp_iter begin_; |
||||||
|
Mp_iter end_; |
||||||
|
}; |
||||||
|
|
||||||
|
template< class Istream_type, class Value_type > |
||||||
|
bool read_stream( Istream_type& is, Value_type& value ) |
||||||
|
{ |
||||||
|
Multi_pass_iters< Istream_type > mp_iters( is ); |
||||||
|
|
||||||
|
return read_range( mp_iters.begin_, mp_iters.end_, value ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Istream_type, class Value_type > |
||||||
|
void read_stream_or_throw( Istream_type& is, Value_type& value ) |
||||||
|
{ |
||||||
|
const Multi_pass_iters< Istream_type > mp_iters( is ); |
||||||
|
|
||||||
|
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,70 @@ |
|||||||
|
#ifndef JSON_SPIRIT_READ_STREAM |
||||||
|
#define JSON_SPIRIT_READ_STREAM |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "json_spirit_reader_template.h" |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
// these classes allows you to read multiple top level contiguous values from a stream,
|
||||||
|
// the normal stream read functions have a bug that prevent multiple top level values
|
||||||
|
// from being read unless they are separated by spaces
|
||||||
|
|
||||||
|
template< class Istream_type, class Value_type > |
||||||
|
class Stream_reader |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
Stream_reader( Istream_type& is ) |
||||||
|
: iters_( is ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
bool read_next( Value_type& value ) |
||||||
|
{ |
||||||
|
return read_range( iters_.begin_, iters_.end_, value ); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
typedef Multi_pass_iters< Istream_type > Mp_iters; |
||||||
|
|
||||||
|
Mp_iters iters_; |
||||||
|
}; |
||||||
|
|
||||||
|
template< class Istream_type, class Value_type > |
||||||
|
class Stream_reader_thrower |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
Stream_reader_thrower( Istream_type& is ) |
||||||
|
: iters_( is ) |
||||||
|
, posn_begin_( iters_.begin_, iters_.end_ ) |
||||||
|
, posn_end_( iters_.end_, iters_.end_ ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void read_next( Value_type& value ) |
||||||
|
{ |
||||||
|
posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
typedef Multi_pass_iters< Istream_type > Mp_iters; |
||||||
|
typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; |
||||||
|
|
||||||
|
Mp_iters iters_; |
||||||
|
Posn_iter_t posn_begin_, posn_end_; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,61 @@ |
|||||||
|
#ifndef JSON_SPIRIT_UTILS |
||||||
|
#define JSON_SPIRIT_UTILS |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
#include <map> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
template< class Obj_t, class Map_t > |
||||||
|
void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) |
||||||
|
{ |
||||||
|
mp_obj.clear(); |
||||||
|
|
||||||
|
for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) |
||||||
|
{ |
||||||
|
mp_obj[ i->name_ ] = i->value_; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template< class Obj_t, class Map_t > |
||||||
|
void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) |
||||||
|
{ |
||||||
|
obj.clear(); |
||||||
|
|
||||||
|
for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) |
||||||
|
{ |
||||||
|
obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
typedef std::map< std::string, Value > Mapped_obj; |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
typedef std::map< std::wstring, wValue > wMapped_obj; |
||||||
|
#endif |
||||||
|
|
||||||
|
template< class Object_type, class String_type > |
||||||
|
const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) |
||||||
|
{ |
||||||
|
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) |
||||||
|
{ |
||||||
|
if( i->name_ == name ) |
||||||
|
{ |
||||||
|
return i->value_; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return Object_type::value_type::Value_type::null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,8 @@ |
|||||||
|
/* Copyright (c) 2007 John W Wilkinson
|
||||||
|
|
||||||
|
This source code can be used for any purpose as long as |
||||||
|
this comment is retained. */ |
||||||
|
|
||||||
|
// json spirit version 2.00
|
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
@ -0,0 +1,532 @@ |
|||||||
|
#ifndef JSON_SPIRIT_VALUE |
||||||
|
#define JSON_SPIRIT_VALUE |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <vector> |
||||||
|
#include <map> |
||||||
|
#include <string> |
||||||
|
#include <cassert> |
||||||
|
#include <sstream> |
||||||
|
#include <stdexcept> |
||||||
|
#include <boost/config.hpp> |
||||||
|
#include <boost/cstdint.hpp> |
||||||
|
#include <boost/shared_ptr.hpp> |
||||||
|
#include <boost/variant.hpp> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; |
||||||
|
|
||||||
|
template< class Config > // Config determines whether the value uses std::string or std::wstring and
|
||||||
|
// whether JSON Objects are represented as vectors or maps
|
||||||
|
class Value_impl |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
typedef Config Config_type; |
||||||
|
typedef typename Config::String_type String_type; |
||||||
|
typedef typename Config::Object_type Object; |
||||||
|
typedef typename Config::Array_type Array; |
||||||
|
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
|
||||||
|
|
||||||
|
Value_impl(); // creates null value
|
||||||
|
Value_impl( Const_str_ptr value ); |
||||||
|
Value_impl( const String_type& value ); |
||||||
|
Value_impl( const Object& value ); |
||||||
|
Value_impl( const Array& value ); |
||||||
|
Value_impl( bool value ); |
||||||
|
Value_impl( int value ); |
||||||
|
Value_impl( boost::int64_t value ); |
||||||
|
Value_impl( boost::uint64_t value ); |
||||||
|
Value_impl( double value ); |
||||||
|
|
||||||
|
Value_impl( const Value_impl& other ); |
||||||
|
|
||||||
|
bool operator==( const Value_impl& lhs ) const; |
||||||
|
|
||||||
|
Value_impl& operator=( const Value_impl& lhs ); |
||||||
|
|
||||||
|
Value_type type() const; |
||||||
|
|
||||||
|
bool is_uint64() const; |
||||||
|
bool is_null() const; |
||||||
|
|
||||||
|
const String_type& get_str() const; |
||||||
|
const Object& get_obj() const; |
||||||
|
const Array& get_array() const; |
||||||
|
bool get_bool() const; |
||||||
|
int get_int() const; |
||||||
|
boost::int64_t get_int64() const; |
||||||
|
boost::uint64_t get_uint64() const; |
||||||
|
double get_real() const; |
||||||
|
|
||||||
|
Object& get_obj(); |
||||||
|
Array& get_array(); |
||||||
|
|
||||||
|
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
|
||||||
|
// or double d = value.get_value< double >();
|
||||||
|
|
||||||
|
static const Value_impl null; |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
void check_type( const Value_type vtype ) const; |
||||||
|
|
||||||
|
typedef boost::variant< String_type, |
||||||
|
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, |
||||||
|
bool, boost::int64_t, double > Variant; |
||||||
|
|
||||||
|
Value_type type_; |
||||||
|
Variant v_; |
||||||
|
bool is_uint64_; |
||||||
|
}; |
||||||
|
|
||||||
|
// vector objects
|
||||||
|
|
||||||
|
template< class Config > |
||||||
|
struct Pair_impl |
||||||
|
{ |
||||||
|
typedef typename Config::String_type String_type; |
||||||
|
typedef typename Config::Value_type Value_type; |
||||||
|
|
||||||
|
Pair_impl( const String_type& name, const Value_type& value ); |
||||||
|
|
||||||
|
bool operator==( const Pair_impl& lhs ) const; |
||||||
|
|
||||||
|
String_type name_; |
||||||
|
Value_type value_; |
||||||
|
}; |
||||||
|
|
||||||
|
template< class String > |
||||||
|
struct Config_vector |
||||||
|
{ |
||||||
|
typedef String String_type; |
||||||
|
typedef Value_impl< Config_vector > Value_type; |
||||||
|
typedef Pair_impl < Config_vector > Pair_type; |
||||||
|
typedef std::vector< Value_type > Array_type; |
||||||
|
typedef std::vector< Pair_type > Object_type; |
||||||
|
|
||||||
|
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) |
||||||
|
{ |
||||||
|
obj.push_back( Pair_type( name , value ) ); |
||||||
|
|
||||||
|
return obj.back().value_; |
||||||
|
} |
||||||
|
|
||||||
|
static String_type get_name( const Pair_type& pair ) |
||||||
|
{ |
||||||
|
return pair.name_; |
||||||
|
} |
||||||
|
|
||||||
|
static Value_type get_value( const Pair_type& pair ) |
||||||
|
{ |
||||||
|
return pair.value_; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// typedefs for ASCII
|
||||||
|
|
||||||
|
typedef Config_vector< std::string > Config; |
||||||
|
|
||||||
|
typedef Config::Value_type Value; |
||||||
|
typedef Config::Pair_type Pair; |
||||||
|
typedef Config::Object_type Object; |
||||||
|
typedef Config::Array_type Array; |
||||||
|
|
||||||
|
// typedefs for Unicode
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
typedef Config_vector< std::wstring > wConfig; |
||||||
|
|
||||||
|
typedef wConfig::Value_type wValue; |
||||||
|
typedef wConfig::Pair_type wPair; |
||||||
|
typedef wConfig::Object_type wObject; |
||||||
|
typedef wConfig::Array_type wArray; |
||||||
|
#endif |
||||||
|
|
||||||
|
// map objects
|
||||||
|
|
||||||
|
template< class String > |
||||||
|
struct Config_map |
||||||
|
{ |
||||||
|
typedef String String_type; |
||||||
|
typedef Value_impl< Config_map > Value_type; |
||||||
|
typedef std::vector< Value_type > Array_type; |
||||||
|
typedef std::map< String_type, Value_type > Object_type; |
||||||
|
typedef typename Object_type::value_type Pair_type; |
||||||
|
|
||||||
|
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) |
||||||
|
{ |
||||||
|
return obj[ name ] = value; |
||||||
|
} |
||||||
|
|
||||||
|
static String_type get_name( const Pair_type& pair ) |
||||||
|
{ |
||||||
|
return pair.first; |
||||||
|
} |
||||||
|
|
||||||
|
static Value_type get_value( const Pair_type& pair ) |
||||||
|
{ |
||||||
|
return pair.second; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// typedefs for ASCII
|
||||||
|
|
||||||
|
typedef Config_map< std::string > mConfig; |
||||||
|
|
||||||
|
typedef mConfig::Value_type mValue; |
||||||
|
typedef mConfig::Object_type mObject; |
||||||
|
typedef mConfig::Array_type mArray; |
||||||
|
|
||||||
|
// typedefs for Unicode
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
typedef Config_map< std::wstring > wmConfig; |
||||||
|
|
||||||
|
typedef wmConfig::Value_type wmValue; |
||||||
|
typedef wmConfig::Object_type wmObject; |
||||||
|
typedef wmConfig::Array_type wmArray; |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// implementation
|
||||||
|
|
||||||
|
template< class Config > |
||||||
|
const Value_impl< Config > Value_impl< Config >::null; |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl() |
||||||
|
: type_( null_type ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( const Const_str_ptr value ) |
||||||
|
: type_( str_type ) |
||||||
|
, v_( String_type( value ) ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( const String_type& value ) |
||||||
|
: type_( str_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( const Object& value ) |
||||||
|
: type_( obj_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( const Array& value ) |
||||||
|
: type_( array_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( bool value ) |
||||||
|
: type_( bool_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( int value ) |
||||||
|
: type_( int_type ) |
||||||
|
, v_( static_cast< boost::int64_t >( value ) ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( boost::int64_t value ) |
||||||
|
: type_( int_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( boost::uint64_t value ) |
||||||
|
: type_( int_type ) |
||||||
|
, v_( static_cast< boost::int64_t >( value ) ) |
||||||
|
, is_uint64_( true ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( double value ) |
||||||
|
: type_( real_type ) |
||||||
|
, v_( value ) |
||||||
|
, is_uint64_( false ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) |
||||||
|
: type_( other.type() ) |
||||||
|
, v_( other.v_ ) |
||||||
|
, is_uint64_( other.is_uint64_ ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) |
||||||
|
{ |
||||||
|
Value_impl tmp( lhs ); |
||||||
|
|
||||||
|
std::swap( type_, tmp.type_ ); |
||||||
|
std::swap( v_, tmp.v_ ); |
||||||
|
std::swap( is_uint64_, tmp.is_uint64_ ); |
||||||
|
|
||||||
|
return *this; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const |
||||||
|
{ |
||||||
|
if( this == &lhs ) return true; |
||||||
|
|
||||||
|
if( type() != lhs.type() ) return false; |
||||||
|
|
||||||
|
return v_ == lhs.v_; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Value_type Value_impl< Config >::type() const |
||||||
|
{ |
||||||
|
return type_; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
bool Value_impl< Config >::is_uint64() const |
||||||
|
{ |
||||||
|
return is_uint64_; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
bool Value_impl< Config >::is_null() const |
||||||
|
{ |
||||||
|
return type() == null_type; |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
void Value_impl< Config >::check_type( const Value_type vtype ) const |
||||||
|
{ |
||||||
|
if( type() != vtype ) |
||||||
|
{ |
||||||
|
std::ostringstream os; |
||||||
|
|
||||||
|
os << "value type is " << type() << " not " << vtype; |
||||||
|
|
||||||
|
throw std::runtime_error( os.str() ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
const typename Config::String_type& Value_impl< Config >::get_str() const |
||||||
|
{ |
||||||
|
check_type( str_type ); |
||||||
|
|
||||||
|
return *boost::get< String_type >( &v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const |
||||||
|
{ |
||||||
|
check_type( obj_type ); |
||||||
|
|
||||||
|
return *boost::get< Object >( &v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const |
||||||
|
{ |
||||||
|
check_type( array_type ); |
||||||
|
|
||||||
|
return *boost::get< Array >( &v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
bool Value_impl< Config >::get_bool() const |
||||||
|
{ |
||||||
|
check_type( bool_type ); |
||||||
|
|
||||||
|
return boost::get< bool >( v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
int Value_impl< Config >::get_int() const |
||||||
|
{ |
||||||
|
check_type( int_type ); |
||||||
|
|
||||||
|
return static_cast< int >( get_int64() ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
boost::int64_t Value_impl< Config >::get_int64() const |
||||||
|
{ |
||||||
|
check_type( int_type ); |
||||||
|
|
||||||
|
return boost::get< boost::int64_t >( v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
boost::uint64_t Value_impl< Config >::get_uint64() const |
||||||
|
{ |
||||||
|
check_type( int_type ); |
||||||
|
|
||||||
|
return static_cast< boost::uint64_t >( get_int64() ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
double Value_impl< Config >::get_real() const |
||||||
|
{ |
||||||
|
if( type() == int_type ) |
||||||
|
{ |
||||||
|
return is_uint64() ? static_cast< double >( get_uint64() ) |
||||||
|
: static_cast< double >( get_int64() ); |
||||||
|
} |
||||||
|
|
||||||
|
check_type( real_type ); |
||||||
|
|
||||||
|
return boost::get< double >( v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() |
||||||
|
{ |
||||||
|
check_type( obj_type ); |
||||||
|
|
||||||
|
return *boost::get< Object >( &v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
typename Value_impl< Config >::Array& Value_impl< Config >::get_array() |
||||||
|
{ |
||||||
|
check_type( array_type ); |
||||||
|
|
||||||
|
return *boost::get< Array >( &v_ ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) |
||||||
|
: name_( name ) |
||||||
|
, value_( value ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const |
||||||
|
{ |
||||||
|
if( this == &lhs ) return true; |
||||||
|
|
||||||
|
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); |
||||||
|
} |
||||||
|
|
||||||
|
// converts a C string, ie. 8 bit char array, to a string object
|
||||||
|
//
|
||||||
|
template < class String_type > |
||||||
|
String_type to_str( const char* c_str ) |
||||||
|
{ |
||||||
|
String_type result; |
||||||
|
|
||||||
|
for( const char* p = c_str; *p != 0; ++p ) |
||||||
|
{ |
||||||
|
result += *p; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace internal_ |
||||||
|
{ |
||||||
|
template< typename T > |
||||||
|
struct Type_to_type |
||||||
|
{ |
||||||
|
}; |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
int get_value( const Value& value, Type_to_type< int > ) |
||||||
|
{ |
||||||
|
return value.get_int(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) |
||||||
|
{ |
||||||
|
return value.get_int64(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) |
||||||
|
{ |
||||||
|
return value.get_uint64(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
double get_value( const Value& value, Type_to_type< double > ) |
||||||
|
{ |
||||||
|
return value.get_real(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) |
||||||
|
{ |
||||||
|
return value.get_str(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) |
||||||
|
{ |
||||||
|
return value.get_array(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) |
||||||
|
{ |
||||||
|
return value.get_obj(); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value > |
||||||
|
bool get_value( const Value& value, Type_to_type< bool > ) |
||||||
|
{ |
||||||
|
return value.get_bool(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template< class Config > |
||||||
|
template< typename T > |
||||||
|
T Value_impl< Config >::get_value() const |
||||||
|
{ |
||||||
|
return internal_::get_value( *this, internal_::Type_to_type< T >() ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,95 @@ |
|||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#include "json_spirit_writer.h" |
||||||
|
#include "json_spirit_writer_template.h" |
||||||
|
|
||||||
|
void json_spirit::write( const Value& value, std::ostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, false ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::write_formatted( const Value& value, std::ostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, true ); |
||||||
|
} |
||||||
|
|
||||||
|
std::string json_spirit::write( const Value& value ) |
||||||
|
{ |
||||||
|
return write_string( value, false ); |
||||||
|
} |
||||||
|
|
||||||
|
std::string json_spirit::write_formatted( const Value& value ) |
||||||
|
{ |
||||||
|
return write_string( value, true ); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
void json_spirit::write( const wValue& value, std::wostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, false ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::write_formatted( const wValue& value, std::wostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, true ); |
||||||
|
} |
||||||
|
|
||||||
|
std::wstring json_spirit::write( const wValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, false ); |
||||||
|
} |
||||||
|
|
||||||
|
std::wstring json_spirit::write_formatted( const wValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, true ); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
void json_spirit::write( const mValue& value, std::ostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, false ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::write_formatted( const mValue& value, std::ostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, true ); |
||||||
|
} |
||||||
|
|
||||||
|
std::string json_spirit::write( const mValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, false ); |
||||||
|
} |
||||||
|
|
||||||
|
std::string json_spirit::write_formatted( const mValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, true ); |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
void json_spirit::write( const wmValue& value, std::wostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, false ); |
||||||
|
} |
||||||
|
|
||||||
|
void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) |
||||||
|
{ |
||||||
|
write_stream( value, os, true ); |
||||||
|
} |
||||||
|
|
||||||
|
std::wstring json_spirit::write( const wmValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, false ); |
||||||
|
} |
||||||
|
|
||||||
|
std::wstring json_spirit::write_formatted( const wmValue& value ) |
||||||
|
{ |
||||||
|
return write_string( value, true ); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,50 @@ |
|||||||
|
#ifndef JSON_SPIRIT_WRITER |
||||||
|
#define JSON_SPIRIT_WRITER |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
# pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
#include <iostream> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
// functions to convert JSON Values to text,
|
||||||
|
// the "formatted" versions add whitespace to format the output nicely
|
||||||
|
|
||||||
|
void write ( const Value& value, std::ostream& os ); |
||||||
|
void write_formatted( const Value& value, std::ostream& os ); |
||||||
|
std::string write ( const Value& value ); |
||||||
|
std::string write_formatted( const Value& value ); |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
void write ( const wValue& value, std::wostream& os ); |
||||||
|
void write_formatted( const wValue& value, std::wostream& os ); |
||||||
|
std::wstring write ( const wValue& value ); |
||||||
|
std::wstring write_formatted( const wValue& value ); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
void write ( const mValue& value, std::ostream& os ); |
||||||
|
void write_formatted( const mValue& value, std::ostream& os ); |
||||||
|
std::string write ( const mValue& value ); |
||||||
|
std::string write_formatted( const mValue& value ); |
||||||
|
|
||||||
|
#ifndef BOOST_NO_STD_WSTRING |
||||||
|
|
||||||
|
void write ( const wmValue& value, std::wostream& os ); |
||||||
|
void write_formatted( const wmValue& value, std::wostream& os ); |
||||||
|
std::wstring write ( const wmValue& value ); |
||||||
|
std::wstring write_formatted( const wmValue& value ); |
||||||
|
|
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,245 @@ |
|||||||
|
#ifndef JSON_SPIRIT_WRITER_TEMPLATE |
||||||
|
#define JSON_SPIRIT_WRITER_TEMPLATE |
||||||
|
|
||||||
|
// Copyright John W. Wilkinson 2007 - 2009.
|
||||||
|
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||||
|
|
||||||
|
// json spirit version 4.03
|
||||||
|
|
||||||
|
#include "json_spirit_value.h" |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
#include <sstream> |
||||||
|
#include <iomanip> |
||||||
|
|
||||||
|
namespace json_spirit |
||||||
|
{ |
||||||
|
inline char to_hex_char( unsigned int c ) |
||||||
|
{ |
||||||
|
assert( c <= 0xF ); |
||||||
|
|
||||||
|
const char ch = static_cast< char >( c ); |
||||||
|
|
||||||
|
if( ch < 10 ) return '0' + ch; |
||||||
|
|
||||||
|
return 'A' - 10 + ch; |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type > |
||||||
|
String_type non_printable_to_string( unsigned int c ) |
||||||
|
{ |
||||||
|
typedef typename String_type::value_type Char_type; |
||||||
|
|
||||||
|
String_type result( 6, '\\' ); |
||||||
|
|
||||||
|
result[1] = 'u'; |
||||||
|
|
||||||
|
result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; |
||||||
|
result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; |
||||||
|
result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; |
||||||
|
result[ 2 ] = to_hex_char( c & 0x000F ); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
template< typename Char_type, class String_type > |
||||||
|
bool add_esc_char( Char_type c, String_type& s ) |
||||||
|
{ |
||||||
|
switch( c ) |
||||||
|
{ |
||||||
|
case '"': s += to_str< String_type >( "\\\"" ); return true; |
||||||
|
case '\\': s += to_str< String_type >( "\\\\" ); return true; |
||||||
|
case '\b': s += to_str< String_type >( "\\b" ); return true; |
||||||
|
case '\f': s += to_str< String_type >( "\\f" ); return true; |
||||||
|
case '\n': s += to_str< String_type >( "\\n" ); return true; |
||||||
|
case '\r': s += to_str< String_type >( "\\r" ); return true; |
||||||
|
case '\t': s += to_str< String_type >( "\\t" ); return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
template< class String_type > |
||||||
|
String_type add_esc_chars( const String_type& s ) |
||||||
|
{ |
||||||
|
typedef typename String_type::const_iterator Iter_type; |
||||||
|
typedef typename String_type::value_type Char_type; |
||||||
|
|
||||||
|
String_type result; |
||||||
|
|
||||||
|
const Iter_type end( s.end() ); |
||||||
|
|
||||||
|
for( Iter_type i = s.begin(); i != end; ++i ) |
||||||
|
{ |
||||||
|
const Char_type c( *i ); |
||||||
|
|
||||||
|
if( add_esc_char( c, result ) ) continue; |
||||||
|
|
||||||
|
const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); |
||||||
|
|
||||||
|
if( iswprint( unsigned_c ) ) |
||||||
|
{ |
||||||
|
result += c; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
result += non_printable_to_string< String_type >( unsigned_c ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
// this class generates the JSON text,
|
||||||
|
// it keeps track of the indentation level etc.
|
||||||
|
//
|
||||||
|
template< class Value_type, class Ostream_type > |
||||||
|
class Generator |
||||||
|
{ |
||||||
|
typedef typename Value_type::Config_type Config_type; |
||||||
|
typedef typename Config_type::String_type String_type; |
||||||
|
typedef typename Config_type::Object_type Object_type; |
||||||
|
typedef typename Config_type::Array_type Array_type; |
||||||
|
typedef typename String_type::value_type Char_type; |
||||||
|
typedef typename Object_type::value_type Obj_member_type; |
||||||
|
|
||||||
|
public: |
||||||
|
|
||||||
|
Generator( const Value_type& value, Ostream_type& os, bool pretty ) |
||||||
|
: os_( os ) |
||||||
|
, indentation_level_( 0 ) |
||||||
|
, pretty_( pretty ) |
||||||
|
{ |
||||||
|
output( value ); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
void output( const Value_type& value ) |
||||||
|
{ |
||||||
|
switch( value.type() ) |
||||||
|
{ |
||||||
|
case obj_type: output( value.get_obj() ); break; |
||||||
|
case array_type: output( value.get_array() ); break; |
||||||
|
case str_type: output( value.get_str() ); break; |
||||||
|
case bool_type: output( value.get_bool() ); break; |
||||||
|
case int_type: output_int( value ); break; |
||||||
|
case real_type: os_ << std::showpoint << std::setprecision( 16 ) |
||||||
|
<< value.get_real(); break; |
||||||
|
case null_type: os_ << "null"; break; |
||||||
|
default: assert( false ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void output( const Object_type& obj ) |
||||||
|
{ |
||||||
|
output_array_or_obj( obj, '{', '}' ); |
||||||
|
} |
||||||
|
|
||||||
|
void output( const Array_type& arr ) |
||||||
|
{ |
||||||
|
output_array_or_obj( arr, '[', ']' ); |
||||||
|
} |
||||||
|
|
||||||
|
void output( const Obj_member_type& member ) |
||||||
|
{ |
||||||
|
output( Config_type::get_name( member ) ); space(); |
||||||
|
os_ << ':'; space(); |
||||||
|
output( Config_type::get_value( member ) ); |
||||||
|
} |
||||||
|
|
||||||
|
void output_int( const Value_type& value ) |
||||||
|
{ |
||||||
|
if( value.is_uint64() ) |
||||||
|
{ |
||||||
|
os_ << value.get_uint64(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
os_ << value.get_int64(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void output( const String_type& s ) |
||||||
|
{ |
||||||
|
os_ << '"' << add_esc_chars( s ) << '"'; |
||||||
|
} |
||||||
|
|
||||||
|
void output( bool b ) |
||||||
|
{ |
||||||
|
os_ << to_str< String_type >( b ? "true" : "false" ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class T > |
||||||
|
void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) |
||||||
|
{ |
||||||
|
os_ << start_char; new_line(); |
||||||
|
|
||||||
|
++indentation_level_; |
||||||
|
|
||||||
|
for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) |
||||||
|
{ |
||||||
|
indent(); output( *i ); |
||||||
|
|
||||||
|
typename T::const_iterator next = i; |
||||||
|
|
||||||
|
if( ++next != t.end()) |
||||||
|
{ |
||||||
|
os_ << ','; |
||||||
|
} |
||||||
|
|
||||||
|
new_line(); |
||||||
|
} |
||||||
|
|
||||||
|
--indentation_level_; |
||||||
|
|
||||||
|
indent(); os_ << end_char; |
||||||
|
} |
||||||
|
|
||||||
|
void indent() |
||||||
|
{ |
||||||
|
if( !pretty_ ) return; |
||||||
|
|
||||||
|
for( int i = 0; i < indentation_level_; ++i ) |
||||||
|
{ |
||||||
|
os_ << " "; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void space() |
||||||
|
{ |
||||||
|
if( pretty_ ) os_ << ' '; |
||||||
|
} |
||||||
|
|
||||||
|
void new_line() |
||||||
|
{ |
||||||
|
if( pretty_ ) os_ << '\n'; |
||||||
|
} |
||||||
|
|
||||||
|
Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
|
||||||
|
|
||||||
|
Ostream_type& os_; |
||||||
|
int indentation_level_; |
||||||
|
bool pretty_; |
||||||
|
}; |
||||||
|
|
||||||
|
template< class Value_type, class Ostream_type > |
||||||
|
void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) |
||||||
|
{ |
||||||
|
Generator< Value_type, Ostream_type >( value, os, pretty ); |
||||||
|
} |
||||||
|
|
||||||
|
template< class Value_type > |
||||||
|
typename Value_type::String_type write_string( const Value_type& value, bool pretty ) |
||||||
|
{ |
||||||
|
typedef typename Value_type::String_type::value_type Char_type; |
||||||
|
|
||||||
|
std::basic_ostringstream< Char_type > os; |
||||||
|
|
||||||
|
write_stream( value, os, pretty ); |
||||||
|
|
||||||
|
return os.str(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue