2
0
mirror of https://github.com/boostorg/json.git synced 2026-01-19 04:12:14 +00:00

parser docs, test, and tidy

This commit is contained in:
Vinnie Falco
2020-09-27 13:55:59 -07:00
parent 47fdfb0840
commit 7882ccf866
7 changed files with 630 additions and 375 deletions

View File

@@ -39,7 +39,7 @@ BOOST_JSON_NS_BEGIN
To use, first declare a variable of type
`basic_parser<T>` where `T` meets the handler
requirements specified below. Then call
@ref write one or more times with the input,
@ref write_some one or more times with the input,
setting `more = false` on the final buffer.
The parsing events are realized through member
function calls on the handler, which exists
@@ -563,8 +563,9 @@ public:
/** Return the last error.
This returns the last error code which was
generated in the most recent call to @ref write.
This returns the last error code which
was generated in the most recent call
to @ref write_some.
@par Complexity
Constant.

View File

@@ -24,11 +24,9 @@ parse(
storage_ptr sp,
const parse_options& opt)
{
unsigned char temp[BOOST_JSON_STACK_BUFFER_SIZE];
parser p(
storage_ptr(),
opt,
temp, sizeof(temp));
unsigned char temp[
BOOST_JSON_STACK_BUFFER_SIZE];
parser p(storage_ptr(), opt, temp);
p.reset(std::move(sp));
p.write(s, ec);
if(ec)

View File

@@ -64,14 +64,7 @@ write_some(
{
auto const n = p_.write_some(
false, data, size, ec);
if(! ec)
{
if(! p_.done())
{
ec = error::incomplete;
p_.fail(ec);
}
}
BOOST_ASSERT(ec || p_.done());
return n;
}
@@ -82,8 +75,8 @@ write_some(
std::size_t size)
{
error_code ec;
auto const n = p_.write_some(
true, data, size, ec);
auto const n = write_some(
data, size, ec);
if(ec)
detail::throw_system_error(ec,
BOOST_CURRENT_LOCATION);
@@ -99,18 +92,10 @@ write(
{
auto const n = write_some(
data, size, ec);
if(! ec)
if(! ec && n < size)
{
if(! p_.done())
{
ec = error::incomplete;
p_.fail(ec);
}
else if(n < size)
{
ec = error::extra_data;
p_.fail(ec);
}
ec = error::extra_data;
p_.fail(ec);
}
return n;
}

View File

@@ -73,8 +73,8 @@ write_some(
std::size_t size)
{
error_code ec;
auto const n = p_.write_some(
true, data, size, ec);
auto const n = write_some(
data, size, ec);
if(ec)
detail::throw_system_error(ec,
BOOST_CURRENT_LOCATION);

View File

@@ -22,35 +22,42 @@ BOOST_JSON_NS_BEGIN
//----------------------------------------------------------
/** A DOM parser for serialized JSON.
/** A DOM parser for JSON contained in a single buffer.
This class is used to incrementally parse JSON
from character buffers into a @ref value container.
This class is used to parse a JSON contained in a
single character buffer, 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.
To use the parser first construct it, then optionally
call @ref reset to specify a @ref storage_ptr to use
for the resulting @ref value. Then call @ref write
to parse a character buffer containing a complete
JSON. If the parse is successful, call @ref release
to take ownership of the value:
@code
parser p; // construct a parser
size_t n = p.write( "[1,2,3]" ); // parse a complete JSON
assert( n == 7 ); // all characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Incremental Parsing
@par Extra Data
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.
When the character buffer provided as input contains
additional data that is not part of the complete
JSON, an error is returned. The @ref write_some
function is an alternative which allows the parse
to finish early, without consuming all the characters
in the buffer. This allows parsing of a buffer
containing multiple individual JSONs or containing
different protocol data:
@code
parser p; // construct a parser
size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON
assert( n == 8 ); // only some characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Temporary Storage
@@ -62,10 +69,10 @@ BOOST_JSON_NS_BEGIN
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.
resource is used. Temporary storage is freed only
when the parser is destroyed; The performance of
parsing multiple JSONs may be improved by reusing
the same parser instance.
\n
It is important to note that the @ref memory_resource
supplied upon construction is used for temporary
@@ -85,7 +92,7 @@ BOOST_JSON_NS_BEGIN
The @ref parse_options structure optionally
provided upon construction is used to customize
some parameters of the parser, including which
some parameters of the parser, including which
non-standard JSON extensions should be allowed.
A default-constructed parse options allows only
standard JSON.
@@ -99,7 +106,8 @@ BOOST_JSON_NS_BEGIN
@see
@ref parse,
@ref parse_options.
@ref parse_options,
@ref stream_parser.
*/
class parser
{
@@ -129,15 +137,15 @@ public:
/** Constructor.
This constructs a new parser which first uses the
caller-owned storage pointed to by `temp_buffer`
This constructs a new parser which first uses
the caller-owned storage pointed to by `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.
The parsed value will use the default memory
resource for storage. To use a different resource,
call @ref reset after construction.
@par Complexity
Constant.
@@ -145,8 +153,8 @@ public:
@par Exception Safety
No-throw guarantee.
@param sp The memory resource to use for temporary storage
when `buffer` is exhausted.
@param sp The memory resource to use for
temporary storage after `buffer` is exhausted.
@param opt The parsing options to use.
@@ -171,9 +179,9 @@ public:
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.
The parsed value will use the default memory
resource for storage. To use a different resource,
call @ref reset after construction.
@par Complexity
Constant.
@@ -188,13 +196,14 @@ public:
/** Constructor.
This constructs a new parser which uses the specified
memory resource for temporary storage, and is
configured to use the specified parsing options.
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.
The parsed value will use the default memory
resource for storage. To use a different resource,
call @ref reset after construction.
@par Complexity
Constant.
@@ -213,13 +222,13 @@ public:
/** Constructor.
This constructs a new parser which uses the specified
memory resource for temporary storage, and accepts
only strict JSON.
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.
The parsed value will use the default memory
resource for storage. To use a different resource,
call @ref reset after construction.
@par Complexity
Constant.
@@ -242,9 +251,9 @@ public:
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.
The parsed value will use the default memory
resource for storage. To use a different resource,
call @ref reset after construction.
@par Complexity
Constant.
@@ -252,15 +261,15 @@ public:
@par Exception Safety
No-throw guarantee.
@param sp The memory resource to use for temporary storage
when `buffer` is exhausted.
@param sp The memory resource to use for
temporary storage after `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.
@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<std::size_t N>
parser(
@@ -273,31 +282,73 @@ public:
}
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
/** Constructor (delegating)
/** Constructor.
@par Effects
@code
parser( std::move(sp), opt,
reinterpret_cast<unsigned char*>( temp_buffer ), N )
@endcode
This constructs a new parser which first uses
the caller-owned storage pointed to by `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 after `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`.
*/
parser(
storage_ptr sp,
parse_options const& opt,
std::byte* temp_buffer,
std::size_t temp_size) noexcept
: parser(sp, opt,
reinterpret_cast<unsigned char*>(
temp_buffer), temp_size)
std::byte* buffer,
std::size_t size) noexcept
: parser(sp, opt, reinterpret_cast<
unsigned char*>(buffer), size)
{
}
/** Constructor (delegating)
/** Constructor.
@par Effects
@code
parser( std::move(sp), opt, &buffer[0], N )
@endcode
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 after `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<std::size_t N>
parser(
@@ -345,30 +396,11 @@ public:
#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.
/** Reset the parser for a new JSON.
This function is used to reset the parser to
prepare it for parsing a new JSON. Any previous
partial results are destroyed.
prepare it for parsing a new complete JSON.
Any previous partial results are destroyed.
@par Complexity
Constant or linear in the size of any previous
@@ -385,35 +417,24 @@ public:
void
reset(storage_ptr sp = {}) noexcept;
/** Parse some of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. Additional
characters past the end of the complete JSON
are ignored. The function returns the actual
number of characters parsed, which may be less
than the size of the input. This allows parsing
of a buffer containing multiple individual JSONs
or containing different protocol data:
@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 Example
@code
parser p; // construct a parser
size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON
assert( n == 8 ); // only some characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -421,8 +442,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -442,35 +463,24 @@ public:
std::size_t size,
error_code& ec);
/** Parse some of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. Additional
characters past the end of the complete JSON
are ignored. The function returns the actual
number of characters parsed, which may be less
than the size of the input. This allows parsing
of a buffer containing multiple individual JSONs
or containing different protocol data:
@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 Example
@code
parser p; // construct a parser
size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON
assert( n == 8 ); // only some characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -478,8 +488,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -498,35 +508,24 @@ public:
char const* data,
std::size_t size);
/** Parse some of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. Additional
characters past the end of the complete JSON
are ignored. The function returns the actual
number of characters parsed, which may be less
than the size of the input. This allows parsing
of a buffer containing multiple individual JSONs
or containing different protocol data:
@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 Example
@code
parser p; // construct a parser
size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON
assert( n == 8 ); // only some characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -534,8 +533,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -553,35 +552,24 @@ public:
s.data(), s.size(), ec);
}
/** Parse some of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. Additional
characters past the end of the complete JSON
are ignored. The function returns the actual
number of characters parsed, which may be less
than the size of the input. This allows parsing
of a buffer containing multiple individual JSONs
or containing different protocol data:
@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 Example
@code
parser p; // construct a parser
size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON
assert( n == 8 ); // only some characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -589,8 +577,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -607,35 +595,21 @@ public:
s.data(), s.size());
}
/** Parse all of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. The entire
buffer must be consumed; if there are additional
characters past the end of the complete JSON,
the parse fails and an error is returned.
@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 Example
@code
parser p; // construct a parser
size_t n = p.write( "[1,2,3]" ); // parse a complete JSON
assert( n == 7 ); // all characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -643,8 +617,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -664,35 +638,21 @@ public:
std::size_t size,
error_code& ec);
/** Parse all of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. The entire
buffer must be consumed; if there are additional
characters past the end of the complete JSON,
the parse fails and an error is returned.
@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 Example
@code
parser p; // construct a parser
size_t n = p.write( "[1,2,3]" ); // parse a complete JSON
assert( n == 7 ); // all characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -700,8 +660,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -720,35 +680,21 @@ public:
char const* data,
std::size_t size);
/** Parse all of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. The entire
buffer must be consumed; if there are additional
characters past the end of the complete JSON,
the parse fails and an error is returned.
@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 Example
@code
parser p; // construct a parser
size_t n = p.write( "[1,2,3]" ); // parse a complete JSON
assert( n == 7 ); // all characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -756,8 +702,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -775,35 +721,21 @@ public:
s.data(), s.size(), ec);
}
/** Parse all of an input string as JSON, incrementally.
/** Parse a buffer containing a complete JSON.
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:
This function parses a complete JSON contained
in the specified character buffer. The entire
buffer must be consumed; if there are additional
characters past the end of the complete JSON,
the parse fails and an error is returned.
@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 Example
@code
parser p; // construct a parser
size_t n = p.write( "[1,2,3]" ); // parse a complete JSON
assert( n == 7 ); // all characters consumed
value jv = p.release(); // take ownership of the value
@endcode
@par Complexity
Linear in `size`.
@@ -811,8 +743,8 @@ public:
@par Exception Safety
Basic guarantee.
Calls to `memory_resource::allocate` may throw.
Upon error, the only valid operations are
@ref reset and destruction.
Upon error or exception, subsequent calls will
fail until @ref reset is called to parse a new JSON.
@return The number of characters consumed from
the buffer.
@@ -837,22 +769,9 @@ public:
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.

View File

@@ -154,7 +154,7 @@ struct is_pilfer_constructible
};
@endcode
Pilfer construction is performed using @ref pilfer:
Pilfer construction is performed using @ref pilfer :
@code
{

View File

@@ -17,9 +17,361 @@ BOOST_JSON_NS_BEGIN
class parser_test
{
public:
void
testCtors()
{
// parser(parser const&)
BOOST_STATIC_ASSERT(
! std::is_copy_constructible<parser>::value);
// operator=(parser const&)
BOOST_STATIC_ASSERT(
! std::is_copy_assignable<parser>::value);
// ~parser()
{
// implied
}
// parser(storage_ptr, parse_options, unsigned char*, size_t)
{
unsigned char buf[256];
parser p(
storage_ptr(),
parse_options(),
&buf[0],
sizeof(buf));
}
// parser()
{
parser p;
}
// parser(storage_ptr, parse_options)
{
parser p(storage_ptr{}, parse_options());
}
// parser(storage_ptr)
{
parser p(storage_ptr{});
}
// parser(storage_ptr, parse_options, unsigned char[])
{
unsigned char buf[256];
parser p(
storage_ptr(),
parse_options(),
buf);
}
#if defined(__cpp_lib_byte)
// parser(storage_ptr, parse_options, std::byte*, size_t)
{
std::byte buf[256];
parser p(
storage_ptr(),
parse_options(),
&buf[0],
sizeof(buf));
}
// parser(storage_ptr, parse_options, std::byte[])
{
std::byte buf[256];
parser p(
storage_ptr(),
parse_options(),
buf);
}
#endif
// parser(storage_ptr, parse_options, unsigned char[], size_t)
{
unsigned char buf[256];
parser p(
storage_ptr(),
parse_options(),
buf,
sizeof(buf));
}
#if defined(__cpp_lib_byte)
// parser(storage_ptr, parse_options, std::byte[], size_t)
{
std::byte buf[256];
parser p(
storage_ptr(),
parse_options(),
buf,
sizeof(buf));
}
#endif
}
void
testMembers()
{
// reset
{
parser p;
p.reset();
}
// write_some(char const*, size_t, error_code&)
{
// valid json
{
parser p;
error_code ec;
auto const n =
p.write_some("null", 4, ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 4);
}
// valid json with trailing space
{
parser p;
error_code ec;
auto const n =
p.write_some("null ", 5, ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 5);
}
// valid json with invalid trailing char
{
parser p;
error_code ec;
auto const n =
p.write_some("null*", 5, ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 4);
}
// partial json
{
parser p;
error_code ec;
p.write_some("nul", 3, ec);
BOOST_TEST(ec);
}
}
// write_some(string_view, error_code&)
{
// valid json
{
parser p;
error_code ec;
auto const n =
p.write_some("null", ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 4);
}
// partial json
{
parser p;
error_code ec;
p.write_some("nul", ec);
BOOST_TEST(ec);
}
}
// write_some(char const*, size_t)
{
// valid json with trailing space
{
parser p;
auto const n =
p.write_some("null ", 5);
BOOST_TEST(n == 5);
}
// partial json
{
parser p;
BOOST_TEST_THROWS(
p.write_some("nul", 3),
system_error);
}
}
// write_some(string_view)
{
// valid json with trailing space
{
parser p;
auto const n =
p.write_some("null ");
BOOST_TEST(n == 5);
}
// partial json
{
parser p;
BOOST_TEST_THROWS(
p.write_some("nul"),
system_error);
}
}
//--------------------------------------------------
// write(char const*, size_t, error_code&)
{
// valid json
{
parser p;
error_code ec;
auto const n =
p.write("null", 4, ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 4);
}
// valid json with trailing space
{
parser p;
error_code ec;
auto const n =
p.write("null ", 5, ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 5);
}
// valid json with invalid trailing char
{
parser p;
error_code ec;
p.write("null*", 5, ec);
BOOST_TEST(ec);
}
// partial json
{
parser p;
error_code ec;
p.write("nul", 3, ec);
BOOST_TEST(ec);
}
}
// write(string_view, error_code&)
{
// valid json
{
parser p;
error_code ec;
auto const n =
p.write("null", ec);
BOOST_TEST(! ec);
BOOST_TEST(n == 4);
}
// partial json
{
parser p;
error_code ec;
p.write("nul", ec);
BOOST_TEST(ec);
}
}
// write(char const*, size_t)
{
// valid json with trailing space
{
parser p;
auto const n =
p.write("null ", 5);
BOOST_TEST(n == 5);
}
// valid json with invalid trailing char
{
parser p;
BOOST_TEST_THROWS(
p.write("null*", 5),
system_error);
}
// partial json
{
parser p;
BOOST_TEST_THROWS(
p.write("nul", 3),
system_error);
}
}
// write(string_view)
{
// valid json with trailing space
{
parser p;
auto const n =
p.write("null ");
BOOST_TEST(n == 5);
}
// valid json with invalid trailing char
{
parser p;
BOOST_TEST_THROWS(
p.write("null*"),
system_error);
}
// partial json
{
parser p;
BOOST_TEST_THROWS(
p.write("nul"),
system_error);
}
}
// release
{
// valid json
{
parser p;
p.write("[1,2,3]");
BOOST_TEST(p.release() ==
value({1,2,3}));
}
// release with no write
{
parser p;
BOOST_TEST_THROWS(
p.release(),
system_error);
}
// release after error
{
parser p;
error_code ec;
p.write("nul", ec);
BOOST_TEST(ec);
BOOST_TEST_THROWS(
p.release(),
system_error);
}
}
}
void
run()
{
testCtors();
testMembers();
}
};