diff --git a/doc/qbk/02_08_parsing.qbk b/doc/qbk/02_08_parsing.qbk
index d4a0eee4..ec621327 100644
--- a/doc/qbk/02_08_parsing.qbk
+++ b/doc/qbk/02_08_parsing.qbk
@@ -38,6 +38,14 @@ functions and types to assist with parsing:
A structure used to select which extensions are
enabled during parsing.
]
+][
+ [__parser__]
+ [
+ A stateful DOM parser object which may be used
+ to efficiently parse a series of JSONs each
+ contained in a single contiguous character buffer,
+ returning each result as a __value__.
+ ]
][
[__stream_parser__]
[
@@ -89,8 +97,10 @@ structure and passing it by value. By default all extensions are disabled:
[doc_parsing_5]
-Using a compiler with support for C++20 features, [@https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers designated initializers] can be used to construct
-__parse_options__ with a less verbose but equally expressive syntax:
+Using a compiler with support for C++20 features,
+[@https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers designated initializers]
+can be used to construct __parse_options__ with a less verbose but equally
+expressive syntax:
[doc_parsing_6]
@@ -98,8 +108,8 @@ __parse_options__ with a less verbose but equally expressive syntax:
[heading Parser Instance]
-Instances of __stream_parser__ offer functionality beyond what is
-available when using the __parse__ free functions:
+Instances of __parser__ and __stream_parser__ offer functionality beyond
+what is available when using the __parse__ free functions:
* More control over memory
* Streaming API, parse input JSON incrementally
@@ -114,12 +124,12 @@ parsing more than one JSON, reducing the total number of dynamic
memory allocations.
To use the __stream_parser__, declare an instance. Then call
-[link json.ref.boost__json__parser.write `write`]
+[link json.ref.boost__json__stream_parser.write `write`]
zero or more times with successive buffers representing the input JSON.
When there are no more buffers, call
-[link json.ref.boost__json__parser.finish `finish`].
+[link json.ref.boost__json__stream_parser.finish `finish`].
The function
-[link json.ref.boost__json__parser.done `done`].
+[link json.ref.boost__json__stream_parser.done `done`].
returns `true` after a successful call to `write` or `finish`
if parsing is complete. This example persists the parser instance
in a class member to reuse across calls:
@@ -141,7 +151,7 @@ JSON in fixed-size amounts, providing these benefits:
In the following example a JSON is parsed from standard input a line
at a time. Error codes are used instead. The function
-[link json.ref.boost__json__parser.finish `finish`]
+[link json.ref.boost__json__stream_parser.finish `finish`]
is used to indicate the end of the input:
[doc_parsing_8]
@@ -165,7 +175,7 @@ allow some non-standard JSON extensions to be recognized:
[heading Controlling Memory]
After default construction, or after
-[link json.ref.boost__json__parser.reset `reset`]
+[link json.ref.boost__json__stream_parser.reset `reset`]
is called with no arguments, the __value__ produced after a successful
parse operation uses the default memory resource. To use a different
memory resource, call `reset` with the resource to use. Here we use
diff --git a/doc/qbk/main.qbk b/doc/qbk/main.qbk
index baa034d3..8aef243c 100644
--- a/doc/qbk/main.qbk
+++ b/doc/qbk/main.qbk
@@ -64,6 +64,7 @@
[def __number_cast__ [link json.ref.boost__json__number_cast `number_cast`]]
[def __object__ [link json.ref.boost__json__object `object`]]
[def __parse__ [link json.ref.boost__json__parse `parse`]]
+[def __parser__ [link json.ref.boost__json__parser `parser`]]
[def __parse_options__ [link json.ref.boost__json__parse_options `parse_options`]]
[def __polymorphic_allocator__ [link json.ref.boost__json__polymorphic_allocator `polymorphic_allocator`]]
[def __serialize__ [link json.ref.boost__json__serialize `serialize`]]
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index b2a0b23f..4fc5a64e 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -25,6 +25,7 @@
key_value_pairmonotonic_resourceobject
+ parserparse_optionsserializerstatic_resource
diff --git a/include/boost/json.hpp b/include/boost/json.hpp
index 313425ba..06be6a15 100644
--- a/include/boost/json.hpp
+++ b/include/boost/json.hpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/include/boost/json/impl/parse.ipp b/include/boost/json/impl/parse.ipp
index 793c1c04..bf97555e 100644
--- a/include/boost/json/impl/parse.ipp
+++ b/include/boost/json/impl/parse.ipp
@@ -12,7 +12,7 @@
#define BOOST_JSON_IMPL_PARSE_IPP
#include
-#include
+#include
#include
BOOST_JSON_NS_BEGIN
@@ -25,17 +25,12 @@ parse(
const parse_options& opt)
{
unsigned char temp[BOOST_JSON_STACK_BUFFER_SIZE];
- stream_parser p(
+ parser p(
storage_ptr(),
opt,
temp, sizeof(temp));
p.reset(std::move(sp));
- p.write(
- s.data(),
- s.size(),
- ec);
- if(! ec)
- p.finish(ec);
+ p.write(s, ec);
if(ec)
return nullptr;
return p.release();
diff --git a/include/boost/json/impl/parser.ipp b/include/boost/json/impl/parser.ipp
new file mode 100644
index 00000000..5f8d309d
--- /dev/null
+++ b/include/boost/json/impl/parser.ipp
@@ -0,0 +1,151 @@
+//
+// 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/cppalliance/json
+//
+
+#ifndef BOOST_JSON_IMPL_PARSER_IPP
+#define BOOST_JSON_IMPL_PARSER_IPP
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+BOOST_JSON_NS_BEGIN
+
+parser::
+parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ unsigned char* buffer,
+ std::size_t size) noexcept
+ : p_(
+ opt,
+ std::move(sp),
+ buffer,
+ size)
+{
+ reset();
+}
+
+parser::
+parser(
+ storage_ptr sp,
+ parse_options const& opt) noexcept
+ : p_(
+ opt,
+ std::move(sp),
+ nullptr,
+ 0)
+{
+ reset();
+}
+
+void
+parser::
+reset(storage_ptr sp) noexcept
+{
+ p_.reset();
+ p_.handler().st.reset(sp);
+}
+
+std::size_t
+parser::
+write_some(
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+{
+ auto const n = p_.write_some(
+ false, data, size, ec);
+ if(! ec)
+ {
+ if(! p_.done())
+ {
+ ec = error::incomplete;
+ p_.fail(ec);
+ }
+ }
+ return n;
+}
+
+std::size_t
+parser::
+write_some(
+ char const* data,
+ std::size_t size)
+{
+ error_code ec;
+ auto const n = p_.write_some(
+ true, data, size, ec);
+ if(ec)
+ detail::throw_system_error(ec,
+ BOOST_CURRENT_LOCATION);
+ return n;
+}
+
+std::size_t
+parser::
+write(
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+{
+ auto const n = write_some(
+ data, size, ec);
+ if(! ec)
+ {
+ if(! p_.done())
+ {
+ ec = error::incomplete;
+ p_.fail(ec);
+ }
+ else if(n < size)
+ {
+ ec = error::extra_data;
+ p_.fail(ec);
+ }
+ }
+ return n;
+}
+
+std::size_t
+parser::
+write(
+ char const* data,
+ std::size_t size)
+{
+ error_code ec;
+ auto const n = write(
+ data, size, ec);
+ if(ec)
+ detail::throw_system_error(ec,
+ BOOST_CURRENT_LOCATION);
+ return n;
+}
+
+value
+parser::
+release()
+{
+ if( ! p_.done())
+ {
+ // prevent undefined behavior
+ if(! p_.last_error())
+ p_.fail(error::incomplete);
+ detail::throw_system_error(
+ p_.last_error(),
+ BOOST_CURRENT_LOCATION);
+ }
+ return p_.handler().st.release();
+}
+
+BOOST_JSON_NS_END
+
+#endif
diff --git a/include/boost/json/parser.hpp b/include/boost/json/parser.hpp
new file mode 100644
index 00000000..07c20087
--- /dev/null
+++ b/include/boost/json/parser.hpp
@@ -0,0 +1,868 @@
+//
+// 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/cppalliance/json
+//
+
+#ifndef BOOST_JSON_PARSER_HPP
+#define BOOST_JSON_PARSER_HPP
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+/** A DOM parser for serialized JSON.
+
+ This class is used to incrementally parse JSON
+ from character buffers into a @ref value container.
+
+ @par Usage
+
+ Parsing for a new JSON may begin after the parser is
+ constructed, or after calling @ref reset, optionally
+ passing the storage pointer to be used by the
+ @ref value container into which the parsed results
+ are stored. After the parse is started, call
+ @ref write_some or @ref write to provide buffers
+ of characters of the JSON. When there are no more
+ buffers, call @ref finish. The parse is complete
+ when the function @ref done returns `true`, or
+ when a non-successful error code is returned.
+ To retrieve the result on success, call @ref release.
+
+ @par Incremental Parsing
+
+ The parser allows the input to be presented in
+ multiple character buffers. This is useful when
+ not all of the serialized JSON is present at once
+ and it is desirable to process the data as it becomes
+ available, such as when reading from a network socket
+ or other device. The incremental interface may also
+ be used to bound the amount of work performed in each
+ parsing cycle.
+
+ @par Temporary Storage
+
+ The parser may dynamically allocate temporary
+ storage as needed to accommodate the nesting level
+ of the JSON being parsed. Temporary storage is
+ first obtained from an optional, caller-owned
+ buffer specified upon construction. When that
+ is exhausted, the next allocation uses the
+ @ref memory_resource passed to the constructor; if
+ no such argument is specified, the default memory
+ resource is used instead. Temporary storage is
+ freed only when the parser is destroyed, improving
+ performance when the parser is reused to parse
+ multiple JSONs.
+\n
+ It is important to note that the @ref memory_resource
+ supplied upon construction is used for temporary
+ storage only, and not for allocating the elements
+ which make up the parsed value. That other memory
+ resource is optionally supplied in each call
+ to @ref reset.
+
+ @par Duplicate Keys
+
+ If there are object elements with duplicate keys;
+ that is, if multiple elements in an object have
+ keys that compare equal, only the last equivalent
+ element will be inserted.
+
+ @par Non-Standard JSON
+
+ The @ref parse_options structure optionally
+ provided upon construction is used to customize
+ some parameters of the parser, including which
+ non-standard JSON extensions should be allowed.
+ A default-constructed parse options allows only
+ standard JSON.
+
+ @par Thread Safety
+
+ Distinct instances may be accessed concurrently.
+ Non-const member functions of a shared instance
+ may not be called concurrently with any other
+ member functions of that instance.
+
+ @see
+ @ref parse,
+ @ref parse_options.
+*/
+class parser
+{
+ basic_parser p_;
+
+public:
+ /// Copy constructor (deleted)
+ parser(
+ parser const&) = delete;
+
+ /// Copy assignment (deleted)
+ parser& operator=(
+ parser const&) = delete;
+
+ /** Destructor.
+
+ All dynamically allocated memory, including
+ any incomplete parsing results, is freed.
+
+ @par Complexity
+ Linear in the size of partial results
+
+ @par Exception Safety
+ No-throw guarantee.
+ */
+ ~parser() = default;
+
+ /** Constructor.
+
+ This constructs a new parser which first uses the
+ caller-owned storage pointed to by `temp_buffer`
+ for temporary storage, falling back to the memory
+ resource `sp` if needed. The parser will use the
+ specified parsing options.
+ \n
+ The parsed value will use the default memory resource
+ for storage. To use a different resource, call
+ @ref reset after construction.
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ No-throw guarantee.
+
+ @param sp The memory resource to use for temporary storage
+ when `buffer` is exhausted.
+
+ @param opt The parsing options to use.
+
+ @param buffer A pointer to valid memory of at least
+ `size` bytes for the parser to use for temporary storage.
+ Ownership is not transferred, the caller is responsible
+ for ensuring the lifetime of the memory pointed to by
+ `buffer` extends until the parser is destroyed.
+
+ @param size The number of valid bytes in `buffer`.
+ */
+ BOOST_JSON_DECL
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ unsigned char* buffer,
+ std::size_t size) noexcept;
+
+ /** Constructor.
+
+ This constructs a new parser which uses the default
+ memory resource for temporary storage, and accepts
+ only strict JSON.
+ \n
+ The parsed value will use the default memory resource
+ for storage. To use a different resource, call
+ @ref reset after construction.
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ No-throw guarantee.
+ */
+ parser() noexcept
+ : parser({}, {})
+ {
+ }
+
+ /** Constructor.
+
+ This constructs a new parser which uses the specified
+ memory resource for temporary storage, and is
+ configured to use the specified parsing options.
+ \n
+ The parsed value will use the default memory resource
+ for storage. To use a different resource, call
+ @ref reset after construction.
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ No-throw guarantee.
+
+ @param sp The memory resource to use for temporary storage.
+
+ @param opt The parsing options to use.
+ */
+ BOOST_JSON_DECL
+ parser(
+ storage_ptr sp,
+ parse_options const& opt) noexcept;
+
+ /** Constructor.
+
+ This constructs a new parser which uses the specified
+ memory resource for temporary storage, and accepts
+ only strict JSON.
+ \n
+ The parsed value will use the default memory resource
+ for storage. To use a different resource, call
+ @ref reset after construction.
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ No-throw guarantee.
+
+ @param sp The memory resource to use for temporary storage.
+ */
+ explicit
+ parser(storage_ptr sp) noexcept
+ : parser(std::move(sp), {})
+ {
+ }
+
+ /** Constructor.
+
+ This constructs a new parser which first uses the
+ caller-owned storage `buffer` for temporary storage,
+ falling back to the memory resource `sp` if needed.
+ The parser will use the specified parsing options.
+ \n
+ The parsed value will use the default memory resource
+ for storage. To use a different resource, call
+ @ref reset after construction.
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ No-throw guarantee.
+
+ @param sp The memory resource to use for temporary storage
+ when `buffer` is exhausted.
+
+ @param opt The parsing options to use.
+
+ @param buffer A buffer for the parser to use for temporary
+ storage. Ownership is not transferred, the caller is
+ responsible for ensuring the lifetime of `buffer` extends
+ until the parser is destroyed.
+ */
+ template
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ unsigned char(&buffer)[N]) noexcept
+ : parser(std::move(sp),
+ opt, &buffer[0], N)
+ {
+ }
+
+#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+ /** Constructor (delegating)
+
+ @par Effects
+ @code
+ parser( std::move(sp), opt,
+ reinterpret_cast( temp_buffer ), N )
+ @endcode
+ */
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ std::byte* temp_buffer,
+ std::size_t temp_size) noexcept
+ : parser(sp, opt,
+ reinterpret_cast(
+ temp_buffer), temp_size)
+ {
+ }
+
+ /** Constructor (delegating)
+
+ @par Effects
+ @code
+ parser( std::move(sp), opt, &buffer[0], N )
+ @endcode
+ */
+ template
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ std::byte(&buffer)[N]) noexcept
+ : parser(std::move(sp),
+ opt, &buffer[0], N)
+ {
+ }
+#endif
+
+#ifndef BOOST_JSON_DOCS
+ // Safety net for accidental buffer overflows
+ template
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ unsigned char(&buffer)[N],
+ std::size_t n) noexcept
+ : parser(std::move(sp),
+ opt, &buffer[0], n)
+ {
+ // If this goes off, check your parameters
+ // closely, chances are you passed an array
+ // thinking it was a pointer.
+ BOOST_ASSERT(n <= N);
+ }
+
+#ifdef __cpp_lib_byte
+ // Safety net for accidental buffer overflows
+ template
+ parser(
+ storage_ptr sp,
+ parse_options const& opt,
+ std::byte(&buffer)[N], std::size_t n) noexcept
+ : parser(std::move(sp),
+ opt, &buffer[0], n)
+ {
+ // If this goes off, check your parameters
+ // closely, chances are you passed an array
+ // thinking it was a pointer.
+ BOOST_ASSERT(n <= N);
+ }
+#endif
+#endif
+
+ /** Returns the current depth of the JSON being parsed.
+
+ The parsing depth is the total current nesting
+ level of arrays and objects.
+
+ @par Complexity
+
+ Constant.
+
+ @par Exception Safety
+
+ No-throw guarantee.
+ */
+ std::size_t
+ depth() const noexcept
+ {
+ return p_.depth();
+ }
+
+ /** Start parsing JSON incrementally.
+
+ This function is used to reset the parser to
+ prepare it for parsing a new JSON. Any previous
+ partial results are destroyed.
+
+ @par Complexity
+ Constant or linear in the size of any previous
+ partial parsing results.
+
+ @par Exception Safety
+ No-throw guarantee.
+
+ @param sp A pointer to the @ref memory_resource
+ to use for the resulting @ref value. The parser
+ will acquire shared ownership.
+ */
+ BOOST_JSON_DECL
+ void
+ reset(storage_ptr sp = {}) noexcept;
+
+ /** Parse some of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, the function will
+ return the number of characters actually used
+ which may be less than the size of the input.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param data A pointer to a buffer of `size`
+ characters to parse.
+
+ @param size The number of characters pointed to
+ by `data`.
+
+ @param ec Set to the error, if any occurred.
+ */
+ BOOST_JSON_DECL
+ std::size_t
+ write_some(
+ char const* data,
+ std::size_t size,
+ error_code& ec);
+
+ /** Parse some of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, the function will
+ return the number of characters actually used
+ which may be less than the size of the input.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param data A pointer to a buffer of `size`
+ characters to parse.
+
+ @param size The number of characters pointed to
+ by `data`.
+
+ @throw system_error Thrown on error.
+ */
+ BOOST_JSON_DECL
+ std::size_t
+ write_some(
+ char const* data,
+ std::size_t size);
+
+ /** Parse some of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, the function will
+ return the number of characters actually used
+ which may be less than the size of the input.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param s The character string to parse.
+
+ @param ec Set to the error, if any occurred.
+ */
+ std::size_t
+ write_some(
+ string_view s,
+ error_code& ec)
+ {
+ return write_some(
+ s.data(), s.size(), ec);
+ }
+
+ /** Parse some of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, the function will
+ return the number of characters actually used
+ which may be less than the size of the input.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param s The character string to parse.
+
+ @throw system_error Thrown on error.
+ */
+ std::size_t
+ write_some(
+ string_view s)
+ {
+ return write_some(
+ s.data(), s.size());
+ }
+
+ /** Parse all of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, but not all
+ characters in the buffer were consumed, an
+ error occurs.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param data A pointer to a buffer of `size`
+ characters to parse.
+
+ @param size The number of characters pointed to
+ by `data`.
+
+ @param ec Set to the error, if any occurred.
+ */
+ BOOST_JSON_DECL
+ std::size_t
+ write(
+ char const* data,
+ std::size_t size,
+ error_code& ec);
+
+ /** Parse all of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, but not all
+ characters in the buffer were consumed, an
+ error occurs.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param data A pointer to a buffer of `size`
+ characters to parse.
+
+ @param size The number of characters pointed to
+ by `data`.
+
+ @throw system_error Thrown on error.
+ */
+ BOOST_JSON_DECL
+ std::size_t
+ write(
+ char const* data,
+ std::size_t size);
+
+ /** Parse all of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, but not all
+ characters in the buffer were consumed, an
+ error occurs.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param s The character string to parse.
+
+ @param ec Set to the error, if any occurred.
+ */
+ std::size_t
+ write(
+ string_view s,
+ error_code& ec)
+ {
+ return write(
+ s.data(), s.size(), ec);
+ }
+
+ /** Parse all of an input string as JSON, incrementally.
+
+ This function parses the JSON in the specified
+ buffer. The parse proceeds from the current
+ state, which is at the beginning of a new JSON
+ or in the middle of the current JSON if any
+ characters were already parsed.
+ \n
+ The characters in the buffer are processed
+ starting from the beginning, until one of the
+ following conditions is met:
+
+ @li All of the characters in the buffer have
+ been parsed, or
+
+ @li A complete JSON is parsed, including any
+ optional trailing whitespace in the buffer, or
+
+ @li A parsing error occurs.
+
+ If a complete JSON is parsed, but not all
+ characters in the buffer were consumed, an
+ error occurs.
+ \n
+ The supplied buffer does not need to contain the
+ entire JSON. Subsequent calls can provide more
+ serialized data, allowing JSON to be processed
+ incrementally. The end of the serialized JSON
+ is be indicated by calling @ref finish.
+
+ @par Complexity
+ Linear in `size`.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The number of characters consumed from
+ the buffer.
+
+ @param s The character string to parse.
+
+ @throw system_error Thrown on error.
+ */
+ std::size_t
+ write(
+ string_view s)
+ {
+ return write(
+ s.data(), s.size());
+ }
+
+ /** Return the parsed JSON as a @ref value.
+
+ This returns the parsed value, or throws
+ an exception if the parsing is incomplete or
+ failed. It is necessary to call @ref reset
+ after calling this function in order to parse
+ another JSON.
+
+ @par Effects
+ @code
+ if( ! this->done() )
+ this->finish();
+ @endcode
+ @note
+
+ @par Complexity
+ Constant.
+
+ @par Exception Safety
+ Basic guarantee.
+ Calls to `memory_resource::allocate` may throw.
+ Upon error, the only valid operations are
+ @ref reset and destruction.
+
+ @return The parsed value. Ownership of this
+ value is transferred to the caller.
+
+ @throw system_error Thrown on failure.
+ */
+ BOOST_JSON_DECL
+ value
+ release();
+};
+
+BOOST_JSON_NS_END
+
+#endif
diff --git a/include/boost/json/src.hpp b/include/boost/json/src.hpp
index 3abc2502..a6153160 100644
--- a/include/boost/json/src.hpp
+++ b/include/boost/json/src.hpp
@@ -35,6 +35,7 @@ in a translation unit of the program.
#include
#include
#include
+#include
#include
#include
#include
diff --git a/test/parser.cpp b/test/parser.cpp
new file mode 100644
index 00000000..25c86031
--- /dev/null
+++ b/test/parser.cpp
@@ -0,0 +1,28 @@
+//
+// 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/cppalliance/json
+//
+
+// Test that header file is self-contained.
+#include
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class parser_test
+{
+public:
+ void
+ run()
+ {
+ }
+};
+
+TEST_SUITE(parser_test, "boost.json.parser");
+
+BOOST_JSON_NS_END