diff --git a/CMakeLists.txt b/CMakeLists.txt index 12d45c88..b03a7a22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ # -# Copyright (c) 2016-2017 Vinnie Falco (vinnie.falco@gmail.com) +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # -# Official repository: https://github.com/boostorg/fixed_string +# Official repository: https://github.com/vinniefalco/json # cmake_minimum_required (VERSION 3.5.1) @@ -151,4 +151,5 @@ file (GLOB_RECURSE PROJECT_FILES ) add_subdirectory (bench) +add_subdirectory (example) add_subdirectory (test) diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 4a0d63e4..5ca49149 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/bench/Jamfile b/bench/Jamfile index 1a92e03a..7d01e2e6 100644 --- a/bench/Jamfile +++ b/bench/Jamfile @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/bench/bench.cpp b/bench/bench.cpp index 735f6641..c0d31309 100644 --- a/bench/bench.cpp +++ b/bench/bench.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/doc/Jamfile b/doc/Jamfile index 5839640a..abd4295f 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -1,9 +1,11 @@ # -# Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # +# Official repository: https://github.com/vinniefalco/json +# project json/doc ; diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml index 3f76abdf..abc15497 100644 --- a/doc/qbk/quickref.xml +++ b/doc/qbk/quickref.xml @@ -81,6 +81,7 @@ error_category error_code error_condition + generic_category string_view system_error diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 00000000..db33af1d --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/vinniefalco/json +# + +GroupSources(example "/") + +add_executable (pretty + pretty.cpp +) +set_property(TARGET pretty PROPERTY FOLDER "example") + +add_executable (allocator + allocator.cpp +) +set_property(TARGET allocator PROPERTY FOLDER "example") diff --git a/example/allocator.cpp b/example/allocator.cpp new file mode 100644 index 00000000..b7319a8e --- /dev/null +++ b/example/allocator.cpp @@ -0,0 +1,18 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/vinniefalco/json +// + +/* + This example implements a custom storage adaptor + which uses any standard C++ allocator. +*/ + +int +main() +{ +} diff --git a/example/pretty.cpp b/example/pretty.cpp new file mode 100644 index 00000000..117e4070 --- /dev/null +++ b/example/pretty.cpp @@ -0,0 +1,97 @@ +// +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/vinniefalco/json +// + +/* + This example parses a JSON file and pretty-prints + it to standard output. +*/ + +#include +#include +#include + +namespace json = boost::json; + +json::value +parse_file( char const* filename ) +{ + json::error_code ec; + auto f = std::fopen( filename, "r" ); + if( ! f ) + { + ec.assign( errno, json::generic_category() ); + throw json::system_error(ec); + } + json::parser p; + p.start(); + do + { + char buf[4096]; + + // Read from the file into our buffer. + auto const nread = fread( buf, 1, sizeof(buf), f ); + if( std::ferror(f) ) + { + ec.assign( errno, json::generic_category() ); + throw json::system_error(ec); + } + + auto nparsed = p.write_some( buf, nread, ec); + + // Make sure we use all the characters in the file. + if( ! ec && nparsed < nread ) + nparsed = p.write_some( buf + nparsed, sizeof(buf) - nparsed, ec ); + + if( ec ) + throw json::system_error(ec); + } + while( ! std::feof(f) ); + + // Tell the parser there is no more serialized JSON. + p.write_eof(ec); + if( ec ) + throw json::system_error(ec); + + return p.release(); +} + +void +pretty_print( std::ostream& os, json::value const& jv ) +{ +} + +int +main(int argc, char** argv) +{ + if(argc != 2) + { + std::cerr << + "Usage: pretty " + << std::endl; + return EXIT_FAILURE; + } + + try + { + // Parse the file as JSON + auto const jv = parse_file( argv[1] ); + + // Now pretty-print the value + pretty_print(std::cout, jv); + } + catch(std::exception const& e) + { + std::cerr << + "Caught exception: " + << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/include/boost/json/basic_parser.hpp b/include/boost/json/basic_parser.hpp index 201bb7f9..cd92e142 100644 --- a/include/boost/json/basic_parser.hpp +++ b/include/boost/json/basic_parser.hpp @@ -153,6 +153,12 @@ public: std::size_t size, error_code& ec); + BOOST_JSON_DECL + std::size_t + write_some( + char const* data, + std::size_t size); + /** Parse the remaining JSON immediately. This function is used to submit the last buffer, @@ -170,12 +176,18 @@ public: @param ec Set to the error, if any occurred. */ BOOST_JSON_DECL - std::size_t + void write( char const* data, std::size_t size, error_code& ec); + BOOST_JSON_DECL + void + write( + char const* data, + std::size_t size); + /** Indicate that no more serialized JSON remains. This function informs the parser that there is @@ -189,6 +201,10 @@ public: void write_eof(error_code& ec); + BOOST_JSON_DECL + void + write_eof(); + protected: using saved_state = char; diff --git a/include/boost/json/config.hpp b/include/boost/json/config.hpp index 109c2d7a..682b83bc 100644 --- a/include/boost/json/config.hpp +++ b/include/boost/json/config.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,21 +17,29 @@ namespace json { #ifndef BOOST_JSON_STANDALONE -/// The type of string view used by the library +/// The type of string view used by the library. using string_view = boost::string_view; -/// The type of error code used by the library +/// The type of error code used by the library. using error_code = boost::system::error_code; -/// The type of system error thrown by the library +/// The type of system error thrown by the library. using system_error = boost::system::system_error; -/// The type of error category used by the library +/// The type of error category used by the library. using error_category = boost::system::error_category; -/// The type of error condition used by the library +/// The type of error condition used by the library. using error_condition = boost::system::error_condition; +#ifdef GENERATING_DOCUMENTATION +/// Returns the generic error category used by the library. +error_category const& +generic_category(); +#else +using boost::system::generic_category; +#endif + #else using error_code = std::error_code; @@ -39,6 +47,7 @@ using error_category = std::error_category; using error_condition = std::error_condition; using string_view = std::string_view; using system_error = std::system_error; +using std::generic_category; #endif diff --git a/include/boost/json/detail/scalar_impl.hpp b/include/boost/json/detail/scalar_impl.hpp index 7fc56b7a..afc6f213 100644 --- a/include/boost/json/detail/scalar_impl.hpp +++ b/include/boost/json/detail/scalar_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/json/impl/basic_parser.ipp b/include/boost/json/impl/basic_parser.ipp index 671ec518..6159dee8 100644 --- a/include/boost/json/impl/basic_parser.ipp +++ b/include/boost/json/impl/basic_parser.ipp @@ -855,11 +855,24 @@ yield: return p - p0; } +std::size_t +basic_parser:: +write_some( + char const* const data, + std::size_t const size) +{ + error_code ec; + auto const n = + write_some(data, size, ec); + if(ec) + BOOST_JSON_THROW( + system_error(ec)); + return n; +} + //---------------------------------------------------------- -// Called to parse the rest of the document, this -// can be optimized by assuming no more data is coming. -std::size_t +void basic_parser:: write( char const* data, @@ -871,12 +884,22 @@ write( if(! ec) { if(n < size) - n += write_some( + write_some( data + n, size - n, ec); } - if(! ec) - write_eof(ec); - return n; +} + +void +basic_parser:: +write( + char const* data, + std::size_t size) +{ + error_code ec; + write(data, size, ec); + if(ec) + BOOST_JSON_THROW( + system_error(ec)); } //---------------------------------------------------------- @@ -959,6 +982,17 @@ write_eof(error_code& ec) } } +void +basic_parser:: +write_eof() +{ + error_code ec; + write_eof(ec); + if(ec) + BOOST_JSON_THROW( + system_error(ec)); +} + } // json } // boost diff --git a/include/boost/json/impl/parser.ipp b/include/boost/json/impl/parser.ipp index 2ea99c4b..71461493 100644 --- a/include/boost/json/impl/parser.ipp +++ b/include/boost/json/impl/parser.ipp @@ -208,6 +208,38 @@ release() noexcept return jv; } +value +parser:: +parse( + char const* data, + std::size_t size, + error_code& ec, + storage_ptr sp) +{ + start(std::move(sp)); + write(data, size, ec); + if(! ec) + write_eof(ec); + return release(); +} + +value +parser:: +parse( + char const* data, + std::size_t size, + storage_ptr sp) +{ + error_code ec; + auto jv = parse( + data, size, ec, + std::move(sp)); + if(ec) + BOOST_JSON_THROW( + system_error(ec)); + return release(); +} + //---------------------------------------------------------- template diff --git a/include/boost/json/parser.hpp b/include/boost/json/parser.hpp index 3fefebbb..e12f279c 100644 --- a/include/boost/json/parser.hpp +++ b/include/boost/json/parser.hpp @@ -139,6 +139,21 @@ public: value release() noexcept; + BOOST_JSON_DECL + value + parse( + char const* data, + std::size_t size, + error_code& ec, + storage_ptr sp = {}); + + BOOST_JSON_DECL + value + parse( + char const* data, + std::size_t size, + storage_ptr sp = {}); + private: template void