From cb21c7a16b45c14f8b2d9484a7c7548b5d0032bc Mon Sep 17 00:00:00 2001 From: Cayleb-Ordo Date: Thu, 7 May 2026 22:56:36 +0200 Subject: [PATCH] Replace json_spirit with nlohmann json v3.12 json_spirit is no longer maintained, as all links inside the third_party folder are going to nirvana. Also most projects on github did not see any commits in at least 6 years. Switching to nlohmann JSON should allow to maintain this part more easily in the future. Add nlohmann-json as a external lib through build-libraries. Create a include-only library target in extern_libs5.lua. On Linux and BSD, the system version is used. Add switch to build with system-nlohmann-json. Update debian-12 dockerfile to include nlohmann-json. Signed-off-by: Cayleb-Ordo --- .../jenkins/dockerfiles/debian-12.Dockerfile | 1 + build/premake/extern_libs5.lua | 9 + build/premake/premake5.lua | 1 + libraries/build-macos-libs.sh | 28 + source/third_party/jsonspirit/LICENSE.txt | 24 - source/third_party/jsonspirit/README.txt | 11 - .../jsonspirit/json_spirit_error_position.h | 54 -- .../jsonspirit/json_spirit_reader_template.h | 659 ------------------ .../jsonspirit/json_spirit_value.h | 606 ---------------- .../jsonspirit/json_spirit_writer_options.h | 35 - .../jsonspirit/json_spirit_writer_template.h | 325 --------- .../tools/atlas/AtlasObject/AtlasObjectJS.cpp | 84 +-- .../atlas/AtlasObject/JSONSpiritInclude.h | 44 -- 13 files changed, 77 insertions(+), 1804 deletions(-) delete mode 100644 source/third_party/jsonspirit/LICENSE.txt delete mode 100644 source/third_party/jsonspirit/README.txt delete mode 100644 source/third_party/jsonspirit/json_spirit_error_position.h delete mode 100644 source/third_party/jsonspirit/json_spirit_reader_template.h delete mode 100644 source/third_party/jsonspirit/json_spirit_value.h delete mode 100644 source/third_party/jsonspirit/json_spirit_writer_options.h delete mode 100644 source/third_party/jsonspirit/json_spirit_writer_template.h delete mode 100644 source/tools/atlas/AtlasObject/JSONSpiritInclude.h diff --git a/build/jenkins/dockerfiles/debian-12.Dockerfile b/build/jenkins/dockerfiles/debian-12.Dockerfile index 97eeb8561d..88df6e1b37 100644 --- a/build/jenkins/dockerfiles/debian-12.Dockerfile +++ b/build/jenkins/dockerfiles/debian-12.Dockerfile @@ -37,6 +37,7 @@ RUN apt-get -qqy update \ libvorbis-dev \ libwxgtk3.2-dev \ libxml2-dev \ + nlohmann-json3-dev \ lld-14 \ llvm \ llvm-14 \ diff --git a/build/premake/extern_libs5.lua b/build/premake/extern_libs5.lua index 4b916edca4..a6e56d37de 100644 --- a/build/premake/extern_libs5.lua +++ b/build/premake/extern_libs5.lua @@ -572,6 +572,15 @@ extern_lib_defs = { end end, }, + nlohmann_json = { + compile_settings = function() + if os.istarget("windows") then + add_default_include_paths("nlohmann-json") + else + pkgconfig.add_includes("nlohmann_json") + end + end, + }, nvtt = { compile_settings = function() if not _OPTIONS["with-system-nvtt"] then diff --git a/build/premake/premake5.lua b/build/premake/premake5.lua index 0c2f4c0142..641cd2b1f6 100644 --- a/build/premake/premake5.lua +++ b/build/premake/premake5.lua @@ -1324,6 +1324,7 @@ function setup_atlas_projects() "sdl", "spidermonkey", "cxxtest", + "nlohmann_json", },{ -- extra_params no_pch = 1 }) diff --git a/libraries/build-macos-libs.sh b/libraries/build-macos-libs.sh index c388de9ddb..c40767cd9d 100755 --- a/libraries/build-macos-libs.sh +++ b/libraries/build-macos-libs.sh @@ -50,6 +50,7 @@ SODIUM_VERSION="libsodium-1.0.20" FMT_VERSION="7.1.3" MOLTENVK_VERSION="1.3.0" OPENAL_SOFT_VERSION="1.24.2" +NLOHMANN_JSON_VERSION="3.12.0" # -------------------------------------------------------------- # Bundled with the game: # * SpiderMonkey @@ -1228,6 +1229,33 @@ echo "Building Molten VK..." fi ) || die "Failed to build MoltenVK" +# -------------------------------------------------------------- +echo "Setting up nlohman-json..." +( + LIB_URL="https://github.com/nlohmann/json/archive/refs/tags/" + LIB_ARCHIVE="v${NLOHMANN_JSON_VERSION}.tar.gz" + mkdir -p nlohmann-json + cd nlohmann-json + + if [ $force_rebuild = "true" ] || [ ! -e .already-built ] || [ "$(cat .already-built)" != "$NLOHMANN_JSON_VERSION" ]; then + rm -f .already-built + + download_lib $LIB_URL $LIB_ARCHIVE + rm -Rf build + tar -xf $LIB_ARCHIVE + + # install. We use the single header library, so no need to compile anything. Just install to generate the correct pkg-config file. + if cmake -S json-${NLOHMANN_JSON_VERSION} -B build -DJSON_MultipleHeaders=OFF -DCMAKE_INSTALL_PREFIX="$PWD" && cmake --install build; then + cp "$PWD"/share/pkgconfig/* "$PC_PATH" + echo "${NLOHMANN_JSON_VERSION}" >.already-built + else + die "Install of nlohmann-json failed..." + fi + else + already_built + fi +) || die "Install of nlohmann-json failed..." + # -------------------------------------------------------------------- # The following libraries and build tools are shared on different OSes # and may be customized, so we build and install them from bundled sources diff --git a/source/third_party/jsonspirit/LICENSE.txt b/source/third_party/jsonspirit/LICENSE.txt deleted file mode 100644 index 724153092d..0000000000 --- a/source/third_party/jsonspirit/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2007 - 2014 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. diff --git a/source/third_party/jsonspirit/README.txt b/source/third_party/jsonspirit/README.txt deleted file mode 100644 index 1e6591d675..0000000000 --- a/source/third_party/jsonspirit/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -This separate JSON library is used for Atlas to avoid the SpiderMonkey dependency. -SpiderMonkey is a fully featured JS engine and even though we already use it for the main engine, it's too heavy-weight to use it in Atlas. -The SpiderMonkey API also changes frequently and we hope that the JSON parsing code needs less changes when we use this separate library. - -Get the library from here: -http://www.codeproject.com/Articles/20027/JSON-Spirit-A-C-JSON-Parser-Generator-Implemented - -The currently used version was released on the 10 of May 2014. - -Search for this comment in json_spirit_value.h and uncomment the lines we don't need: -// comment out the value types you don't need to reduce build times and intermediate file sizes diff --git a/source/third_party/jsonspirit/json_spirit_error_position.h b/source/third_party/jsonspirit/json_spirit_error_position.h deleted file mode 100644 index 7eeec0300f..0000000000 --- a/source/third_party/jsonspirit/json_spirit_error_position.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef JSON_SPIRIT_ERROR_POSITION -#define JSON_SPIRIT_ERROR_POSITION - -// Copyright John W. Wilkinson 2007 - 2014 -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.08 - -#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 diff --git a/source/third_party/jsonspirit/json_spirit_reader_template.h b/source/third_party/jsonspirit/json_spirit_reader_template.h deleted file mode 100644 index 3cc6510df0..0000000000 --- a/source/third_party/jsonspirit/json_spirit_reader_template.h +++ /dev/null @@ -1,659 +0,0 @@ -#ifndef JSON_SPIRIT_READER_TEMPLATE -#define JSON_SPIRIT_READER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2014 -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.08 - -#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 -#if BOOST_VERSION >= 107600 -# include -# include - using namespace std::placeholders; -#else -# define BOOST_BIND_GLOBAL_PLACEHOLDERS 1 -# include -#endif - -#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; - - // Triggers gcc warning with optimizations enabled. This line prevents that. - if( end - begin < 1 ) return String_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 and what would appear to be comments 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 | - spirit_namespace::comment_p("//") | - spirit_namespace::comment_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 diff --git a/source/third_party/jsonspirit/json_spirit_value.h b/source/third_party/jsonspirit/json_spirit_value.h deleted file mode 100644 index 68d7aec827..0000000000 --- a/source/third_party/jsonspirit/json_spirit_value.h +++ /dev/null @@ -1,606 +0,0 @@ -#ifndef JSON_SPIRIT_VALUE -#define JSON_SPIRIT_VALUE - -// Copyright John W. Wilkinson 2007 - 2014 -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.08 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -# pragma warning(disable: 4505) // Unreferenced function has been removed. -#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 }; - - static inline std::string value_type_to_string(const Value_type vtype ); - - 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 const String_type& get_name( const Pair_type& pair ) - { - return pair.name_; - } - - static const 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< const 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 const String_type& get_name( const Pair_type& pair ) - { - return pair.first; - } - - static const 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 << "get_value< " << value_type_to_string( vtype ) << " > called on " << value_type_to_string( type() ) << " Value"; - - 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 >() ); - } - - static inline std::string value_type_to_string( const Value_type vtype ) - { - switch( vtype ) - { - case obj_type: return "Object"; - case array_type: return "Array"; - case str_type: return "string"; - case bool_type: return "boolean"; - case int_type: return "integer"; - case real_type: return "real"; - case null_type: return "null"; - } - - assert( false ); - - return "unknown type"; - } -} - -#endif diff --git a/source/third_party/jsonspirit/json_spirit_writer_options.h b/source/third_party/jsonspirit/json_spirit_writer_options.h deleted file mode 100644 index 60dc68ed4c..0000000000 --- a/source/third_party/jsonspirit/json_spirit_writer_options.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER_OPTIONS -#define JSON_SPIRIT_WRITER_OPTIONS - -// Copyright John W. Wilkinson 2007 - 2014 -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.08 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -namespace json_spirit -{ - enum Output_options{ none = 0, // default 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, - // no longer used kept for backwards compatibility - single_line_arrays = 0x08, - // pretty printing except that arrays printed on single lines unless they contain - // composite elements, i.e. objects or arrays - always_escape_nonascii = 0x10, - // all unicode wide characters are escaped, i.e. outputed as "\uXXXX", even if they are - // printable under the current locale, ascii printable chars are not escaped - }; -} - -#endif diff --git a/source/third_party/jsonspirit/json_spirit_writer_template.h b/source/third_party/jsonspirit/json_spirit_writer_template.h deleted file mode 100644 index c200c114b4..0000000000 --- a/source/third_party/jsonspirit/json_spirit_writer_template.h +++ /dev/null @@ -1,325 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER_TEMPLATE -#define JSON_SPIRIT_WRITER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2014 -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.08 - -#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 ) - { - 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, bool esc_nonascii ) - { - 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( !esc_nonascii && iswprint( unsigned_c ) ) - { - result += c; - } - else - { - result += non_printable_to_string< String_type >( unsigned_c ); - } - } - } - - return result; - } - - // this class generates the JSON text, - // it keeps track of the indentation level etc. - // - template< class Value_type, class Ostream_type > - class Generator - { - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - typedef typename Object_type::value_type Obj_member_type; - - public: - - Generator( const Value_type& value, Ostream_type& os, int options, unsigned int precision_of_doubles ) - : os_( os ) - , indentation_level_( 0 ) - , pretty_( ( options & pretty_print ) != 0 || ( options & single_line_arrays ) != 0 ) - , raw_utf8_( ( options & raw_utf8 ) != 0 ) - , esc_nonascii_( ( options & always_escape_nonascii ) != 0 ) - , single_line_arrays_( ( options & single_line_arrays ) != 0 ) - , ios_saver_( os ) - { - if( precision_of_doubles > 0 ) - { - precision_of_doubles_ = precision_of_doubles; - } - else - { - precision_of_doubles_ = ( options & remove_trailing_zeros ) != 0 ? 16 : 17; - } - - 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_, esc_nonascii_ ) << '"'; - } - - void output( bool b ) - { - os_ << to_str< String_type >( b ? "true" : "false" ); - } - - void output( double d ) - { - os_ << std::setprecision( precision_of_doubles_ ) << d; - } - - 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 esc_nonascii_; - bool single_line_arrays_; - int precision_of_doubles_; - 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, int options = none, unsigned int precision_of_doubles = 0 ) - { - os << std::dec; - Generator< Value_type, Ostream_type >( value, os, options, precision_of_doubles ); - } - - // 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, int options = none, unsigned int precision_of_doubles = 0 ) - { - typedef typename Value_type::String_type::value_type Char_type; - - std::basic_ostringstream< Char_type > os; - - write_stream( value, os, options, precision_of_doubles ); - - return os.str(); - } -} - -#endif diff --git a/source/tools/atlas/AtlasObject/AtlasObjectJS.cpp b/source/tools/atlas/AtlasObject/AtlasObjectJS.cpp index c0cccc9ad4..60db1b50a8 100644 --- a/source/tools/atlas/AtlasObject/AtlasObjectJS.cpp +++ b/source/tools/atlas/AtlasObject/AtlasObjectJS.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,21 +18,16 @@ #include "AtlasObject.h" #include "AtlasObjectImpl.h" -#if defined(_MSC_VER) -# pragma warning(disable:4996) // deprecated CRT -# pragma warning(disable: 4459) // global declaration hidden -#endif - -#include "JSONSpiritInclude.h" - +#include #include -static AtSmartPtr ConvertNode(json_spirit::Value node); +using json = nlohmann::json; + +static AtSmartPtr ConvertNode(json node); AtObj AtlasObject::LoadFromJSON(const std::string& json) { - json_spirit::Value rootnode; - json_spirit::read_string(json, rootnode); + auto rootnode = json::parse(json); AtObj obj; obj.m_Node = ConvertNode(rootnode); @@ -40,63 +35,60 @@ AtObj AtlasObject::LoadFromJSON(const std::string& json) } // Convert from a JSON to an AtNode -static AtSmartPtr ConvertNode(json_spirit::Value node) +static AtSmartPtr ConvertNode(json node) { AtSmartPtr obj (new AtNode()); - if (node.type() == json_spirit::str_type) + if (node.is_string()) { - obj->m_Value = node.get_str(); + obj->m_Value = node.dump(); } - else if (node.type() == json_spirit::int_type || node.type() == json_spirit::real_type) + else if (node.is_number_integer() || node.is_number_unsigned()) { std::stringstream stream; - if (node.type() == json_spirit::int_type) - stream << node.get_int(); - if (node.type() == json_spirit::real_type) - stream << node.get_real(); + if (node.is_number_integer()) + stream << node.get(); + if (node.is_number_unsigned()) + stream << node.get(); obj->m_Value = stream.str().c_str(); obj->m_Children.insert(AtNode::child_pairtype( "@number", AtSmartPtr(new AtNode()) )); } - else if (node.type() == json_spirit::bool_type) + else if (node.is_boolean()) { - obj->m_Value = node.get_bool() ? "true" : "false"; + obj->m_Value = node.get() ? "true" : "false"; obj->m_Children.insert(AtNode::child_pairtype( "@boolean", AtSmartPtr(new AtNode()) )); } - else if (node.type() == json_spirit::array_type) + else if (node.is_array()) { obj->m_Children.insert(AtNode::child_pairtype( "@array", AtSmartPtr(new AtNode()) )); - json_spirit::Array nodeChildren = node.get_array(); - json_spirit::Array::iterator itr = nodeChildren.begin(); + json nodeChildren = node.get>(); - for (; itr != nodeChildren.end(); ++itr) + for (auto child: nodeChildren) { obj->m_Children.insert(AtNode::child_pairtype( - "item", ConvertNode(*itr) - )); + "item", ConvertNode(child))); } } - else if (node.type() == json_spirit::obj_type) + else if (node.is_object()) { - json_spirit::Object objectProperties = node.get_obj(); - json_spirit::Object::iterator itr = objectProperties.begin(); - for (; itr != objectProperties.end(); ++itr) + json objectProperties = node; + for (auto& property: objectProperties.items()) { obj->m_Children.insert(AtNode::child_pairtype( - itr->name_, ConvertNode(itr->value_) + property.key(), ConvertNode(property.value()) )); } } - else if (node.type() == json_spirit::null_type) + else if (node.is_null()) { return obj; } @@ -109,11 +101,11 @@ static AtSmartPtr ConvertNode(json_spirit::Value node) } -json_spirit::Value BuildJSONNode(AtNode::Ptr p) +static json BuildJSONNode(AtNode::Ptr p) { if (!p) { - json_spirit::Value rval; + json rval; return rval; } @@ -124,7 +116,7 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p) double val = 0; static_cast(p->m_Value) >> val; - json_spirit::Value rval(val); + json rval(val); return rval; } else if (p->m_Children.count("@boolean")) @@ -133,20 +125,20 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p) if (p->m_Value == "true") val = true; - json_spirit::Value rval(val); + json rval(val); return rval; } // If no children, then use the value string instead if (p->m_Children.empty()) { - json_spirit::Value rval(p->m_Value); + json rval(p->m_Value); return rval; } if (p->m_Children.find("@array") != p->m_Children.end()) { - json_spirit::Array rval; + auto rval = json::array(); // Find the children AtNode::child_maptype::const_iterator lower = p->m_Children.lower_bound("item"); @@ -154,7 +146,7 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p) for (AtNode::child_maptype::const_iterator it = lower; it != upper; ++it) { - json_spirit::Value child = BuildJSONNode(it->second); + json child = BuildJSONNode(it->second); rval.push_back(child); } @@ -162,16 +154,16 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p) } else { - json_spirit::Object rval; + auto rval = json::object(); for (AtNode::child_maptype::const_iterator it = p->m_Children.begin(); it != p->m_Children.end(); ++it) { - json_spirit::Value child = BuildJSONNode(it->second); + json child = BuildJSONNode(it->second); // We don't serialize childs with null value. // Instead of something like this we omit the whole property: "StartingCamera": null // There's no special reason for that, it's just the same behaviour the previous implementations had. - if (child.type() != json_spirit::null_type) - rval.push_back(json_spirit::Pair(it->first.c_str(), child)); + if (!child.is_null()) + rval.emplace(it->first.c_str(), child); } return rval; @@ -180,6 +172,6 @@ json_spirit::Value BuildJSONNode(AtNode::Ptr p) std::string AtlasObject::SaveToJSON(AtObj& obj) { - json_spirit::Value root = BuildJSONNode(obj.m_Node); - return json_spirit::write_string(root, json_spirit::raw_utf8); + auto root = BuildJSONNode(obj.m_Node); + return root.dump(); } diff --git a/source/tools/atlas/AtlasObject/JSONSpiritInclude.h b/source/tools/atlas/AtlasObject/JSONSpiritInclude.h deleted file mode 100644 index beea6094de..0000000000 --- a/source/tools/atlas/AtlasObject/JSONSpiritInclude.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2025 Wildfire Games. - * This file is part of 0 A.D. - * - * 0 A.D. is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 0 A.D. is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with 0 A.D. If not, see . - */ - - // We use this special header for including the JSONSpirit header because some tweaking is needed to disable warnings. -#ifndef JSON_SPIRIT_INCLUDE_H -#define JSON_SPIRIT_INCLUDE_H - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -#ifdef _MSC_VER - #pragma warning(disable: 4100) - #pragma warning(disable: 4512) -#endif - -# include "third_party/jsonspirit/json_spirit_writer_template.h" -# include "third_party/jsonspirit/json_spirit_reader_template.h" - -#ifdef _MSC_VER - #pragma warning(default: 4100) - #pragma warning(default: 4512) -#endif - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -#endif // JSON_SPIRIT_INCLUDE_H