json_spirit_v4_05/0000755000000000000000000000000011634366260013043 5ustar rootrootjson_spirit_v4_05/README.cmake0000644000000000000000000000107311202064724014772 0ustar rootrootFor using the cmake build system do the following steps: 1. Install cmake (under Ubuntu with "sudo apt-get install cmake", on Mac OS X with "sudo port install cmake") 2. Create an build dir (for example json_spirit_v3.00/build) an switch to this new directory. 3. Create files for your build system "cmake .." generates makefiles for GNU automake "cmake -G Xcode" generates an Xcode project 4. Start the build BOOST_ROOT Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers. json_spirit_v4_05/json.sln0000644000000000000000000000632311315737322014533 0ustar rootroot Microsoft Visual Studio Solution File, Format Version 9.00 # Visual C++ Express 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json_test", "json_test\json_test.vcproj", "{2DA49050-32A7-49D4-AF55-9BEE2BDDF889}" ProjectSection(ProjectDependencies) = postProject {BE262A86-CC26-4B25-A877-883ED2688CEC} = {BE262A86-CC26-4B25-A877-883ED2688CEC} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json_map_demo", "json_map_demo\json_map_demo.vcproj", "{07D8AA9F-D637-45A2-B06C-FF741462EAE8}" ProjectSection(ProjectDependencies) = postProject {BE262A86-CC26-4B25-A877-883ED2688CEC} = {BE262A86-CC26-4B25-A877-883ED2688CEC} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json_spirit_lib", "json_spirit\json_spirit.vcproj", "{BE262A86-CC26-4B25-A877-883ED2688CEC}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json_demo", "json_demo\json_demo.vcproj", "{EFA1226E-A818-481B-A094-93A22D68130C}" ProjectSection(ProjectDependencies) = postProject {BE262A86-CC26-4B25-A877-883ED2688CEC} = {BE262A86-CC26-4B25-A877-883ED2688CEC} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json_headers_only_demo", "json_headers_only_demo\json_headers_only_demo.vcproj", "{4F019AE5-7DB7-460D-A64A-BBC8E7CF3AA3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2DA49050-32A7-49D4-AF55-9BEE2BDDF889}.Debug|Win32.ActiveCfg = Debug|Win32 {2DA49050-32A7-49D4-AF55-9BEE2BDDF889}.Debug|Win32.Build.0 = Debug|Win32 {2DA49050-32A7-49D4-AF55-9BEE2BDDF889}.Release|Win32.ActiveCfg = Release|Win32 {2DA49050-32A7-49D4-AF55-9BEE2BDDF889}.Release|Win32.Build.0 = Release|Win32 {07D8AA9F-D637-45A2-B06C-FF741462EAE8}.Debug|Win32.ActiveCfg = Debug|Win32 {07D8AA9F-D637-45A2-B06C-FF741462EAE8}.Debug|Win32.Build.0 = Debug|Win32 {07D8AA9F-D637-45A2-B06C-FF741462EAE8}.Release|Win32.ActiveCfg = Release|Win32 {07D8AA9F-D637-45A2-B06C-FF741462EAE8}.Release|Win32.Build.0 = Release|Win32 {BE262A86-CC26-4B25-A877-883ED2688CEC}.Debug|Win32.ActiveCfg = Debug|Win32 {BE262A86-CC26-4B25-A877-883ED2688CEC}.Debug|Win32.Build.0 = Debug|Win32 {BE262A86-CC26-4B25-A877-883ED2688CEC}.Release|Win32.ActiveCfg = Release|Win32 {BE262A86-CC26-4B25-A877-883ED2688CEC}.Release|Win32.Build.0 = Release|Win32 {EFA1226E-A818-481B-A094-93A22D68130C}.Debug|Win32.ActiveCfg = Debug|Win32 {EFA1226E-A818-481B-A094-93A22D68130C}.Debug|Win32.Build.0 = Debug|Win32 {EFA1226E-A818-481B-A094-93A22D68130C}.Release|Win32.ActiveCfg = Release|Win32 {EFA1226E-A818-481B-A094-93A22D68130C}.Release|Win32.Build.0 = Release|Win32 {4F019AE5-7DB7-460D-A64A-BBC8E7CF3AA3}.Debug|Win32.ActiveCfg = Debug|Win32 {4F019AE5-7DB7-460D-A64A-BBC8E7CF3AA3}.Debug|Win32.Build.0 = Debug|Win32 {4F019AE5-7DB7-460D-A64A-BBC8E7CF3AA3}.Release|Win32.ActiveCfg = Release|Win32 {4F019AE5-7DB7-460D-A64A-BBC8E7CF3AA3}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal json_spirit_v4_05/json_map_demo/0000755000000000000000000000000011634366260015655 5ustar rootrootjson_spirit_v4_05/json_map_demo/json_map_demo.vcproj0000644000000000000000000000743611313750272021720 0ustar rootroot json_spirit_v4_05/json_map_demo/json_map_demo.cpp0000644000000000000000000000671411616562300021174 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 // This demo shows you how to read and write JSON objects and arrays. // In this demo objects are stored as a map of names to values. #include "json_spirit.h" #include #include #ifndef JSON_SPIRIT_MVALUE_ENABLED #error Please define JSON_SPIRIT_MVALUE_ENABLED for the mValue type to be enabled #endif using namespace std; using namespace json_spirit; struct Address { int house_number_; string road_; string town_; string county_; string country_; }; bool operator==( const Address& a1, const Address& a2 ) { return ( a1.house_number_ == a2.house_number_ ) && ( a1.road_ == a2.road_ ) && ( a1.town_ == a2.town_ ) && ( a1.county_ == a2.county_ ) && ( a1.country_ == a2.country_ ); } void write_address( mArray& a, const Address& addr ) { mObject addr_obj; addr_obj[ "house_number" ] = addr.house_number_; addr_obj[ "road" ] = addr.road_; addr_obj[ "town" ] = addr.town_; addr_obj[ "county" ] = addr.county_; addr_obj[ "country" ] = addr.country_; a.push_back( addr_obj ); } const mValue& find_value( const mObject& obj, const string& name ) { mObject::const_iterator i = obj.find( name ); assert( i != obj.end() ); assert( i->first == name ); return i->second; } Address read_address( const mObject& obj ) { Address addr; addr.house_number_ = find_value( obj, "house_number" ).get_int(); addr.road_ = find_value( obj, "road" ).get_str(); addr.town_ = find_value( obj, "town" ).get_str(); addr.county_ = find_value( obj, "county" ).get_str(); addr.country_ = find_value( obj, "country" ).get_str(); return addr; } void write_addrs( const char* file_name, const Address addrs[] ) { mArray addr_array; for( int i = 0; i < 5; ++i ) { write_address( addr_array, addrs[i] ); } ofstream os( file_name ); write_formatted( addr_array, os ); os.close(); } vector< Address > read_addrs( const char* file_name ) { ifstream is( file_name ); mValue value; read( is, value ); const mArray& addr_array = value.get_array(); vector< Address > addrs; for( vector< Address >::size_type i = 0; i < addr_array.size(); ++i ) { addrs.push_back( read_address( addr_array[i].get_obj() ) ); } return addrs; } int main() { const Address addrs[5] = { { 42, "East Street", "Newtown", "Essex", "England" }, { 1, "West Street", "Hull", "Yorkshire", "England" }, { 12, "South Road", "Aberystwyth", "Dyfed", "Wales" }, { 45, "North Road", "Paignton", "Devon", "England" }, { 78, "Upper Street", "Ware", "Hertfordshire", "England" } }; const char* file_name( "demo.txt" ); write_addrs( file_name, addrs ); vector< Address > new_addrs = read_addrs( file_name ); assert( new_addrs.size() == 5 ); for( int i = 0; i < 5; ++i ) { assert( new_addrs[i] == addrs[i] ); } return 0; } ;json_spirit_v4_05/json_map_demo/CMakeLists.txt0000644000000000000000000000034711321706214020407 0ustar rootrootSET(JSON_MAP_DEMO_SRCS json_map_demo.cpp) FIND_PACKAGE(Boost 1.34 REQUIRED) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) ADD_EXECUTABLE(json_map_demo ${JSON_MAP_DEMO_SRCS}) TARGET_LINK_LIBRARIES(json_map_demo json_spirit) json_spirit_v4_05/json_map_demo/demo.txt0000644000000000000000000000151511213470260017331 0ustar rootroot[ { "country" : "England", "county" : "Essex", "house_number" : 42, "road" : "East Street", "town" : "Newtown" }, { "country" : "England", "county" : "Yorkshire", "house_number" : 1, "road" : "West Street", "town" : "Hull" }, { "country" : "Wales", "county" : "Dyfed", "house_number" : 12, "road" : "South Road", "town" : "Aberystwyth" }, { "country" : "England", "county" : "Devon", "house_number" : 45, "road" : "North Road", "town" : "Paignton" }, { "country" : "England", "county" : "Hertfordshire", "house_number" : 78, "road" : "Upper Street", "town" : "Ware" } ]json_spirit_v4_05/json_spirit/0000755000000000000000000000000011634366260015406 5ustar rootrootjson_spirit_v4_05/json_spirit/json_spirit.vcproj0000644000000000000000000001030011570762564021176 0ustar rootroot json_spirit_v4_05/json_spirit/json_spirit_writer.h0000644000000000000000000000447411616562300021520 0ustar rootroot#ifndef JSON_SPIRIT_WRITER #define JSON_SPIRIT_WRITER // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include "json_spirit_value.h" #include "json_spirit_writer_options.h" #include namespace json_spirit { // these functions to convert JSON Values to text #ifdef JSON_SPIRIT_VALUE_ENABLED void write( const Value& value, std::ostream& os, unsigned int options = 0 ); std::string write( const Value& value, unsigned int options = 0 ); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED void write( const mValue& value, std::ostream& os, unsigned int options = 0 ); std::string write( const mValue& value, unsigned int options = 0 ); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void write( const wValue& value, std::wostream& os, unsigned int options = 0 ); std::wstring write( const wValue& value, unsigned int options = 0 ); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void write( const wmValue& value, std::wostream& os, unsigned int options = 0 ); std::wstring write( const wmValue& value, unsigned int options = 0 ); #endif // these "formatted" versions of the "write" functions are the equivalent of the above functions // with option "pretty_print" #ifdef JSON_SPIRIT_VALUE_ENABLED void write_formatted( const Value& value, std::ostream& os ); std::string write_formatted( const Value& value ); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED void write_formatted( const mValue& value, std::ostream& os ); std::string write_formatted( const mValue& value ); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void write_formatted( const wValue& value, std::wostream& os ); std::wstring write_formatted( const wValue& value ); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void write_formatted( const wmValue& value, std::wostream& os ); std::wstring write_formatted( const wmValue& value ); #endif } #endif json_spirit_v4_05/json_spirit/json_spirit_reader.h0000644000000000000000000000501311616561604021442 0ustar rootroot#ifndef JSON_SPIRIT_READER #define JSON_SPIRIT_READER // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include "json_spirit_value.h" #include "json_spirit_error_position.h" #include namespace json_spirit { // functions to reads a JSON values #ifdef JSON_SPIRIT_VALUE_ENABLED 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 ); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( 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 #ifdef JSON_SPIRIT_MVALUE_ENABLED 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 ); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( 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 json_spirit_v4_05/json_spirit/json_spirit_reader_template.h0000644000000000000000000005204211616562300023333 0ustar rootroot#ifndef JSON_SPIRIT_READER_TEMPLATE #define JSON_SPIRIT_READER_TEMPLATE // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #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 #include #include #if BOOST_VERSION >= 103800 #include #include #include #include #include #define spirit_namespace boost::spirit::classic #else #include #include #include #include #include #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 > 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 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_; }; // reads a JSON Value from a pair of input iterators throwing an exception on invalid input, e.g. // // string::const_iterator start = str.begin(); // const string::const_iterator next = read_range_or_throw( str.begin(), str.end(), value ); // // The iterator 'next' will point to the character past the // last one read. // 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; } // reads a JSON Value from a pair of input iterators, e.g. // // string::const_iterator start = str.begin(); // const bool success = read_string( start, str.end(), value ); // // The iterator 'start' will point to the character past the // last one read. // 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; } } // reads a JSON Value from a string, e.g. // // const bool success = read_string( str, 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 ); } // reads a JSON Value from a string throwing an exception on invalid input, e.g. // // read_string_or_throw( is, value ); // 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 ); } // reads a JSON Value from a stream, e.g. // // const bool success = read_stream( is, value ); // 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 ); } // reads a JSON Value from a stream throwing an exception on invalid input, e.g. // // read_stream_or_throw( is, 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 json_spirit_v4_05/json_spirit/json_spirit_value.h0000644000000000000000000003771311616562300021322 0ustar rootroot#ifndef JSON_SPIRIT_VALUE #define JSON_SPIRIT_VALUE // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include #include #include #include #include #include #include #include #include #include // comment out the value types you don't need to reduce build times and intermediate file sizes #define JSON_SPIRIT_VALUE_ENABLED #define JSON_SPIRIT_WVALUE_ENABLED #define JSON_SPIRIT_MVALUE_ENABLED #define JSON_SPIRIT_WMVALUE_ENABLED namespace json_spirit { enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; struct Null{}; 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 ); template< class Iter > Value_impl( Iter first, Iter last ); // constructor from containers, e.g. std::vector or std::list template< BOOST_VARIANT_ENUM_PARAMS( typename T ) > Value_impl( const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& variant ); // constructor for compatible variant types 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< boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, String_type, bool, boost::int64_t, double, Null, boost::uint64_t > Variant; Variant v_; class Variant_converter_visitor : public boost::static_visitor< Variant > { public: template< typename T, typename A, template< typename, typename > class Cont > Variant operator()( const Cont< T, A >& cont ) const { return Array( cont.begin(), cont.end() ); } Variant operator()( int i ) const { return static_cast< boost::int64_t >( i ); } template Variant operator()( const T& t ) const { return t; } }; }; // vector objects template< class Config > struct Pair_impl { typedef typename Config::String_type String_type; typedef typename Config::Value_type Value_type; Pair_impl() { } Pair_impl( const String_type& name, const Value_type& value ); bool operator==( const Pair_impl& lhs ) const; String_type name_; Value_type value_; }; #if defined( JSON_SPIRIT_VALUE_ENABLED ) || defined( JSON_SPIRIT_WVALUE_ENABLED ) 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_; } }; #endif // typedefs for ASCII #ifdef JSON_SPIRIT_VALUE_ENABLED 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; #endif // typedefs for Unicode #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( 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 #if defined( JSON_SPIRIT_MVALUE_ENABLED ) || defined( JSON_SPIRIT_WMVALUE_ENABLED ) 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 std::pair< String_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; } }; #endif // typedefs for ASCII #ifdef JSON_SPIRIT_MVALUE_ENABLED typedef Config_map< std::string > mConfig; typedef mConfig::Value_type mValue; typedef mConfig::Object_type mObject; typedef mConfig::Array_type mArray; #endif // typedefs for Unicode #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( 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 inline bool operator==( const Null&, const Null& ) { return true; } template< class Config > const Value_impl< Config > Value_impl< Config >::null; template< class Config > Value_impl< Config >::Value_impl() : v_( Null() ) { } template< class Config > Value_impl< Config >::Value_impl( const Const_str_ptr value ) : v_( String_type( value ) ) { } template< class Config > Value_impl< Config >::Value_impl( const String_type& value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Object& value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Array& value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( bool value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( int value ) : v_( static_cast< boost::int64_t >( value ) ) { } template< class Config > Value_impl< Config >::Value_impl( boost::int64_t value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( boost::uint64_t value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( double value ) : v_( value ) { } template< class Config > Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) : v_( other.v_ ) { } template< class Config > template< class Iter > Value_impl< Config >::Value_impl( Iter first, Iter last ) : v_( Array( first, last ) ) { } template< class Config > template< BOOST_VARIANT_ENUM_PARAMS( typename T ) > Value_impl< Config >::Value_impl( const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& variant ) : v_( boost::apply_visitor( Variant_converter_visitor(), variant) ) { } template< class Config > Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) { Value_impl tmp( lhs ); std::swap( v_, tmp.v_ ); 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 { if( is_uint64() ) { return int_type; } return static_cast< Value_type >( v_.which() ); } template< class Config > bool Value_impl< Config >::is_uint64() const { return v_.which() == null_type + 1; } 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 ); if( is_uint64() ) { return static_cast< boost::int64_t >( get_uint64() ); } return boost::get< boost::int64_t >( v_ ); } template< class Config > boost::uint64_t Value_impl< Config >::get_uint64() const { check_type( int_type ); if( !is_uint64() ) { return static_cast< boost::uint64_t >( get_int64() ); } return boost::get< boost::uint64_t >( v_ ); } 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 json_spirit_v4_05/json_spirit/json_spirit_writer_options.h0000644000000000000000000000253311616562300023265 0ustar rootroot#ifndef JSON_SPIRIT_WRITER_OPTIONS #define JSON_SPIRIT_WRITER_OPTIONS // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { enum Output_options{ pretty_print = 0x01, // Add whitespace to format the output nicely. raw_utf8 = 0x02, // This prevents non-printable characters from being escapted using "\uNNNN" notation. // Note, this is an extension to the JSON standard. It disables the escaping of // non-printable characters allowing UTF-8 sequences held in 8 bit char strings // to pass through unaltered. remove_trailing_zeros = 0x04, // outputs e.g. "1.200000000000000" as "1.2" single_line_arrays = 0x08, // pretty printing except that arrays printed on single lines unless they contain // composite elements, i.e. objects or arrays }; } #endif json_spirit_v4_05/json_spirit/json_spirit_writer_template.h0000644000000000000000000002576611632723102023417 0ustar rootroot#ifndef JSON_SPIRIT_WRITER_TEMPLATE #define JSON_SPIRIT_WRITER_TEMPLATE // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include "json_spirit_value.h" #include "json_spirit_writer_options.h" #include #include #include #include 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, bool raw_utf8 ) { 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; if( raw_utf8 ) { result += c; } else { 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; } template< class Ostream > void append_double( Ostream& os, const double d, const int precision ) { os << std::showpoint << std::setprecision( precision ) << d; } template< class String_type > void erase_and_extract_exponent( String_type& str, String_type& exp ) { const typename String_type::size_type exp_start= str.find( 'e' ); if( exp_start != String_type::npos ) { exp = str.substr( exp_start ); str.erase( exp_start ); } } template< class String_type > typename String_type::size_type find_first_non_zero( const String_type& str ) { typename String_type::size_type result = str.size() - 1; for( ; result != 0; --result ) { if( str[ result ] != '0' ) { break; } } return result; } template< class String_type > void remove_trailing( String_type& str ) { String_type exp; erase_and_extract_exponent( str, exp ); const typename String_type::size_type first_non_zero = find_first_non_zero( str ); if( first_non_zero != 0 ) { const int offset = str[first_non_zero] == '.' ? 2 : 1; // note zero digits following a decimal point is non standard str.erase( first_non_zero + offset ); } str += exp; } // 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, unsigned int options ) : os_( os ) , indentation_level_( 0 ) , pretty_( ( options & pretty_print ) != 0 || ( options & single_line_arrays ) != 0 ) , raw_utf8_( ( options & raw_utf8 ) != 0 ) , remove_trailing_zeros_( ( options & remove_trailing_zeros ) != 0 ) , single_line_arrays_( ( options & single_line_arrays ) != 0 ) , ios_saver_( os ) { 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 real_type: output( value.get_real() ); break; case int_type: output_int( value ); break; case null_type: os_ << "null"; break; default: assert( false ); } } void output( const Object_type& obj ) { output_array_or_obj( obj, '{', '}' ); } 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, raw_utf8_ ) << '"'; } void output( bool b ) { os_ << to_str< String_type >( b ? "true" : "false" ); } void output( double d ) { if( remove_trailing_zeros_ ) { std::basic_ostringstream< Char_type > os; append_double( os, d, 16 ); // note precision is 16 so that we get some trailing space that we can remove, // otherwise, 0.1234 gets converted to "0.12399999..." String_type str = os.str(); remove_trailing( str ); os_ << str; } else { append_double( os_, d, 17 ); } } static bool contains_composite_elements( const Array_type& arr ) { for( typename Array_type::const_iterator i = arr.begin(); i != arr.end(); ++i ) { const Value_type& val = *i; if( val.type() == obj_type || val.type() == array_type ) { return true; } } return false; } template< class Iter > void output_composite_item( Iter i, Iter last ) { output( *i ); if( ++i != last ) { os_ << ','; } } void output( const Array_type& arr ) { if( single_line_arrays_ && !contains_composite_elements( arr ) ) { os_ << '['; space(); for( typename Array_type::const_iterator i = arr.begin(); i != arr.end(); ++i ) { output_composite_item( i, arr.end() ); space(); } os_ << ']'; } else { output_array_or_obj( arr, '[', ']' ); } } 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_composite_item( i, t.end() ); 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_; bool raw_utf8_; bool remove_trailing_zeros_; bool single_line_arrays_; boost::io::basic_ios_all_saver< Char_type > ios_saver_; // so that ostream state is reset after control is returned to the caller }; // writes JSON Value to a stream, e.g. // // write_stream( value, os, pretty_print ); // template< class Value_type, class Ostream_type > void write_stream( const Value_type& value, Ostream_type& os, unsigned int options = 0 ) { os << std::dec; Generator< Value_type, Ostream_type >( value, os, options ); } // writes JSON Value to a stream, e.g. // // const string json_str = write( value, pretty_print ); // template< class Value_type > typename Value_type::String_type write_string( const Value_type& value, unsigned int options = 0 ) { typedef typename Value_type::String_type::value_type Char_type; std::basic_ostringstream< Char_type > os; write_stream( value, os, options ); return os.str(); } } #endif json_spirit_v4_05/json_spirit/json_spirit_utils.h0000644000000000000000000000325311616562300021336 0ustar rootroot#ifndef JSON_SPIRIT_UTILS #define JSON_SPIRIT_UTILS // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include "json_spirit_value.h" #include 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 ) ); } } #ifdef JSON_SPIRIT_VALUE_ENABLED typedef std::map< std::string, Value > Mapped_obj; #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( 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 json_spirit_v4_05/json_spirit/json_spirit_error_position.h0000644000000000000000000000275311616562300023257 0ustar rootroot#ifndef JSON_SPIRIT_ERROR_POSITION #define JSON_SPIRIT_ERROR_POSITION // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include 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 json_spirit_v4_05/json_spirit/json_spirit_value.cpp0000644000000000000000000000031011122257530021632 0ustar rootroot/* 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" json_spirit_v4_05/json_spirit/json_spirit_stream_reader.h0000644000000000000000000000340211616562300023007 0ustar rootroot#ifndef JSON_SPIRIT_READ_STREAM #define JSON_SPIRIT_READ_STREAM // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #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 json_spirit_v4_05/json_spirit/CMakeLists.txt0000644000000000000000000000074211617557616020161 0ustar rootrootSET(JSON_SPIRIT_SRCS json_spirit_reader.cpp json_spirit_reader.h json_spirit_value.cpp json_spirit_value.h json_spirit_writer.cpp json_spirit_writer.h json_spirit.h json_spirit_error_position.h json_spirit_reader_template.h json_spirit_stream_reader.h json_spirit_utils.h json_spirit_writer_options.h json_spirit_writer_template.h ) FIND_PACKAGE(Boost 1.34 REQUIRED) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS}) json_spirit_v4_05/json_spirit/json_spirit.h0000644000000000000000000000063511616562300020117 0ustar rootroot#ifndef JSON_SPIRIT #define JSON_SPIRIT // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #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 json_spirit_v4_05/json_spirit/json_spirit_writer.cpp0000644000000000000000000000545411616562300022052 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_writer.h" #include "json_spirit_writer_template.h" using namespace json_spirit; #ifdef JSON_SPIRIT_VALUE_ENABLED void json_spirit::write( const Value& value, std::ostream& os, unsigned int options ) { write_stream( value, os, options ); } std::string json_spirit::write( const Value& value, unsigned int options ) { return write_string( value, options ); } void json_spirit::write_formatted( const Value& value, std::ostream& os ) { write_stream( value, os, pretty_print ); } std::string json_spirit::write_formatted( const Value& value ) { return write_string( value, pretty_print ); } #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED void json_spirit::write( const mValue& value, std::ostream& os, unsigned int options ) { write_stream( value, os, options ); } std::string json_spirit::write( const mValue& value, unsigned int options ) { return write_string( value, options ); } void json_spirit::write_formatted( const mValue& value, std::ostream& os ) { write_stream( value, os, pretty_print ); } std::string json_spirit::write_formatted( const mValue& value ) { return write_string( value, pretty_print ); } #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void json_spirit::write( const wValue& value, std::wostream& os, unsigned int options ) { write_stream( value, os, options ); } std::wstring json_spirit::write( const wValue& value, unsigned int options ) { return write_string( value, options ); } void json_spirit::write_formatted( const wValue& value, std::wostream& os ) { write_stream( value, os, pretty_print ); } std::wstring json_spirit::write_formatted( const wValue& value ) { return write_string( value, pretty_print ); } #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) { write_stream( value, os, pretty_print ); } std::wstring json_spirit::write_formatted( const wmValue& value ) { return write_string( value, pretty_print ); } void json_spirit::write( const wmValue& value, std::wostream& os, unsigned int options ) { write_stream( value, os, options ); } std::wstring json_spirit::write( const wmValue& value, unsigned int options ) { return write_string( value, options ); } #endif json_spirit_v4_05/json_spirit/json_spirit_reader.cpp0000644000000000000000000001001211616562300021762 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_reader.h" #include "json_spirit_reader_template.h" using namespace json_spirit; #ifdef JSON_SPIRIT_VALUE_ENABLED 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 ); } #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( 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 #ifdef JSON_SPIRIT_MVALUE_ENABLED 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 ); } #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( 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 json_spirit_v4_05/json_test/0000755000000000000000000000000011634366260015053 5ustar rootrootjson_spirit_v4_05/json_test/json_spirit_stream_reader_test.h0000644000000000000000000000057611616562300023524 0ustar rootroot#ifndef JSON_SPIRIT_STREAM_READER_TEST #define JSON_SPIRIT_STREAM_READER_TEST // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { void test_stream_reader(); } #endif json_spirit_v4_05/json_test/json_spirit_reader_test.h0000644000000000000000000000055111616562300022142 0ustar rootroot#ifndef JSON_SPIRIT_READER_TEST #define JSON_SPIRIT_READER_TEST // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { void test_reader(); } #endif json_spirit_v4_05/json_test/test.txt0000644000000000000000000000675511122257530016577 0ustar rootroot[[["Field_1_0", "Field_2_0"], ["Field_1_1", "Field_2_1"], ["Field_1_2", "Field_2_2"], ["Field_1_3", "Field_2_3"], ["Field_1_4", "Field_2_4"], ["Field_1_5", "Field_2_5"], ["Field_1_6", "Field_2_6"], ["Field_1_7", "Field_2_7"], ["Field_1_8", "Field_2_8"], ["Field_1_9", "Field_2_9"], ["Field_1_10", "Field_2_10"], ["Field_1_11", "Field_2_11"], ["Field_1_12", "Field_2_12"], ["Field_1_13", "Field_2_13"], ["Field_1_14", "Field_2_14"], ["Field_1_15", "Field_2_15"], ["Field_1_16", "Field_2_16"], ["Field_1_17", "Field_2_17"], ["Field_1_18", "Field_2_18"], ["Field_1_19", "Field_2_19"], ["Field_1_20", "Field_2_20"], ["Field_1_21", "Field_2_21"], ["Field_1_22", "Field_2_22"], ["Field_1_23", "Field_2_23"], ["Field_1_24", "Field_2_24"], ["Field_1_25", "Field_2_25"], ["Field_1_26", "Field_2_26"], ["Field_1_27", "Field_2_27"], ["Field_1_28", "Field_2_28"], ["Field_1_29", "Field_2_29"], ["Field_1_30", "Field_2_30"], ["Field_1_31", "Field_2_31"], ["Field_1_32", "Field_2_32"], ["Field_1_33", "Field_2_33"], ["Field_1_34", "Field_2_34"], ["Field_1_35", "Field_2_35"], ["Field_1_36", "Field_2_36"], ["Field_1_37", "Field_2_37"], ["Field_1_38", "Field_2_38"], ["Field_1_39", "Field_2_39"], ["Field_1_40", "Field_2_40"], ["Field_1_41", "Field_2_41"], ["Field_1_42", "Field_2_42"], ["Field_1_43", "Field_2_43"], ["Field_1_44", "Field_2_44"], ["Field_1_45", "Field_2_45"], ["Field_1_46", "Field_2_46"], ["Field_1_47", "Field_2_47"], ["Field_1_48", "Field_2_48"], ["Field_1_49", "Field_2_49"], ["Field_1_50", "Field_2_50"], ["Field_1_51", "Field_2_51"], ["Field_1_52", "Field_2_52"], ["Field_1_53", "Field_2_53"], ["Field_1_54", "Field_2_54"], ["Field_1_55", "Field_2_55"], ["Field_1_56", "Field_2_56"], ["Field_1_57", "Field_2_57"], ["Field_1_58", "Field_2_58"], ["Field_1_59", "Field_2_59"]],[["Field_1_0", "Field_2_0"], ["Field_1_1", "Field_2_1"], ["Field_1_2", "Field_2_2"], ["Field_1_3", "Field_2_3"], ["Field_1_4", "Field_2_4"], ["Field_1_5", "Field_2_5"], ["Field_1_6", "Field_2_6"], ["Field_1_7", "Field_2_7"], ["Field_1_8", "Field_2_8"], ["Field_1_9", "Field_2_9"], ["Field_1_10", "Field_2_10"], ["Field_1_11", "Field_2_11"], ["Field_1_12", "Field_2_12"], ["Field_1_13", "Field_2_13"], ["Field_1_14", "Field_2_14"], ["Field_1_15", "Field_2_15"], ["Field_1_16", "Field_2_16"], ["Field_1_17", "Field_2_17"], ["Field_1_18", "Field_2_18"], ["Field_1_19", "Field_2_19"], ["Field_1_20", "Field_2_20"], ["Field_1_21", "Field_2_21"], ["Field_1_22", "Field_2_22"], ["Field_1_23", "Field_2_23"], ["Field_1_24", "Field_2_24"], ["Field_1_25", "Field_2_25"], ["Field_1_26", "Field_2_26"], ["Field_1_27", "Field_2_27"], ["Field_1_28", "Field_2_28"], ["Field_1_29", "Field_2_29"], ["Field_1_30", "Field_2_30"], ["Field_1_31", "Field_2_31"], ["Field_1_32", "Field_2_32"], ["Field_1_33", "Field_2_33"], ["Field_1_34", "Field_2_34"], ["Field_1_35", "Field_2_35"], ["Field_1_36", "Field_2_36"], ["Field_1_37", "Field_2_37"], ["Field_1_38", "Field_2_38"], ["Field_1_39", "Field_2_39"], ["Field_1_40", "Field_2_40"], ["Field_1_41", "Field_2_41"], ["Field_1_42", "Field_2_42"], ["Field_1_43", "Field_2_43"], ["Field_1_44", "Field_2_44"], ["Field_1_45", "Field_2_45"], ["Field_1_46", "Field_2_46"], ["Field_1_47", "Field_2_47"], ["Field_1_48", "Field_2_48"], ["Field_1_49", "Field_2_49"], ["Field_1_50", "Field_2_50"], ["Field_1_51", "Field_2_51"], ["Field_1_52", "Field_2_52"], ["Field_1_53", "Field_2_53"], ["Field_1_54", "Field_2_54"], ["Field_1_55", "Field_2_55"], ["Field_1_56", "Field_2_56"], ["Field_1_57", "Field_2_57"], ["Field_1_58", "Field_2_58"], ["Field_1_59", "Field_2_59"]]] json_spirit_v4_05/json_test/json_test.vcproj0000644000000000000000000001212311517354356020312 0ustar rootroot json_spirit_v4_05/json_test/json_test.cpp0000644000000000000000000000131411616562300017557 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_value_test.h" #include "json_spirit_writer_test.h" #include "json_spirit_reader_test.h" #include "json_spirit_stream_reader_test.h" #include "json_spirit_utils_test.h" #include #include using namespace std; using namespace json_spirit; int main() { test_value(); test_writer(); test_reader(); test_stream_reader(); test_utils(); cout << "all tests passed" << endl << endl; cout << "press any key to continue"; string s; cin >> s; return 0; } json_spirit_v4_05/json_test/json_spirit_writer_test.h0000644000000000000000000000055111616562300022214 0ustar rootroot#ifndef JSON_SPIRIT_WRITER_TEST #define JSON_SPIRIT_WRITER_TEST // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { void test_writer(); } #endif json_spirit_v4_05/json_test/json_spirit_writer_test.cpp0000644000000000000000000006356211632723102022557 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_writer_test.h" #include "utils_test.h" #include "json_spirit_writer.h" #include "json_spirit_value.h" #include #include using namespace json_spirit; using namespace std; using namespace boost; namespace { const int64_t max_int64 = integer_traits< int64_t >::max(); const uint64_t max_uint64 = integer_traits< uint64_t >::max(); template< class Config_type > struct Test_runner { 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 Config_type::Value_type Value_type; typedef typename String_type::value_type Char_type; typedef typename String_type::const_iterator Iter_type; typedef std::basic_ostream< Char_type > Ostream_type; String_type to_str( const char* c_str ) { return ::to_str< String_type >( c_str ); } String_type zero_str() { #ifdef WIN32 return to_str( "0.00000000000000000" ); #else return to_str( "0.0000000000000000" ); #endif } void add_value( Object_type& obj, const char* c_name, const Value_type& value ) { Config_type::add( obj, to_str( c_name ), value ); } void add_c_str( Object_type& obj, const char* c_name, const char* c_value ) { add_value( obj, c_name, to_str( c_value ) ); } void check_eq( const Value_type& value, const String_type& expected_result ) { assert_eq( write( value ), expected_result ); } void check_eq( const Value_type& value, const char* expected_result ) { check_eq( value, to_str( expected_result ) ); } void check_eq_pretty( const Value_type& value, const char* expected_result ) { assert_eq( write_formatted( value ), to_str( expected_result ) ); assert_eq( write( value, pretty_print ), to_str( expected_result ) ); } void check_eq_single_line_arrays( const Value_type& value, const char* expected_result ) { assert_eq( write( value, single_line_arrays ), to_str( expected_result ) ); } void check_eq( const Value_type& value, const String_type& expected_result , unsigned int options ) { assert_eq( write( value, options ), expected_result ); } void check_eq( const Value_type& value, const char* expected_result, unsigned int options ) { check_eq( value, to_str( expected_result ), options ); } void test_empty_obj() { check_eq( Object_type(), "{}" ); check_eq_pretty( Object_type(), "{\n}" ); } void test_obj_with_one_member() { Object_type obj; add_c_str( obj, "name", "value" ); check_eq ( obj, "{\"name\":\"value\"}" ); check_eq_pretty( obj, "{\n" " \"name\" : \"value\"\n" "}" ); } void test_obj_with_two_members() { Object_type obj; add_c_str( obj, "name_1", "value_1" ); add_c_str( obj, "name_2", "value_2" ); check_eq( obj, "{\"name_1\":\"value_1\",\"name_2\":\"value_2\"}" ); check_eq_pretty( obj, "{\n" " \"name_1\" : \"value_1\",\n" " \"name_2\" : \"value_2\"\n" "}" ); } void test_obj_with_three_members() { Object_type obj; add_c_str( obj, "name_1", "value_1" ); add_c_str( obj, "name_2", "value_2" ); add_c_str( obj, "name_3", "value_3" ); check_eq( obj, "{\"name_1\":\"value_1\",\"name_2\":\"value_2\",\"name_3\":\"value_3\"}" ); check_eq_pretty( obj, "{\n" " \"name_1\" : \"value_1\",\n" " \"name_2\" : \"value_2\",\n" " \"name_3\" : \"value_3\"\n" "}" ); } void test_obj_with_one_empty_child_obj() { Object_type child; Object_type root; add_value( root, "child", child ); check_eq( root, "{\"child\":{}}" ); check_eq_pretty( root, "{\n" " \"child\" : {\n" " }\n" "}" ); } void test_obj_with_one_child_obj() { Object_type child; add_c_str( child, "name_2", "value_2" ); Object_type root; add_value( root, "child", child ); add_c_str( root, "name_1", "value_1" ); check_eq( root, "{\"child\":{\"name_2\":\"value_2\"},\"name_1\":\"value_1\"}" ); check_eq_pretty( root, "{\n" " \"child\" : {\n" " \"name_2\" : \"value_2\"\n" " },\n" " \"name_1\" : \"value_1\"\n" "}" ); } void test_obj_with_grandchild_obj() { Object_type child_1; add_c_str( child_1, "name_1", "value_1" ); Object_type child_2; Object_type child_3; add_c_str( child_3, "name_3", "value_3" ); add_value( child_2, "grandchild", child_3 ); add_c_str( child_2, "name_2", "value_2" ); Object_type root; add_value( root, "child_1", child_1 ); add_value( root, "child_2", child_2 ); add_c_str( root, "name_a", "value_a" ); add_c_str( root, "name_b", "value_b" ); check_eq( root, "{\"child_1\":{\"name_1\":\"value_1\"}," "\"child_2\":{\"grandchild\":{\"name_3\":\"value_3\"},\"name_2\":\"value_2\"}," "\"name_a\":\"value_a\"," "\"name_b\":\"value_b\"}" ); check_eq_pretty( root, "{\n" " \"child_1\" : {\n" " \"name_1\" : \"value_1\"\n" " },\n" " \"child_2\" : {\n" " \"grandchild\" : {\n" " \"name_3\" : \"value_3\"\n" " },\n" " \"name_2\" : \"value_2\"\n" " },\n" " \"name_a\" : \"value_a\",\n" " \"name_b\" : \"value_b\"\n" "}" ); } void test_objs_with_bool_pairs() { Object_type obj; add_value( obj, "name_1", true ); add_value( obj, "name_2", false ); add_value( obj, "name_3", true ); check_eq( obj, "{\"name_1\":true,\"name_2\":false,\"name_3\":true}" ); } void test_objs_with_int_pairs() { Object_type obj; add_value( obj, "name_1", 11 ); add_value( obj, "name_2", INT_MAX ); add_value( obj, "name_3", max_int64 ); ostringstream os; os << "{\"name_1\":11,\"name_2\":" << INT_MAX << ",\"name_3\":" << max_int64 << "}"; check_eq( obj, os.str().c_str() ); } void test_objs_with_real_pairs() { Object_type obj; add_value( obj, "name_1", 0.0 ); add_value( obj, "name_2", 1.234567890123456789e-108 ); add_value( obj, "name_3", -1234567890.123456789 ); add_value( obj, "name_4", -1.2e-126 ); check_eq( obj, to_str( "{\"name_1\":" ) + zero_str() + to_str( "," "\"name_2\":1.2345678901234567e-108," "\"name_3\":-1234567890.1234567," "\"name_4\":-1.2000000000000000e-126}" ) ); } void test_objs_with_null_pairs() { Object_type obj; add_value( obj, "name_1", Value_type::null ); add_value( obj, "name_2", Value_type::null ); add_value( obj, "name_3", Value_type::null ); check_eq( obj, "{\"name_1\":null,\"name_2\":null,\"name_3\":null}" ); } void test_empty_array() { check_eq( Array_type(), "[]" ); check_eq_pretty( Array_type(), "[\n" "]" ); check_eq_single_line_arrays( Array_type(), "[ ]" ); } void test_array_with_one_member() { Array_type arr; arr.push_back( to_str( "value" ) ); check_eq ( arr, "[\"value\"]" ); check_eq_pretty( arr, "[\n" " \"value\"\n" "]" ); check_eq_single_line_arrays( arr, "[ \"value\" ]" ); } void test_array_with_two_members() { Array_type arr; arr.push_back( to_str( "value_1" ) ); arr.push_back( 1 ); check_eq ( arr, "[\"value_1\",1]" ); check_eq_pretty( arr, "[\n" " \"value_1\",\n" " 1\n" "]" ); check_eq_single_line_arrays( arr, "[ \"value_1\", 1 ]" ); } void test_array_with_n_members() { Array_type arr; arr.push_back( to_str( "value_1" ) ); arr.push_back( 123 ); arr.push_back( 123.456 ); arr.push_back( true ); arr.push_back( false ); arr.push_back( Value_type() ); check_eq ( arr, "[\"value_1\",123,123.45600000000000,true,false,null]" ); check_eq_pretty( arr, "[\n" " \"value_1\",\n" " 123,\n" " 123.45600000000000,\n" " true,\n" " false,\n" " null\n" "]" ); check_eq_single_line_arrays( arr, "[ \"value_1\", 123, 123.45600000000000, true, false, null ]" ); } void test_array_with_one_empty_child_array() { Array_type arr; arr.push_back( Array_type() ); check_eq ( arr, "[[]]" ); check_eq_pretty( arr, "[\n" " [\n" " ]\n" "]" ); check_eq_single_line_arrays( arr, "[\n" " [ ]\n" "]" ); } void test_array_with_one_child_array() { Array_type child; child.push_back( 2 ); Array_type root; root.push_back( 1 ); root.push_back( child ); check_eq ( root, "[1,[2]]" ); check_eq_pretty( root, "[\n" " 1,\n" " [\n" " 2\n" " ]\n" "]" ); check_eq_single_line_arrays( root, "[\n" " 1,\n" " [ 2 ]\n" "]" ); } void test_array_with_grandchild_array() { Array_type child_1; child_1.push_back( 11 ); Array_type child_2; child_2.push_back( 22 ); Array_type child_3; child_3.push_back( 33 ); child_2.push_back( child_3 ); Array_type root; root.push_back( 1); root.push_back( child_1 ); root.push_back( child_2 ); root.push_back( 2 ); check_eq ( root, "[1,[11],[22,[33]],2]" ); check_eq_pretty( root, "[\n" " 1,\n" " [\n" " 11\n" " ],\n" " [\n" " 22,\n" " [\n" " 33\n" " ]\n" " ],\n" " 2\n" "]" ); check_eq_single_line_arrays( root, "[\n" " 1,\n" " [ 11 ],\n" " [\n" " 22,\n" " [ 33 ]\n" " ],\n" " 2\n" "]" ); } void test_array_and_objs() { Array_type a; a.push_back( 11 ); Object_type obj; add_value( obj, "a", 1 ); a.push_back( obj ); check_eq ( a, "[11,{\"a\":1}]" ); check_eq_pretty( a, "[\n" " 11,\n" " {\n" " \"a\" : 1\n" " }\n" "]" ); check_eq_single_line_arrays( a, "[\n" " 11,\n" " {\n" " \"a\" : 1\n" " }\n" "]" ); add_value( obj, "b", 2 ); a.push_back( 22 ); a.push_back( 33 ); a.push_back( obj ); check_eq ( a, "[11,{\"a\":1},22,33,{\"a\":1,\"b\":2}]" ); check_eq_pretty( a, "[\n" " 11,\n" " {\n" " \"a\" : 1\n" " },\n" " 22,\n" " 33,\n" " {\n" " \"a\" : 1,\n" " \"b\" : 2\n" " }\n" "]" ); check_eq_single_line_arrays( a, "[\n" " 11,\n" " {\n" " \"a\" : 1\n" " },\n" " 22,\n" " 33,\n" " {\n" " \"a\" : 1,\n" " \"b\" : 2\n" " }\n" "]" ); } void test_obj_and_arrays() { Object_type obj; add_value( obj, "a", 1 ); Array_type a; a.push_back( 11 ); a.push_back( 12 ); add_value( obj, "b", a ); check_eq ( obj, "{\"a\":1,\"b\":[11,12]}" ); check_eq_pretty( obj, "{\n" " \"a\" : 1,\n" " \"b\" : [\n" " 11,\n" " 12\n" " ]\n" "}" ); check_eq_single_line_arrays( obj, "{\n" " \"a\" : 1,\n" " \"b\" : [ 11, 12 ]\n" "}" ); a.push_back( obj ); add_value( obj, "c", a ); check_eq ( obj, "{\"a\":1,\"b\":[11,12],\"c\":[11,12,{\"a\":1,\"b\":[11,12]}]}" ); check_eq_pretty( obj, "{\n" " \"a\" : 1,\n" " \"b\" : [\n" " 11,\n" " 12\n" " ],\n" " \"c\" : [\n" " 11,\n" " 12,\n" " {\n" " \"a\" : 1,\n" " \"b\" : [\n" " 11,\n" " 12\n" " ]\n" " }\n" " ]\n" "}" ); check_eq_single_line_arrays( obj, "{\n" " \"a\" : 1,\n" " \"b\" : [ 11, 12 ],\n" " \"c\" : [\n" " 11,\n" " 12,\n" " {\n" " \"a\" : 1,\n" " \"b\" : [ 11, 12 ]\n" " }\n" " ]\n" "}" ); } void test_escape_char( const char* esc_str_in, const char* esc_str_out, unsigned int option = 0 ) { Object_type obj; const string name_str( string( esc_str_in ) + "name" ); add_value( obj, name_str.c_str(), to_str( "value" ) + to_str( esc_str_in ) ); const string out_str( string( "{\"" ) + esc_str_out + "name\":\"value" + esc_str_out + "\"}" ); check_eq( obj, out_str.c_str(), option ); } void test_escape_chars() { test_escape_char( "\r", "\\r" ); test_escape_char( "\n", "\\n" ); test_escape_char( "\t", "\\t" ); test_escape_char( "\f", "\\f" ); test_escape_char( "\b", "\\b" ); test_escape_char( "\"", "\\\"" ); test_escape_char( "\\", "\\\\" ); test_escape_char( "\x01", "\\u0001" ); test_escape_char( "\x12", "\\u0012" ); test_escape_char( "\x7F", "\\u007F" ); } void test_disabling_nonprintable_esc_chars() { test_escape_char( "\t", "\\t", raw_utf8 ); test_escape_char( "\x01", "\x01", raw_utf8 ); test_escape_char( "\x01\x12", "\x01\x12", raw_utf8 ); } void test_to_stream() { basic_ostringstream< Char_type > os; Array_type arr; arr.push_back( 111 ); arr.push_back( 222 ); os << hex; // the code should handle this, i.e. output decimal write( arr, os ); assert_eq( os.str(), to_str( "[111,222]" ) ); } void test_values() { check_eq( 123, "123" ); check_eq( 1.234, "1.2340000000000000" ); check_eq( to_str( "abc" ), "\"abc\"" ); check_eq( false, "false" ); check_eq( Value_type::null, "null" ); } void test_uint64() { check_eq( Value_type( 0 ), "0" ); check_eq( Value_type( int64_t( 0 ) ), "0" ); check_eq( Value_type( uint64_t( 0 ) ), "0" ); check_eq( Value_type( 1 ), "1" ); check_eq( Value_type( int64_t( 1 ) ), "1" ); check_eq( Value_type( uint64_t( 1 ) ), "1" ); check_eq( Value_type( -1 ), "-1" ); check_eq( Value_type( int64_t( -1 ) ), "-1" ); check_eq( Value_type( max_int64 ), "9223372036854775807" ); check_eq( Value_type( uint64_t( max_int64 ) ), "9223372036854775807" ); check_eq( Value_type( max_uint64 ), "18446744073709551615" ); } void test_ios_state_saved() { basic_ostringstream< Char_type > os; os << 0.123456789; Array_type arr; arr.push_back( 0.123456789 ); write( arr, os ); os << 0.123456789; assert_eq( os.str(), to_str( "0.123457" "[0.12345678900000000]" "0.123457" ) ); } void check_remove_trailing_zeros( const double value, const String_type& expected_str_with, const String_type& expected_str_without ) { check_eq( value, expected_str_with, 0 ); check_eq( value, expected_str_without, remove_trailing_zeros ); } void check_remove_trailing_zeros( const double value, const char* expected_str_with, const char* expected_str_without ) { check_remove_trailing_zeros( value, to_str( expected_str_with ), to_str( expected_str_without ) ); } void test_remove_trailing_zeros() { #ifdef WIN32 const String_type exp = to_str( "099" ); #else const String_type exp = to_str( "99" ); #endif check_remove_trailing_zeros( 0.0, zero_str(), to_str( "0.0" ) ); check_remove_trailing_zeros( 1.2, "1.2000000000000000", "1.2" ); check_remove_trailing_zeros( 0.123456789, "0.12345678900000000", "0.123456789" ); check_remove_trailing_zeros( 1.2e-99, to_str( "1.2000000000000000e-" ) + exp, to_str( "1.2e-" ) + exp ); check_remove_trailing_zeros( 1.23456789e99, to_str( "1.2345678900000001e+" ) + exp, to_str( "1.23456789e+" ) + exp ); } void run_tests() { test_empty_obj(); test_obj_with_one_member(); test_obj_with_two_members(); test_obj_with_three_members(); test_obj_with_one_empty_child_obj(); test_obj_with_one_child_obj(); test_obj_with_grandchild_obj(); test_objs_with_bool_pairs(); test_objs_with_int_pairs(); test_objs_with_real_pairs(); test_objs_with_null_pairs(); test_empty_array(); test_array_with_one_member(); test_array_with_two_members(); test_array_with_n_members(); test_array_with_one_empty_child_array(); test_array_with_one_child_array(); test_array_with_grandchild_array(); test_array_and_objs(); test_obj_and_arrays(); test_escape_chars(); test_disabling_nonprintable_esc_chars(); test_to_stream(); test_values(); test_uint64(); test_ios_state_saved(); test_remove_trailing_zeros(); } }; #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void test_wide_esc_u( wchar_t c, const wstring& result) { const wstring s( 1, c ); wArray arr( 1, s ); assert_eq( write( arr ), L"[\"\\u" + result + L"\"]" ); } void test_wide_esc_u() { test_wide_esc_u( 0xABCD, L"ABCD" ); test_wide_esc_u( 0xFFFF, L"FFFF" ); } #endif bool is_printable( char c ) { const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); return iswprint( unsigned_c ) != 0; } #ifdef JSON_SPIRIT_VALUE_ENABLED void test_extended_ascii() { const string expeced_result( is_printable( 'ä' ) ? "[\"äöüß\"]" : "[\"\\u00E4\\u00F6\\u00FC\\u00DF\"]" ); assert_eq( write( Array( 1, "äöüß" ) ), expeced_result ); } #endif } void json_spirit::test_writer() { #ifdef JSON_SPIRIT_VALUE_ENABLED Test_runner< Config >().run_tests(); test_extended_ascii(); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED Test_runner< mConfig >().run_tests(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wConfig >().run_tests(); test_wide_esc_u(); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wmConfig >().run_tests(); #endif } json_spirit_v4_05/json_test/utils_test.h0000644000000000000000000000141711616562300017417 0ustar rootroot#ifndef JSON_SPIRIT_TEST_UTILS #define JSON_SPIRIT_TEST_UTILS // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include #include // these functions allow you to inspect the values that caused a test to fail template< class T1, class T2 > void assert_eq( const T1& t1, const T2& t2 ) { if( t1 == t2 ) return; assert( false ); } template< class T1, class T2 > void assert_neq( const T1& t1, const T2& t2 ) { if( !(t1 == t2) ) return; assert( false ); } void assert_eq( const double d1, const double d2, const double abs_error ); #endif json_spirit_v4_05/json_test/utils_test.cpp0000644000000000000000000000055411616562300017753 0ustar rootroot// Copyright John W. Wilkinson 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "utils_test.h" void assert_eq( const double d1, const double d2, const double abs_error ) { const double err = fabs( d1 - d2 ); if( err <= abs_error ) return; assert( false ); } json_spirit_v4_05/json_test/json_spirit_value_test.h0000644000000000000000000000054611616562300022020 0ustar rootroot#ifndef JSON_SPIRIT_VALUE_TEST #define JSON_SPIRIT_VALUE_TEST // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { void test_value(); } #endif json_spirit_v4_05/json_test/json_spirit_stream_reader_test.cpp0000644000000000000000000001076011616562300024053 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_stream_reader_test.h" #include "utils_test.h" #include "json_spirit_stream_reader.h" #include #include using namespace json_spirit; using namespace std; using namespace boost; using namespace boost::assign; namespace { template< class Config_type > struct Test_runner { 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 Config_type::Value_type Value_type; typedef typename Config_type::Pair_type Pair_type; typedef typename String_type::value_type Char_type; typedef typename String_type::const_iterator Iter_type; typedef std::basic_istringstream< Char_type > Istringstream_type; typedef std::basic_istream< Char_type > Istream_type; String_type to_str( const char* c_str ) { return ::to_str< String_type >( c_str ); } Test_runner() { } void check_stream_reader( Stream_reader< Istream_type, Value_type >& reader, const vector< int >& expected_result ) { Value_type v; const bool ok = reader.read_next( v ); assert_eq( ok, true ); assert_eq( v.type(), array_type ); assert_eq( v.get_array().size(), expected_result.size() ); for( vector< int >::size_type i = 0; i < v.get_array().size(); ++i ) { assert_eq( v.get_array()[i], expected_result[i] ); } } void check_stream_read_or_throw( Stream_reader_thrower< Istream_type, Value_type >& reader, const vector< int >& expected_result ) { Value_type v; try { reader.read_next( v ); assert_eq( v.type(), array_type ); assert_eq( v.get_array().size(), expected_result.size() ); for( vector< int >::size_type i = 0; i < v.get_array().size(); ++i ) { assert_eq( v.get_array()[i], expected_result[i] ); } } catch( ... ) { assert( false ); } } void test_stream_reader( const char* s ) { { Istringstream_type is( to_str( s ) ); Stream_reader< Istream_type, Value_type > reader( is ); check_stream_reader( reader, vector< int >() ); check_stream_reader( reader, list_of( 1 ) ); check_stream_reader( reader, list_of( 1 )( 2 ) ); check_stream_reader( reader, list_of( 1 )( 2 )( 3 ) ); Value_type v; const bool ok = reader.read_next( v ); assert_eq( ok, false ); } { Istringstream_type is( to_str( s ) ); Stream_reader_thrower< Istream_type, Value_type > reader( is ); check_stream_read_or_throw( reader, vector< int >() ); check_stream_read_or_throw( reader, list_of( 1 ) ); check_stream_read_or_throw( reader, list_of( 1 )( 2 ) ); check_stream_read_or_throw( reader, list_of( 1 )( 2 )( 3 ) ); try { Value_type v; reader.read_next( v ); assert( false ); } catch( ... ) { } } } void run_tests() { test_stream_reader( "[][1][1,2][1,2,3]" ); test_stream_reader( "[] [1] [1,2] [1,2,3]" ); test_stream_reader( " [] [1] [1,2] [1,2,3] " ); } }; } void json_spirit::test_stream_reader() { #ifdef JSON_SPIRIT_VALUE_ENABLED Test_runner< Config >().run_tests(); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED Test_runner< mConfig >().run_tests(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wConfig >().run_tests(); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wmConfig >().run_tests(); #endif } json_spirit_v4_05/json_test/json_spirit_reader_test.cpp0000644000000000000000000007341611616562300022507 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_reader_test.h" #include "utils_test.h" #include "json_spirit_reader.h" #include "json_spirit_value.h" #include "json_spirit_writer.h" #include #include #include #include #include using namespace json_spirit; using namespace std; using namespace boost; using namespace boost::assign; namespace { template< class String_type, class Value_type > void test_read( const String_type& s, Value_type& value ) { // performs both types of read and checks they produce the same value read( s, value ); Value_type value_2; read_or_throw( s, value_2 ); assert_eq( value, value_2 ); } template< class Config_type > struct Test_runner { 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 Config_type::Value_type Value_type; typedef typename Config_type::Pair_type Pair_type; typedef typename String_type::value_type Char_type; typedef typename String_type::const_iterator Iter_type; typedef std::basic_istringstream< Char_type > Istringstream_type; typedef std::basic_istream< Char_type > Istream_type; String_type to_str( const char* c_str ) { return ::to_str< String_type >( c_str ); } Test_runner() { } void check_eq( const Object_type& obj_1, const Object_type& obj_2 ) { const typename Object_type::size_type size( obj_1.size() ); assert_eq( size, obj_2.size() ); typename Object_type::const_iterator i1 = obj_1.begin(); typename Object_type::const_iterator i2 = obj_2.begin(); for( ; i1 != obj_1.end(); ++i1, ++i2 ) { assert_eq( *i1, *i2 ); } } void add_value( Object_type& obj, const char* c_name, const Value_type& value ) { Config_type::add( obj, to_str( c_name ), value ); } void add_c_str( Object_type& obj, const char* c_name, const char* c_value ) { add_value( obj, c_name, to_str( c_value ) ); } void test_syntax( const char* c_str, bool expected_success = true ) { const String_type str = to_str( c_str ); Value_type value; const bool ok = read( str, value ); assert_eq( ok, expected_success ); try { read_or_throw( str, value ); assert( expected_success ); } catch( ... ) { assert( !expected_success ); } } template< typename Int > void test_syntax( Int min_int, Int max_int ) { ostringstream os; os << "[" << min_int << "," << max_int << "]"; test_syntax( os.str().c_str() ); } void test_syntax() { test_syntax( "{}" ); test_syntax( "{ }" ); test_syntax( "{ } " ); test_syntax( "{ } " ); test_syntax( "{\"\":\"\"}" ); test_syntax( "{\"test\":\"123\"}" ); test_syntax( "{\"test\" : \"123\"}" ); test_syntax( "{\"testing testing testing\":\"123\"}" ); test_syntax( "{\"\":\"abc\"}" ); test_syntax( "{\"abc\":\"\"}" ); test_syntax( "{\"\":\"\"}" ); test_syntax( "{\"test\":true}" ); test_syntax( "{\"test\":false}" ); test_syntax( "{\"test\":null}" ); test_syntax( "{\"test1\":\"123\",\"test2\":\"456\"}" ); test_syntax( "{\"test1\":\"123\",\"test2\":\"456\",\"test3\":\"789\"}" ); test_syntax( "{\"test1\":{\"test2\":\"123\",\"test3\":\"456\"}}" ); test_syntax( "{\"test1\":{\"test2\":{\"test3\":\"456\"}}}" ); test_syntax( "{\"test1\":[\"a\",\"bb\",\"cc\"]}" ); test_syntax( "{\"test1\":[true,false,null]}" ); test_syntax( "{\"test1\":[true,\"abc\",{\"a\":\"b\"},{\"d\":false},null]}" ); test_syntax( "{\"test1\":[1,2,-3]}" ); test_syntax( "{\"test1\":[1.1,2e4,-1.234e-34]}" ); test_syntax( "{\n" "\t\"test1\":\n" "\t\t{\n" "\t\t\t\"test2\":\"123\",\n" "\t\t\t\"test3\":\"456\"\n" "\t\t}\n" "}\n" ); test_syntax( "[]" ); test_syntax( "[ ]" ); test_syntax( "[1,2,3]" ); test_syntax( "[ 1, -2, 3]" ); test_syntax( "[ 1.2, -2e6, -3e-6 ]" ); test_syntax( "[ 1.2, \"str\", -3e-6, { \"field\" : \"data\" } ]" ); test_syntax( INT_MIN, INT_MAX ); test_syntax( LLONG_MIN, LLONG_MAX ); test_syntax( "[1 2 3]", false ); } Value_type read_cstr( const char* c_str ) { Value_type value; test_read( to_str( c_str ), value ); return value; } void read_cstr( const char* c_str, Value_type& value ) { test_read( to_str( c_str ), value ); } void check_reading( const char* c_str ) { Value_type value; String_type in_s( to_str( c_str ) ); test_read( in_s, value ); const String_type result = write_formatted( value ); assert_eq( in_s, result ); } template< typename Int > void check_reading( Int min_int, Int max_int ) { ostringstream os; os << "[\n" " " << min_int << ",\n" " " << max_int << "\n" "]"; check_reading( os.str().c_str() ); } void test_reading() { check_reading( "{\n}" ); Object_type obj; Value_type value; read_cstr( "{\n" " \"name 1\" : \"value 1\"\n" "}", value ); add_c_str( obj, "name 1", "value 1" ); check_eq( value.get_obj(), obj ); read_cstr( "{\"name 1\":\"value 1\",\"name 2\":\"value 2\"}", value ); add_c_str( obj, "name 2", "value 2" ); check_eq( value.get_obj(), obj ); read_cstr( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : \"value 2\",\n" " \"name 3\" : \"value 3\"\n" "}", value ); add_c_str( obj, "name 3", "value 3" ); check_eq( value.get_obj(), obj ); check_reading( "{\n" " \"\" : \"value\",\n" " \"name\" : \"\"\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : {\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : \"value_4\"\n" " }\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : {\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : \"value_4\",\n" " \"name_5\" : {\n" " \"name_6\" : \"value_6\",\n" " \"name_7\" : \"value_7\"\n" " }\n" " }\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : {\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : {\n" " \"name_5\" : \"value_5\",\n" " \"name_6\" : \"value_6\"\n" " },\n" " \"name_7\" : \"value_7\"\n" " }\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : {\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : {\n" " \"name_5\" : \"value_5\",\n" " \"name_6\" : \"value_6\"\n" " },\n" " \"name_7\" : \"value_7\"\n" " },\n" " \"name_8\" : \"value_8\",\n" " \"name_9\" : {\n" " \"name_10\" : \"value_10\"\n" " }\n" "}" ); check_reading( "{\n" " \"name 1\" : {\n" " \"name 2\" : {\n" " \"name 3\" : {\n" " \"name_4\" : {\n" " \"name_5\" : \"value\"\n" " }\n" " }\n" " }\n" " }\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : true,\n" " \"name 3\" : false,\n" " \"name_4\" : \"value_4\",\n" " \"name_5\" : true\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : null,\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : null\n" "}" ); check_reading( "{\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : 123,\n" " \"name 3\" : \"value 3\",\n" " \"name_4\" : -567\n" "}" ); check_reading( "[\n]" ); check_reading( "[\n" " 1\n" "]" ); check_reading( "[\n" " 1,\n" " 1.2000000000000000,\n" " \"john]\",\n" " true,\n" " false,\n" " null\n" "]" ); check_reading( "[\n" " 1,\n" " [\n" " 2,\n" " 3\n" " ]\n" "]" ); check_reading( "[\n" " 1,\n" " [\n" " 2,\n" " 3\n" " ],\n" " [\n" " 4,\n" " [\n" " 5,\n" " 6,\n" " 7\n" " ]\n" " ]\n" "]" ); check_reading( "[\n" " {\n" " \"name\" : \"value\"\n" " }\n" "]" ); check_reading( "{\n" " \"name\" : [\n" " 1\n" " ]\n" "}" ); check_reading( "[\n" " {\n" " \"name 1\" : \"value\",\n" " \"name 2\" : [\n" " 1,\n" " 2,\n" " 3\n" " ]\n" " }\n" "]" ); check_reading( "{\n" " \"name 1\" : [\n" " 1,\n" " {\n" " \"name 2\" : \"value 2\"\n" " }\n" " ]\n" "}" ); check_reading( "[\n" " {\n" " \"name 1\" : \"value 1\",\n" " \"name 2\" : [\n" " 1,\n" " 2,\n" " {\n" " \"name 3\" : \"value 3\"\n" " }\n" " ]\n" " }\n" "]" ); check_reading( "{\n" " \"name 1\" : [\n" " 1,\n" " {\n" " \"name 2\" : [\n" " 1,\n" " 2,\n" " 3\n" " ]\n" " }\n" " ]\n" "}" ); check_reading( INT_MIN, INT_MAX ); check_reading( LLONG_MIN, LLONG_MAX ); } void test_reading_reals() { Value_type value; const String_type in_s = to_str( "[1.200000000000000,1.234567890123456e+125,-1.234000000000000e-123," " 1.000000000000000e-123,1234567890.123456,123]" ); basic_istringstream< Char_type > is( in_s ); const bool ok = read( is, value ); assert_eq( ok, true ); assert_eq( value.type(), array_type ); const Array_type arr = value.get_array(); assert_eq( arr.size(), 6 ); assert_eq( arr[0].get_real(), 1.200000000000000, 1e-16 ); assert_eq( arr[1].get_real(), 1.234567890123456e+125, 1e+110 ); assert_eq( arr[2].get_real(), -1.234000000000000e-123, 1e+108 ); assert_eq( arr[3].get_real(), 1.000000000000000e-123, 1e+108 ); assert_eq( arr[4].get_real(), 1234567890.123456, 1e-7 ); assert_eq( arr[5].get_real(), 123.0, 1e-13 ); } void test_from_stream( const char* json_str, bool expected_success, const Error_position& expected_error ) { Value_type value; String_type in_s( to_str( json_str ) ); basic_istringstream< Char_type > is( in_s ); const bool ok = read( is, value ); assert_eq( ok, expected_success ); if( ok ) { assert_eq( in_s, write( value ) ); } try { basic_istringstream< Char_type > is( in_s ); read_or_throw( is, value ); assert_eq( expected_success, true ); assert_eq( in_s, write( value ) ); } catch( const Error_position error ) { assert_eq( error, expected_error ); } } void test_from_stream() { test_from_stream( "[1,2]", true, Error_position() ); test_from_stream( "\n\n foo", false, Error_position( 3, 2,"not a value" ) ); } void test_escape_chars( const char* json_str, const char* c_str ) { Value_type value; string s( string( "{\"" ) + json_str + "\" : \"" + json_str + "\"} " ); read_cstr( s.c_str(), value ); const Pair_type& pair( *value.get_obj().begin() ); assert_eq( Config_type::get_name ( pair ), to_str( c_str ) ); assert_eq( Config_type::get_value( pair ), to_str( c_str ) ); } void test_escape_chars() { test_escape_chars( "\\t", "\t"); test_escape_chars( "a\\t", "a\t" ); test_escape_chars( "\\tb", "\tb" ); test_escape_chars( "a\\tb", "a\tb" ); test_escape_chars( "a\\tb", "a\tb" ); test_escape_chars( "a123\\tb", "a123\tb" ); test_escape_chars( "\\t\\n\\\\", "\t\n\\" ); test_escape_chars( "\\/\\r\\b\\f\\\"", "/\r\b\f\"" ); test_escape_chars( "\\h\\j\\k", "" ); // invalid esc chars test_escape_chars( "\\x61\\x62\\x63", "abc" ); test_escape_chars( "a\\x62c", "abc" ); test_escape_chars( "\\x01\\x02\\x7F", "\x01\x02\x7F" ); // NB x7F is the greatest char spirit will parse test_escape_chars( "\\u0061\\u0062\\u0063", "abc" ); } void check_is_null( const char* c_str ) { assert_eq( read_cstr( c_str ).type(), null_type ); } template< typename T > void check_value( const char* c_str, const T& expected_value ) { const Value_type v( read_cstr( c_str ) ); assert_eq( v.template get_value< T >(), expected_value ); } void test_values() { check_value( "1", 1 ); check_value( "1.5", 1.5 ); check_value( "\"Test\"", to_str( "Test" ) ); check_value( "true", true ); check_value( "false", false ); check_is_null( "null" ); } void check_read_fails( const char* c_str, int line, int column, const string& reason ) { Value_type value; try { read_cstr( c_str, value ); assert( false ); } catch( const Error_position posn ) { assert_eq( posn, Error_position( line, column, reason ) ); } } void test_error_cases() { check_read_fails( "", 1, 1, "not a value" ); check_read_fails( "foo", 1, 1, "not a value" ); check_read_fails( " foo", 1, 2, "not a value" ); check_read_fails( " foo", 1, 3, "not a value" ); check_read_fails( "\n\n foo", 3, 2, "not a value" ); check_read_fails( "!!!", 1, 1, "not a value" ); check_read_fails( "\"bar", 1, 1, "not a value" ); check_read_fails( "bar\"", 1, 1, "not a value" ); check_read_fails( "[1}", 1, 3, "not an array" ); check_read_fails( "[1,2?", 1, 5, "not an array" ); check_read_fails( "[1,2}", 1, 5, "not an array" ); check_read_fails( "[1;2]", 1, 3, "not an array" ); check_read_fails( "[1,\n2,\n3,]", 3, 2, "not an array" ); check_read_fails( "{\"name\":\"value\"]", 1, 16, "not an object" ); check_read_fails( "{\"name\",\"value\"}", 1, 8, "no colon in pair" ); check_read_fails( "{name:\"value\"}", 1, 2, "not an object" ); check_read_fails( "{\n1:\"value\"}", 2, 1, "not an object" ); check_read_fails( "{\n name\":\"value\"}", 2, 3, "not an object" ); check_read_fails( "{\"name\":foo}", 1, 9, "not a value" ); check_read_fails( "{\"name\":value\"}", 1, 9, "not a value" ); } typedef vector< int > Ints; bool test_read_range( Iter_type& first, Iter_type last, Value_type& value ) { Iter_type first_ = first; const bool ok = read( first, last, value ); try { Value_type value_; read_or_throw( first_, last, value_ ); assert_eq( ok, true ); assert_eq( value, value_ ); } catch( ... ) { assert_eq( ok, false ); } return ok; } void check_value_sequence( Iter_type first, Iter_type last, const Ints& expected_values, bool all_input_consumed ) { Value_type value; for( Ints::size_type i = 0; i < expected_values.size(); ++i ) { const bool ok = test_read_range( first, last, value ); assert_eq( ok, true ); const bool is_last( i == expected_values.size() - 1 ); assert_eq( first == last, is_last ? all_input_consumed : false ); } const bool ok = test_read_range( first, last, value ); assert_eq( ok, false ); } void check_value_sequence( Istream_type& is, const Ints& expected_values, bool all_input_consumed ) { Value_type value; for( Ints::size_type i = 0; i < expected_values.size(); ++i ) { read_or_throw( is, value ); assert_eq( value.get_int(), expected_values[i] ); const bool is_last( i == expected_values.size() - 1 ); assert_eq( is.eof(), is_last ? all_input_consumed : false ); } try { read_or_throw( is, value ); assert( false ); } catch( ... ) { } assert_eq( is.eof(), true ); } void check_value_sequence( const char* c_str, const Ints& expected_values, bool all_input_consumed ) { const String_type s( to_str( c_str ) ); check_value_sequence( s.begin(), s.end(), expected_values, all_input_consumed ); Istringstream_type is( s ); check_value_sequence( is, expected_values, all_input_consumed ); } void check_array( const Value_type& value, typename Array_type::size_type expected_size ) { assert_eq( value.type(), array_type ); const Array_type& arr = value.get_array(); assert_eq( arr.size(), expected_size ); for( typename Array_type::size_type i = 0; i < expected_size; ++i ) { const Value_type& val = arr[i]; assert_eq( val.type(), int_type ); assert_eq( val.get_int(), int( i + 1 ) ); } } void check_reading_array( Iter_type& begin, Iter_type end, typename Array_type::size_type expected_size ) { Value_type value; test_read_range( begin, end, value ); check_array( value, expected_size ); } void check_reading_array( Istream_type& is, typename Array_type::size_type expected_size ) { Value_type value; read( is, value ); check_array( value, expected_size ); } void check_reading_arrays( const char* arrays_str ) { const String_type str( to_str( arrays_str ) ); Iter_type begin = str.begin(); const Iter_type end = str.end(); check_reading_array( begin, end, 0 ); check_reading_array( begin, end, 1 ); check_reading_array( begin, end, 2 ); check_reading_array( begin, end, 3 ); Istringstream_type is( str ); check_reading_array( is, 0 ); check_reading_array( is, 1 ); check_reading_array( is, 2 ); check_reading_array( is, 3 ); } void test_sequence_of_values() { check_value_sequence( "", Ints(), false ); check_value_sequence( " ", Ints(), false ); check_value_sequence( " ", Ints(), false ); check_value_sequence( " 10 ", list_of( 10 ), false ); check_value_sequence( " 10 11 ", list_of( 10 )( 11 ), false ); check_value_sequence( " 10 11 12", list_of( 10 )( 11 )( 12 ), true); check_value_sequence( "10 11 12", list_of( 10 )( 11 )( 12 ), true); // check_reading_arrays( "[] [ 1 ] [ 1, 2 ] [ 1, 2, 3 ]" ); // check_reading_arrays( "[][1][1,2][1,2,3]" ); // fails due to multi_pass iterator bug, // use stream_reader class instead } void test_uint64( const char* value_str, int expected_int, int64_t expected_int64, uint64_t expected_uint64 ) { const Value_type v( read_cstr( value_str ) ); assert_eq( v.get_int(), expected_int ); assert_eq( v.get_int64(), expected_int64 ); assert_eq( v.get_uint64(), expected_uint64 ); } void test_uint64() { test_uint64( "0", 0, 0, 0 ); test_uint64( "1", 1, 1, 1 ); test_uint64( "-1", -1, -1, ULLONG_MAX ); test_uint64( "18446744073709551615", -1, -1, ULLONG_MAX ); } void test_types() { Value_type value; read( to_str( "[ \"foo\", true, false, 1, 12.3, null ]" ), value ); assert_eq( value.type(), array_type ); const Array_type& a = value.get_array(); assert_eq( a[0].get_str(), to_str( "foo" ) ); assert_eq( a[1].get_bool(), true ); assert_eq( a[2].get_bool(), false ); assert_eq( a[3].get_int(), 1 ); assert_eq( a[3].get_int64(), 1 ); assert_eq( a[3].get_uint64(), 1u ); assert_eq( a[3].get_real(), 1.0 ); assert_eq( a[4].get_real(), 12.3 ); assert_eq( a[5].is_null(), true ); } void run_tests() { test_syntax(); test_reading(); test_reading_reals(); test_from_stream(); test_escape_chars(); test_values(); test_error_cases(); test_sequence_of_values(); test_uint64(); test_types(); } }; #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) void test_wide_esc_u() { wValue value; test_read( L"[\"\\uABCD\"]", value ); const wstring s( value.get_array()[0].get_str() ); assert_eq( s.length(), static_cast< wstring::size_type >( 1u ) ); assert_eq( s[0], 0xABCD ); } #endif #ifdef JSON_SPIRIT_VALUE_ENABLED void test_extended_ascii( const string& s ) { Value value; test_read( "[\"" + s + "\"]", value ); assert_eq( value.get_array()[0].get_str(), "äöüß" ); } void test_extended_ascii() { test_extended_ascii( "\\u00E4\\u00F6\\u00FC\\u00DF" ); test_extended_ascii( "äöüß" ); } #endif } //#include void json_spirit::test_reader() { #ifdef JSON_SPIRIT_VALUE_ENABLED Test_runner< Config >().run_tests(); test_extended_ascii(); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED Test_runner< mConfig >().run_tests(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wConfig >().run_tests(); test_wide_esc_u(); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wmConfig >().run_tests(); #endif #ifndef _DEBUG //ifstream ifs( "test.txt" ); //string s; //getline( ifs, s ); //timer t; //for( int i = 0; i < 2000; ++i ) //{ // Value value; // read( s, value ); //} //cout << t.elapsed() << endl; // const string so = write( value ); //Object obj; //for( int i = 0; i < 100000; ++i ) //{ // obj.push_back( Pair( "\x01test\x7F", lexical_cast< string >( i ) ) ); //} //const string s = write( obj ); //Value value; //timer t; //read( s, value ); //cout << t.elapsed() << endl; //cout << "obj size " << value.get_obj().size(); #endif } json_spirit_v4_05/json_test/CMakeLists.txt0000644000000000000000000000101511617557616017620 0ustar rootrootSET(JSON_TEST_SRCS json_spirit_reader_test.cpp json_spirit_reader_test.h json_spirit_stream_reader_test.cpp json_spirit_stream_reader_test.h json_spirit_utils_test.cpp json_spirit_utils_test.h json_spirit_value_test.cpp json_spirit_value_test.h json_spirit_writer_test.cpp json_spirit_writer_test.h utils_test.cpp utils_test.h json_test.cpp) FIND_PACKAGE(Boost 1.34 REQUIRED) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) ADD_EXECUTABLE(json_test ${JSON_TEST_SRCS}) TARGET_LINK_LIBRARIES(json_test json_spirit) json_spirit_v4_05/json_test/json_spirit_value_test.cpp0000644000000000000000000004004611617552170022357 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_value_test.h" #include "utils_test.h" #include "json_spirit_value.h" #include #include #include #include using namespace json_spirit; using namespace std; using namespace boost; using namespace boost::assign; namespace { #ifdef JSON_SPIRIT_VALUE_ENABLED const int64_t max_int64 = integer_traits< int64_t >::max(); const uint64_t max_uint64 = integer_traits< uint64_t >::max(); void test_obj_value() { const Pair p1( "name1", "value1" ); const Pair p3( "name3", "value3" ); Object obj_1; obj_1.push_back( p1 ); Object obj_2; obj_2.push_back( p1 ); Object obj_3; obj_3.push_back( p3 ); Value v1( obj_1 ); Value v2( obj_2 ); Value v3( obj_3 ); assert_eq( v1.type(), obj_type ); assert_eq ( v1, v2 ); assert_neq( v1, v3 ); assert_eq( v1.get_obj(), obj_1 ); assert_eq( v3.get_obj(), obj_3 ); } void test_array_value() { Array array_1; array_1.push_back( 1 ); array_1.push_back( "2" ); Array array_2; array_2.push_back( 1 ); array_2.push_back( "2" ); Array array_3; array_3.push_back( 1 ); array_3.push_back( "X" ); Value v1( array_1 ); Value v2( array_2 ); Value v3( array_3 ); assert_eq( v1.type(), array_type ); assert_eq ( v1, v2 ); assert_neq( v1, v3 ); assert_eq( v1.get_array(), array_1 ); assert_eq( v3.get_array(), array_3 ); } void test_bool_value() { Value v1( true ); Value v2( true ); Value v3( false ); assert_eq( v1.type(), bool_type ); assert_eq ( v1, v2 ); assert_neq( v1, v3 ); assert( v1.get_bool() ); assert( !v3.get_bool() ); } void test_int_value() { Value v1( 1 ); Value v2( 1 ); Value v3( INT_MAX ); assert_eq( v1.type(), int_type ); assert_eq ( v1, v2 ); assert_neq( v1, v3 ); unsigned int uint_max = INT_MAX; assert_eq( v1.get_int(), 1 ); assert_eq( v1.get_int64(), 1 ); assert_eq( v1.get_uint64(), 1u ); assert_eq( v3.get_int(), INT_MAX ); assert_eq( v3.get_int64(), INT_MAX ); assert_eq( v3.get_uint64(), uint_max ); Value v4( max_int64 ); assert_eq( v4.get_int64(), max_int64 ); assert_eq( v4.get_uint64(), static_cast< uint64_t >( max_int64 ) ); const uint64_t max_int64_plus_1 = max_int64 + uint64_t( 1 ); Value v5( max_int64_plus_1 ); assert_eq( v5.get_uint64(), max_int64_plus_1 ); Value v6( max_uint64 ); assert_eq( v6.get_uint64(), max_uint64 ); Value v7( 0 ); assert_eq( v7.get_int(), 0 ); assert_eq( v7.get_int64(), 0 ); assert_eq( v7.get_uint64(), 0u ); Value v8( -1 ); assert_eq( v8.get_int(), -1 ); assert_eq( v8.get_int64(), -1 ); assert_eq( v8.get_uint64(), max_uint64 ); } void test_real_value() { Value v1( 1.0 ); Value v2( 1.0 ); Value v3( 2.0 ); assert_eq( v1.type(), real_type ); assert_eq ( v1, v2 ); assert_neq( v1, v3 ); assert_eq( v1.get_real(), 1.0 ); assert_eq( v3.get_real(), 2.0 ); } void test_null_value() { Value v1; Value v2; assert_eq( v1.type(), null_type ); assert_eq( v1.is_null(), true ); assert_eq( v1, v2 ); assert_eq( v1.is_null(), true ); assert_eq( Value( 1 ).is_null(), false ); } template< typename T > void test_get_value( const T& t ) { assert_eq( Value( t ).get_value< T >(), t ); } void test_get_value() { test_get_value( 123 ); test_get_value( max_int64 ); test_get_value( 1.23 ); test_get_value( true ); test_get_value( false ); test_get_value( string( "test" ) ); Array a; a.push_back( 1 ); a.push_back( "2" ); test_get_value( a ); Object obj; obj.push_back( Pair( "name1", "value1" ) ); test_get_value( obj ); } void assert_array_eq( const Value& v, const Array& a ) { assert_eq( v.get_array(), a ); } void assert_obj_eq( const Value& v, const Object& obj ) { assert_eq( v.get_obj(), obj ); } template< typename T > void check_copy( const T& t ) { const Value v1( t ); const Value v2( v1 ); Value v3; v3 = v1; assert_eq( v1, v2 ); assert_eq( v1, v3 ); assert_eq( v2.get_value< T >(), t ); assert_eq( v3.get_value< T >(), t ); assert_eq( v1.is_uint64(), v2.is_uint64() ); assert_eq( v1.is_uint64(), v3.is_uint64() ); } void check_copying_null() { const Value v1; const Value v2( v1 ); Value v3; v3 = v1; assert_eq( v2.type(), null_type ); assert_eq( v3.type(), null_type ); } void test_copying() { { const Array array_1 = list_of(1)(2); Value v1( array_1 ); const Value v2( v1 ); assert_array_eq( v1, array_1 ); assert_array_eq( v2, array_1 ); v1.get_array()[0] = 3; assert_array_eq( v1, list_of(3)(2) ); assert_array_eq( v2, array_1 ); } { const Object obj_1 = list_of( Pair( "a", 1 ) )( Pair( "b", 2 ) ); Value v1( obj_1 ); Value v2; v2 = v1; assert_obj_eq( v1, obj_1 ); assert_obj_eq( v2, obj_1 ); v1.get_obj()[0] = Pair( "c", 3 ); assert_obj_eq( v1, list_of( Pair( "c", 3 ) )( Pair( "b", 2 ) ) ); assert_obj_eq( v2, obj_1 ); } { check_copy( 1 ); check_copy( 2.0 ); check_copy( max_int64 ); check_copy( max_uint64 ); check_copy( string("test") ); check_copy( true ); check_copy( false ); const Array array_1 = list_of(1)(2); check_copy( array_1 ); const Object obj_1 = list_of( Pair( "a", 1 ) )( Pair( "b", 2 ) ); check_copy( obj_1 ); check_copying_null(); } } template< typename ObjectType > void check_pair_typedefs( ObjectType &object ) { typename ObjectType::value_type::String_type name = object[0].name_; typename ObjectType::value_type::Value_type value = object[0].value_; } void check_pair_typedefs() { Object o; check_pair_typedefs( o ); #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) wObject wo; check_pair_typedefs( wo ); #endif } void test_obj_map_implemention() { #ifdef JSON_SPIRIT_MVALUE_ENABLED mObject obj; obj[ "name 1" ] = 1; obj[ "name 2" ] = "two"; assert_eq( obj.size(), 2u ); assert_eq( obj.find( "name 1" )->second.get_int(), 1 ); assert_eq( obj.find( "name 2" )->second.get_str(), "two" ); #endif } template< typename Int > void check_an_int_is_a_real( Int i, bool expected_result ) { assert_eq( Value( i ).is_uint64(), expected_result ); } void test_is_uint64() { check_an_int_is_a_real( 1, false ); check_an_int_is_a_real( static_cast< int64_t >( 1 ), false ); check_an_int_is_a_real( static_cast< uint64_t >( 1 ), true ); } template< typename Int > void check_an_int_is_a_real( Int i, double expected_result ) { assert_eq( Value( i ).get_real(), expected_result ); } void test_an_int_is_a_real() { check_an_int_is_a_real( -1, -1.0 ); check_an_int_is_a_real( 0, 0.0 ); check_an_int_is_a_real( 1, 1.0 ); check_an_int_is_a_real( max_int64, 9223372036854775800.0 ); check_an_int_is_a_real( max_uint64, 18446744073709552000.0 ); } template< typename T > void check_wrong_type_exceptions( const Value_type vtype ) { Value v; assert_eq( v.type(), null_type ); try { v.get_value< T >(); assert( false ); } catch( const runtime_error& e ) { ostringstream os; os << "value type is " << null_type << " not " << vtype; assert_eq( e.what(), os.str() ); } } void test_wrong_type_exceptions() { check_wrong_type_exceptions< Object >( obj_type ); check_wrong_type_exceptions< Array >( array_type ); check_wrong_type_exceptions< string >( str_type ); check_wrong_type_exceptions< bool >( bool_type ); check_wrong_type_exceptions< boost::int64_t >( int_type ); check_wrong_type_exceptions< int >( int_type ); check_wrong_type_exceptions< double >( real_type ); } #endif template< class Config_type > class Container_constructor_runner { public: Container_constructor_runner() { vector< double > vd = list_of( 1.2 )( 1.3 ); test_container_constructor( vd ); vector< int > vi = list_of( 1 ); test_container_constructor( vi ); vi = list_of( 1 )( 2 ); test_container_constructor( vi ); vi = list_of( 1 )( 2 )( 3 ); test_container_constructor( vi ); list< double > ld = list_of( 1.2 )( 1.3 ); test_container_constructor( ld ); list< int > li = list_of( 1 ); test_container_constructor( li ); li = list_of( 1 )( 2 ); test_container_constructor( li ); li = list_of( 1 )( 2 )( 3 ); test_container_constructor( li ); } private: typedef typename Config_type::Array_type Array_type; typedef typename Config_type::Value_type Value_type; template< class Cont > void test_container_constructor( const Cont& cont ) { typedef typename Cont::value_type Cont_value_type; const Value_type val( cont.begin(), cont.end() ); const Array_type& arr = val.get_array(); Cont result; for( unsigned int i = 0; i < arr.size(); ++i ) { result.push_back( arr[i].template get_value< Cont_value_type>() ); } assert_eq( result, cont ); } }; void test_container_constructor() { #ifdef JSON_SPIRIT_VALUE_ENABLED Container_constructor_runner< Config >(); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED Container_constructor_runner< mConfig >(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Container_constructor_runner< wConfig >(); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Container_constructor_runner< wmConfig >(); #endif } template< class Config_type > class Variant_constructor_runner { public: Variant_constructor_runner() { test_variant_constructor< variant< int, double > >( 1.23 ); test_variant_constructor< variant< int, double > >( 123 ); test_variant_constructor< variant< int, double, String_type > >( to_str< String_type >( "foo" ) ); test_variant_constructor< variant< int, double, String_type, bool > >( true ); test_variant_constructor< variant< int, double, String_type, bool, boost::int64_t > >( boost::int64_t( 123 ) ); test_variant_constructor< variant< int, double, String_type, bool, boost::uint64_t > >( boost::uint64_t( 123 ) ); { variant< int, Null > variant = Null(); const Value_type val( variant ); assert( val.is_null() ); } vector< double > vd = list_of( 1.2 )( 1.3 ); test_variant_array_constructor< double > ( vd ); vector< int > vi = list_of( 1 ); test_variant_array_constructor< int >( vi ); vi = list_of( 1 )( 2 ); test_variant_array_constructor< int >( vi ); vi = list_of( 1 )( 2 )( 3 ); test_variant_array_constructor< int >( vi ); list< double > ld = list_of( 1.2 )( 1.3 ); test_variant_array_constructor< double >( ld ); list< int > li = list_of( 1 ); test_variant_array_constructor< int >( li ); li = list_of( 1 )( 2 ); test_variant_array_constructor< int >( li ); li = list_of( 1 )( 2 )( 3 ); test_variant_array_constructor< int >( li ); } private: typedef typename Config_type::String_type String_type; typedef typename Config_type::Array_type Array_type; typedef typename Config_type::Value_type Value_type; template< class Variant_t, typename T > void test_variant_constructor( const T& t ) { const Variant_t variant( t ); const Value_type val( variant ); assert_eq( val.template get_value< T >(), t ); } template< typename T, typename A, template< typename, typename > class Cont > void test_variant_array_constructor( const Cont< T, A >& cont ) { const variant< int, Cont< T, A > > variant = cont; const Value_type val( variant ); const Array_type& arr = val.get_array(); Cont< T, A > result; for( unsigned int i = 0; i < arr.size(); ++i ) { result.push_back( arr[i].template get_value< T >() ); } assert_eq( result, cont ); } }; void test_variant_constructor() { #ifdef JSON_SPIRIT_VALUE_ENABLED Variant_constructor_runner< Config >(); #endif #ifdef JSON_SPIRIT_MVALUE_ENABLED Variant_constructor_runner< mConfig >(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Variant_constructor_runner< wConfig >(); #endif #if defined( JSON_SPIRIT_WMVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Variant_constructor_runner< wmConfig >(); #endif } } void json_spirit::test_value() { #ifdef JSON_SPIRIT_VALUE_ENABLED Object obj; Value value_str ( "value" ); Value value_obj ( obj ); Value value_bool( true ); Value value_str_2 ( string( "value" ) ); Value value_obj_2 ( obj ); Value value_bool_2( false ); const char* str( "value" ); Value value_str_2b ( str ); assert_eq( value_str, value_str ); assert_eq( value_str, value_str_2 ); assert_eq( value_str, value_str_2b ); assert_eq( value_obj, value_obj ); assert_eq( value_obj, value_obj_2 ); assert_neq( value_str, value_obj ); assert_neq( value_str, value_bool ); Object obj_2; obj_2.push_back( Pair( "name", value_str ) ); Value value_str_3( "xxxxx" ); Value value_obj_3( obj_2 ); assert_neq( value_str, value_str_3 ); assert_neq( value_obj, value_obj_3 ); test_obj_value(); test_array_value(); test_bool_value(); test_int_value(); test_real_value(); test_null_value(); test_get_value(); test_copying(); test_obj_map_implemention(); test_is_uint64(); test_an_int_is_a_real(); test_wrong_type_exceptions(); #endif test_container_constructor(); test_variant_constructor(); } json_spirit_v4_05/json_test/json_spirit_utils_test.cpp0000644000000000000000000001032611616562300022374 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #include "json_spirit_utils_test.h" #include "utils_test.h" #include "json_spirit_utils.h" #include using namespace json_spirit; using namespace std; using namespace boost::assign; namespace { template< class Obj_t, class Map_t > struct Test_runner { typedef typename Map_t::key_type String_type; typedef typename Obj_t::value_type Pair_type; typedef typename Pair_type::Value_type Value_type; String_type to_str( const char* c_str ) { return ::to_str< String_type >( c_str ); } void assert_equal( const Obj_t& obj, const Map_t& mp_obj ) { typename Obj_t::size_type obj_size = obj.size(); typename Map_t::size_type map_size = mp_obj.size(); assert_eq( obj_size, map_size ); for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) { assert_eq( mp_obj.find( i->name_ )->second, i->value_ ); } } void check_obj_to_map( const Obj_t& obj ) { Map_t mp_obj; obj_to_map( obj, mp_obj ); assert_equal( obj, mp_obj ); } void check_map_cleared() { Map_t mp_obj; mp_obj[ to_str( "del" ) ] = to_str( "me" ); obj_to_map( Obj_t(), mp_obj ); assert_eq( mp_obj.size(), 0u ); } void check_map_to_obj( const Map_t& mp_obj ) { Obj_t obj; map_to_obj( mp_obj, obj ); assert_equal( obj, mp_obj ); } void check_obj_cleared() { Obj_t obj; obj.push_back( Pair_type( to_str( "del" ), to_str( "me" ) ) ); map_to_obj( Map_t(), obj ); assert_eq( obj.size(), 0u ); } void test_obj_to_map() { check_obj_to_map( Obj_t() ); check_obj_to_map( list_of( Pair_type( to_str( "a" ), 1 ) ) ); check_obj_to_map( list_of( Pair_type( to_str( "a" ), 1 ) )( Pair_type( to_str( "b" ), 2 ) ) ); check_obj_to_map( list_of( Pair_type( to_str( "a" ), 1 ) )( Pair_type( to_str( "b" ), 2 ) )( Pair_type( to_str( "c" ), 3 ) ) ); check_map_cleared(); check_map_to_obj( Map_t() ); check_map_to_obj( map_list_of( to_str( "a" ), 1 ) ); check_map_to_obj( map_list_of( to_str( "a" ), 1 )( to_str( "b" ), 2 ) ); check_map_to_obj( map_list_of( to_str( "a" ), 1 )( to_str( "b" ), 2 )( to_str( "c" ), 3 ) ); check_obj_cleared(); } void check_find( const Obj_t& obj, const char* name, const Value_type& expected_result ) { const Value_type& result = find_value( obj, to_str( name ) ); assert_eq( result, expected_result ); } void test_find() { check_find( Obj_t(), "not there", Value_type::null ); const Obj_t obj_1 = list_of( Pair_type( to_str( "a" ), 1 ) ); check_find( obj_1, "not there", Value_type::null ); check_find( obj_1, "a", 1 ); const Obj_t obj_2 = list_of( Pair_type( to_str( "a" ), 1 ) )( Pair_type( to_str( "ab" ), 2 ) ); check_find( obj_2, "a", 1 ); check_find( obj_2, "ab", 2 ); const Obj_t obj_3 = list_of( Pair_type( to_str( "a" ), 1 ) )( Pair_type( to_str( "ab" ), 2 ) )( Pair_type( to_str( "abc" ), 3 ) ); check_find( obj_3, "a", 1 ); check_find( obj_3, "ab", 2 ); check_find( obj_3, "abc", 3 ); } void run_tests() { test_obj_to_map(); test_find(); } }; } void json_spirit::test_utils() { #ifdef JSON_SPIRIT_VALUE_ENABLED Test_runner< Object, Mapped_obj >().run_tests(); #endif #if defined( JSON_SPIRIT_WVALUE_ENABLED ) && !defined( BOOST_NO_STD_WSTRING ) Test_runner< wObject, wMapped_obj >().run_tests(); #endif } json_spirit_v4_05/json_test/json_spirit_utils_test.h0000644000000000000000000000054611616562300022044 0ustar rootroot#ifndef JSON_SPIRIT_UTILS_TEST #define JSON_SPIRIT_UTILS_TEST // Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif namespace json_spirit { void test_utils(); } #endif json_spirit_v4_05/CMakeLists.txt0000644000000000000000000000153211423615136015577 0ustar rootrootCMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(json_spirit) SUBDIRS(json_spirit json_demo json_headers_only_demo json_map_demo json_test) INCLUDE_DIRECTORIES(json_spirit) INSTALL( FILES ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_error_position.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_reader.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_reader_template.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_stream_reader.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_utils.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_value.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_writer.h ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_writer_template.h DESTINATION include) INSTALL( FILES ${CMAKE_BINARY_DIR}/json_spirit/libjson_spirit.a DESTINATION lib) INCLUDE(CPack) json_spirit_v4_05/json.vcproj0000644000000000000000000001103111122257530015224 0ustar rootroot json_spirit_v4_05/LICENSE.txt0000644000000000000000000000212511607363666014675 0ustar rootrootThe MIT License Copyright (c) 2007 - 2010 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. json_spirit_v4_05/json_headers_only_demo/0000755000000000000000000000000011634366260017554 5ustar rootrootjson_spirit_v4_05/json_headers_only_demo/json_headers_only_demo.cpp0000644000000000000000000000765511616562300024777 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 // This demo shows you how to read and write JSON objects and arrays // using header files only, i.e. not linking to the JSON Spirit object library. // In this demo objects are stored as a vector of name/value pairs. #include "json_spirit_reader_template.h" #include "json_spirit_writer_template.h" #include #include #ifndef JSON_SPIRIT_VALUE_ENABLED #error Please define JSON_SPIRIT_VALUE_ENABLED for the Value type to be enabled #endif using namespace std; using namespace json_spirit; struct Address { int house_number_; string road_; string town_; string county_; string country_; }; bool operator==( const Address& a1, const Address& a2 ) { return ( a1.house_number_ == a2.house_number_ ) && ( a1.road_ == a2.road_ ) && ( a1.town_ == a2.town_ ) && ( a1.county_ == a2.county_ ) && ( a1.country_ == a2.country_ ); } void write_address( Array& a, const Address& addr ) { Object addr_obj; addr_obj.push_back( Pair( "house_number", addr.house_number_ ) ); addr_obj.push_back( Pair( "road", addr.road_ ) ); addr_obj.push_back( Pair( "town", addr.town_ ) ); addr_obj.push_back( Pair( "county", addr.county_ ) ); addr_obj.push_back( Pair( "country", addr.country_ ) ); a.push_back( addr_obj ); } Address read_address( const Object& obj ) { Address addr; for( Object::size_type i = 0; i != obj.size(); ++i ) { const Pair& pair = obj[i]; const string& name = pair.name_; const Value& value = pair.value_; if( name == "house_number" ) { addr.house_number_ = value.get_int(); } else if( name == "road" ) { addr.road_ = value.get_str(); } else if( name == "town" ) { addr.town_ = value.get_str(); } else if( name == "county" ) { addr.county_ = value.get_str(); } else if( name == "country" ) { addr.country_ = value.get_str(); } else { assert( false ); } } return addr; } void write_addrs( const char* file_name, const Address addrs[] ) { Array addr_array; for( int i = 0; i < 5; ++i ) { write_address( addr_array, addrs[i] ); } ofstream os( file_name ); write_stream( Value( addr_array ), os, pretty_print ); // NB need to convert Array to a Value os.close(); } vector< Address > read_addrs( const char* file_name ) { ifstream is( file_name ); Value value; read_stream( is, value ); const Array& addr_array = value.get_array(); vector< Address > addrs; for( unsigned int i = 0; i < addr_array.size(); ++i ) { addrs.push_back( read_address( addr_array[i].get_obj() ) ); } return addrs; } int main() { const Address addrs[5] = { { 42, "East Street", "Newtown", "Essex", "England" }, { 1, "West Street", "Hull", "Yorkshire", "England" }, { 12, "South Road", "Aberystwyth", "Dyfed", "Wales" }, { 45, "North Road", "Paignton", "Devon", "England" }, { 78, "Upper Street", "Ware", "Hertfordshire", "England" } }; const char* file_name( "demo.txt" ); write_addrs( file_name, addrs ); vector< Address > new_addrs = read_addrs( file_name ); assert( new_addrs.size() == 5 ); for( int i = 0; i < 5; ++i ) { assert( new_addrs[i] == addrs[i] ); } return 0; } json_spirit_v4_05/json_headers_only_demo/json_headers_only_demo.vcproj0000644000000000000000000000666511315737322025524 0ustar rootroot json_spirit_v4_05/json_headers_only_demo/CMakeLists.txt0000644000000000000000000000042411321706214022302 0ustar rootrootSET(JSON_HEADERS_ONLY_DEMO_SRCS json_headers_only_demo.cpp) FIND_PACKAGE(Boost 1.34 REQUIRED) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) ADD_EXECUTABLE(json_headers_only_demo ${JSON_HEADERS_ONLY_DEMO_SRCS}) TARGET_LINK_LIBRARIES(json_headers_only_demo json_spirit) json_spirit_v4_05/json_demo/0000755000000000000000000000000011634366260015020 5ustar rootrootjson_spirit_v4_05/json_demo/json_demo.vcproj0000644000000000000000000000747111313750272020225 0ustar rootroot json_spirit_v4_05/json_demo/address.txt0000644000000000000000000000012311122257530017171 0ustar rootroot{ "house_number" : 42, "road" : "East Street", "town" : "Newtown" }json_spirit_v4_05/json_demo/CMakeLists.txt0000644000000000000000000000032311321706214017544 0ustar rootrootSET(JSON_DEMO_SRCS json_demo.cpp) FIND_PACKAGE(Boost 1.34 REQUIRED) INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) ADD_EXECUTABLE(json_demo ${JSON_DEMO_SRCS}) TARGET_LINK_LIBRARIES(json_demo json_spirit) json_spirit_v4_05/json_demo/json_demo.cpp0000644000000000000000000000733711616562300017504 0ustar rootroot// Copyright John W. Wilkinson 2007 - 2011 // Distributed under the MIT License, see accompanying file LICENSE.txt // json spirit version 4.05 // This demo shows you how to read and write JSON objects and arrays. // In this demo objects are stored as a vector of name/value pairs. #include "json_spirit.h" #include #include #ifndef JSON_SPIRIT_VALUE_ENABLED #error Please define JSON_SPIRIT_VALUE_ENABLED for the Value type to be enabled #endif using namespace std; using namespace json_spirit; struct Address { int house_number_; string road_; string town_; string county_; string country_; }; bool operator==( const Address& a1, const Address& a2 ) { return ( a1.house_number_ == a2.house_number_ ) && ( a1.road_ == a2.road_ ) && ( a1.town_ == a2.town_ ) && ( a1.county_ == a2.county_ ) && ( a1.country_ == a2.country_ ); } void write_address( Array& a, const Address& addr ) { Object addr_obj; addr_obj.push_back( Pair( "house_number", addr.house_number_ ) ); addr_obj.push_back( Pair( "road", addr.road_ ) ); addr_obj.push_back( Pair( "town", addr.town_ ) ); addr_obj.push_back( Pair( "county", addr.county_ ) ); addr_obj.push_back( Pair( "country", addr.country_ ) ); a.push_back( addr_obj ); } Address read_address( const Object& obj ) { Address addr; for( Object::size_type i = 0; i != obj.size(); ++i ) { const Pair& pair = obj[i]; const string& name = pair.name_; const Value& value = pair.value_; if( name == "house_number" ) { addr.house_number_ = value.get_int(); } else if( name == "road" ) { addr.road_ = value.get_str(); } else if( name == "town" ) { addr.town_ = value.get_str(); } else if( name == "county" ) { addr.county_ = value.get_str(); } else if( name == "country" ) { addr.country_ = value.get_str(); } else { assert( false ); } } return addr; } void write_addrs( const char* file_name, const Address addrs[] ) { Array addr_array; for( int i = 0; i < 5; ++i ) { write_address( addr_array, addrs[i] ); } ofstream os( file_name ); write_formatted( addr_array, os ); os.close(); } vector< Address > read_addrs( const char* file_name ) { ifstream is( file_name ); Value value; read( is, value ); const Array& addr_array = value.get_array(); vector< Address > addrs; for( unsigned int i = 0; i < addr_array.size(); ++i ) { addrs.push_back( read_address( addr_array[i].get_obj() ) ); } return addrs; } int main() { const Address addrs[5] = { { 42, "East Street", "Newtown", "Essex", "England" }, { 1, "West Street", "Hull", "Yorkshire", "England" }, { 12, "South Road", "Aberystwyth", "Dyfed", "Wales" }, { 45, "North Road", "Paignton", "Devon", "England" }, { 78, "Upper Street", "Ware", "Hertfordshire", "England" } }; const char* file_name( "demo.txt" ); write_addrs( file_name, addrs ); vector< Address > new_addrs = read_addrs( file_name ); assert( new_addrs.size() == 5 ); for( int i = 0; i < 5; ++i ) { assert( new_addrs[i] == addrs[i] ); } return 0; } json_spirit_v4_05/json_demo/demo.txt0000644000000000000000000000151511213470260016474 0ustar rootroot[ { "house_number" : 42, "road" : "East Street", "town" : "Newtown", "county" : "Essex", "country" : "England" }, { "house_number" : 1, "road" : "West Street", "town" : "Hull", "county" : "Yorkshire", "country" : "England" }, { "house_number" : 12, "road" : "South Road", "town" : "Aberystwyth", "county" : "Dyfed", "country" : "Wales" }, { "house_number" : 45, "road" : "North Road", "town" : "Paignton", "county" : "Devon", "country" : "England" }, { "house_number" : 78, "road" : "Upper Street", "town" : "Ware", "county" : "Hertfordshire", "country" : "England" } ]