Use return channel in parser

This commit is contained in:
Vinnie Falco 2020-03-28 14:02:04 -07:00
parent 8e34c77783
commit 79ba1a8198
8 changed files with 613 additions and 537 deletions

View File

@ -365,24 +365,25 @@ class boost_vec_impl : public any_impl
vec_parser() {}
~vec_parser() {}
void on_document_begin(error_code&) override {}
void on_document_end(error_code&) override {}
void on_object_begin(error_code&) override {}
void on_object_end(std::size_t, error_code&) override {}
void on_array_begin(error_code&) override {}
void on_array_end(std::size_t, error_code&) override {}
void on_key_part(string_view, error_code&) override {}
void on_key( string_view, error_code&) override {}
void on_string_part(string_view, error_code&) override {}
void on_string(string_view, error_code&) override {}
void on_int64(std::int64_t, error_code&) override {}
void on_uint64(std::uint64_t, error_code&) override {}
void on_double(double d, error_code&) override
bool on_document_begin(error_code&) override { return true; }
bool on_document_end(error_code&) override { return true; }
bool on_object_begin(error_code&) override { return true; }
bool on_object_end(std::size_t, error_code&) override { return true; }
bool on_array_begin(error_code&) override { return true; }
bool on_array_end(std::size_t, error_code&) override { return true; }
bool on_key_part(string_view, error_code&) override { return true; }
bool on_key( string_view, error_code&) override { return true; }
bool on_string_part(string_view, error_code&) override { return true; }
bool on_string(string_view, error_code&) override { return true; }
bool on_int64(std::int64_t, error_code&) override { return true; }
bool on_uint64(std::uint64_t, error_code&) override { return true; }
bool on_double(double d, error_code&) override
{
vec_.push_back(d);
return true;
}
void on_bool(bool, error_code&) override {}
void on_null(error_code&) override {}
bool on_bool(bool, error_code&) override { return true; }
bool on_null(error_code&) override { return true; }
};
public:
@ -426,21 +427,21 @@ class boost_null_impl : public any_impl
{
null_parser() {}
~null_parser() {}
void on_document_begin(error_code&) override {}
void on_document_end(error_code&) override {}
void on_object_begin(error_code&) override {}
void on_object_end(std::size_t, error_code&) override {}
void on_array_begin(error_code&) override {}
void on_array_end(std::size_t, error_code&) override {}
void on_key_part(string_view, error_code&) override {}
void on_key( string_view, error_code&) override {}
void on_string_part(string_view, error_code&) override {}
void on_string(string_view, error_code&) override {}
void on_int64(std::int64_t, error_code&) override {}
void on_uint64(std::uint64_t, error_code&) override {}
void on_double(double, error_code&) override {}
void on_bool(bool, error_code&) override {}
void on_null(error_code&) override {}
bool on_document_begin(error_code&) override { return true; }
bool on_document_end(error_code&) override { return true; }
bool on_object_begin(error_code&) override { return true; }
bool on_object_end(std::size_t, error_code&) override { return true; }
bool on_array_begin(error_code&) override { return true; }
bool on_array_end(std::size_t, error_code&) override { return true; }
bool on_key_part(string_view, error_code&) override { return true; }
bool on_key( string_view, error_code&) override { return true; }
bool on_string_part(string_view, error_code&) override { return true; }
bool on_string(string_view, error_code&) override { return true; }
bool on_int64(std::int64_t, error_code&) override { return true; }
bool on_uint64(std::uint64_t, error_code&) override { return true; }
bool on_double(double, error_code&) override { return true; }
bool on_bool(bool, error_code&) override { return true; }
bool on_null(error_code&) override { return true; }
void reset()
{
basic_parser::reset();

View File

@ -31,21 +31,21 @@ validate( string_view s )
{
null_parser() {}
~null_parser() {}
void on_document_begin( error_code& ) override {}
void on_document_end( error_code& ) override {}
void on_object_begin( error_code& ) override {}
void on_object_end( std::size_t, error_code& ) override {}
void on_array_begin( error_code& ) override {}
void on_array_end( std::size_t, error_code& ) override {}
void on_key_part( string_view, error_code& ) override {}
void on_key( string_view, error_code& ) override {}
void on_string_part( string_view, error_code& ) override {}
void on_string( string_view, error_code& ) override {}
void on_int64( std::int64_t, error_code& ) override {}
void on_uint64( std::uint64_t, error_code& ) override {}
void on_double( double, error_code& ) override {}
void on_bool( bool, error_code& ) override {}
void on_null( error_code& ) override {}
bool on_document_begin( error_code& ) override { return true; }
bool on_document_end( error_code& ) override { return true; }
bool on_object_begin( error_code& ) override { return true; }
bool on_object_end( std::size_t, error_code& ) override { return true; }
bool on_array_begin( error_code& ) override { return true; }
bool on_array_end( std::size_t, error_code& ) override { return true; }
bool on_key_part( string_view, error_code& ) override { return true; }
bool on_key( string_view, error_code& ) override { return true; }
bool on_string_part( string_view, error_code& ) override { return true; }
bool on_string( string_view, error_code& ) override { return true; }
bool on_int64( std::int64_t, error_code& ) override { return true; }
bool on_uint64( std::uint64_t, error_code& ) override { return true; }
bool on_double( double, error_code& ) override { return true; }
bool on_bool( bool, error_code& ) override { return true; }
bool on_null( error_code& ) override { return true; }
};
// Parse with the null parser and return false on error

View File

@ -50,6 +50,14 @@ class basic_parser
{
enum class state : char;
using const_stream = detail::const_stream;
enum result
{
ok = 0,
fail,
partial
};
struct number
{
uint64_t mant;
@ -76,16 +84,16 @@ class basic_parser
inline void suspend(state st);
inline void suspend(state st, std::size_t n);
inline void suspend(state st, number const& num);
inline void parse_element(const_stream& cs);
inline void parse_white(const_stream& cs);
inline void parse_value(const_stream& cs);
inline void parse_null(const_stream& cs);
inline void parse_true(const_stream& cs);
inline void parse_false(const_stream& cs);
inline void parse_string(const_stream& cs);
inline void parse_object(const_stream& cs);
inline void parse_array(const_stream& cs);
inline void parse_number(const_stream& cs);
inline bool skip_white(const_stream& cs);
inline result parse_element(const_stream& cs);
inline result parse_value(const_stream& cs);
inline result parse_null(const_stream& cs);
inline result parse_true(const_stream& cs);
inline result parse_false(const_stream& cs);
inline result parse_string(const_stream& cs);
inline result parse_object(const_stream& cs);
inline result parse_array(const_stream& cs);
inline result parse_number(const_stream& cs);
public:
//------------------------------------------------------
@ -506,12 +514,14 @@ protected:
presented. The call happens before any other
events.
@return `true` on success.
@param ec The error, if any, which will be
returned by the current invocation of
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_document_begin(
error_code& ec) = 0;
@ -522,12 +532,14 @@ protected:
The call happens last; no other calls are made
before the parser is reset.
@return `true` on success.
@param ec The error, if any, which will be
returned by the current invocation of
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_document_end(
error_code& ec) = 0;
@ -536,12 +548,14 @@ protected:
This function is called during parsing when a new
object is started.
@return `true` on success.
@param ec The error, if any, which will be
returned by the current invocation of
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_object_begin(
error_code& ec) = 0;
@ -551,6 +565,8 @@ protected:
the elements of an object have been parsed, and the
closing brace for the object is reached.
@return `true` on success.
@param n The number of elements in the object.
@param ec The error, if any, which will be
@ -558,7 +574,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_object_end(
std::size_t n,
error_code& ec) = 0;
@ -568,12 +584,14 @@ protected:
This function is called during parsing when a new
array is started.
@return `true` on success.
@param ec The error, if any, which will be
returned by the current invocation of
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_array_begin(
error_code& ec) = 0;
@ -583,6 +601,8 @@ protected:
the elements of an array have been parsed, and the
closing bracket for the array is reached.
@return `true` on success.
@param n The number of elements in the array.
@param ec The error, if any, which will be
@ -590,7 +610,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_array_end(
std::size_t n,
error_code& ec) = 0;
@ -603,6 +623,8 @@ protected:
by zero or more calls to @ref on_key_part, followed
by a final call to @ref on_key.
@return `true` on success.
@param s The string view holding the next buffer of
key data, with escapes converted to their actual
characters.
@ -612,7 +634,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_key_part(
string_view s,
error_code& ec) = 0;
@ -624,6 +646,8 @@ protected:
being parsed as part of an object. The key is
considered complete with these characters.
@return `true` on success.
@param s The string view holding the final buffer of
key data, with escapes converted to their actual
characters.
@ -633,7 +657,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_key(
string_view s,
error_code& ec) = 0;
@ -646,6 +670,8 @@ protected:
more calls to @ref on_string_part, followed by a
final call to @ref on_string.
@return `true` on success.
@param s The string view holding the next buffer of
string data, with escapes converted to their actual
characters.
@ -655,7 +681,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_string_part(
string_view s,
error_code& ec) = 0;
@ -667,6 +693,8 @@ protected:
string being parsed. The string element is
considered complete with these characters.
@return `true` on success.
@param s The string view holding the final buffer of
string data, with escapes converted to their actual
characters.
@ -676,7 +704,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_string(
string_view s,
error_code& ec) = 0;
@ -686,6 +714,8 @@ protected:
This function is called when a suitable
number is parsed.
@return `true` on success.
@param i The number encountered.
@param ec The error, if any, which will be
@ -693,7 +723,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_int64(
int64_t i,
error_code& ec) = 0;
@ -703,6 +733,8 @@ protected:
This function is called when a suitable
number is parsed.
@return `true` on success.
@param u The number encountered.
@param ec The error, if any, which will be
@ -710,7 +742,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_uint64(
uint64_t u,
error_code& ec) = 0;
@ -720,6 +752,8 @@ protected:
This function is called when a suitable
number is parsed.
@return `true` on success.
@param d The number encountered.
@param ec The error, if any, which will be
@ -727,7 +761,7 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_double(
double d,
error_code& ec) = 0;
@ -737,6 +771,8 @@ protected:
This function is called when a
boolean value is encountered.
@return `true` on success.
@param b The boolean value.
@param ec The error, if any, which will be
@ -744,19 +780,21 @@ protected:
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_bool(bool b, error_code& ec) = 0;
/** Called when a null is parsed.
This function is called when a null is encountered.
@return `true` on success.
@param ec The error, if any, which will be
returned by the current invocation of
@ref write_some, @ref write, or @ref finish.
*/
virtual
void
bool
on_null(error_code& ec) = 0;
};

File diff suppressed because it is too large Load Diff

View File

@ -338,7 +338,7 @@ pop_chars(
//----------------------------------------------------------
void
bool
parser::
on_document_begin(
error_code& ec)
@ -346,7 +346,7 @@ on_document_begin(
if(lev_.st == state::need_start)
{
ec = error::need_start;
return;
return false;
}
lev_.count = 0;
@ -358,16 +358,19 @@ on_document_begin(
// inside a notional 1-element array.
rs_.add(sizeof(value));
lev_.st = state::top;
return true;
}
void
bool
parser::
on_document_end(error_code&)
{
BOOST_ASSERT(lev_.count == 1);
return true;
}
void
bool
parser::
on_object_begin(error_code&)
{
@ -383,9 +386,10 @@ on_object_begin(error_code&)
object::value_type));
lev_.count = 0;
lev_.st = state::obj;
return true;
}
void
bool
parser::
on_object_end(
std::size_t,
@ -397,9 +401,10 @@ on_object_end(
rs_.subtract(lev_.align);
pop(lev_);
emplace(std::move(uo));
return true;
}
void
bool
parser::
on_array_begin(error_code&)
{
@ -414,9 +419,10 @@ on_array_begin(error_code&)
rs_.add(sizeof(value));
lev_.count = 0;
lev_.st = state::arr;
return true;
}
void
bool
parser::
on_array_end(
std::size_t,
@ -428,9 +434,10 @@ on_array_end(
rs_.subtract(lev_.align);
pop(lev_);
emplace(std::move(ua));
return true;
}
void
bool
parser::
on_key_part(
string_view s,
@ -442,9 +449,10 @@ on_key_part(
push_chars(s);
key_size_ += static_cast<
std::uint32_t>(s.size());
return true;
}
void
bool
parser::
on_key(
string_view s,
@ -452,13 +460,15 @@ on_key(
{
BOOST_ASSERT(
lev_.st == state::obj);
on_key_part(s, ec);
if(! on_key_part(s, ec))
return false;
push(key_size_);
key_size_ = 0;
lev_.st = state::key;
return true;
}
void
bool
parser::
on_string_part(
string_view s,
@ -470,9 +480,10 @@ on_string_part(
push_chars(s);
str_size_ += static_cast<
std::uint32_t>(s.size());
return true;
}
void
bool
parser::
on_string(
string_view s,
@ -503,47 +514,54 @@ on_string(
str.grow(sv.size() + s.size());
emplace(std::move(str));
}
return true;
}
void
bool
parser::
on_int64(
int64_t i,
error_code&)
{
emplace(i, sp_);
return true;
}
void
bool
parser::
on_uint64(
uint64_t u,
error_code&)
{
emplace(u, sp_);
return true;
}
void
bool
parser::
on_double(
double d,
error_code&)
{
emplace(d, sp_);
return true;
}
void
bool
parser::
on_bool(bool b, error_code&)
on_bool(
bool b, error_code&)
{
emplace(b, sp_);
return true;
}
void
bool
parser::
on_null(error_code&)
{
emplace(nullptr, sp_);
return true;
}
//----------------------------------------------------------

View File

@ -201,87 +201,87 @@ private:
std::size_t size) noexcept;
BOOST_JSON_DECL
void
bool
on_document_begin(
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_document_end(
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_object_begin(
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_object_end(
std::size_t n,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_array_begin(
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_array_end(
std::size_t n,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_key_part(
string_view s,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_key(
string_view s,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_string_part(
string_view s,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_string(
string_view s,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_int64(
int64_t i,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_uint64(
uint64_t u,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_double(
double d,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_bool(
bool b,
error_code& ec) override;
BOOST_JSON_DECL
void
bool
on_null(error_code&) override;
};

View File

@ -110,21 +110,21 @@ validate( string_view s )
{
null_parser() {}
~null_parser() {}
void on_document_begin( error_code& ) override {}
void on_document_end( error_code& ) override {}
void on_object_begin( error_code& ) override {}
void on_object_end( std::size_t, error_code& ) override {}
void on_array_begin( error_code& ) override {}
void on_array_end( std::size_t, error_code& ) override {}
void on_key_part( string_view, error_code& ) override {}
void on_key( string_view, error_code& ) override {}
void on_string_part( string_view, error_code& ) override {}
void on_string( string_view, error_code& ) override {}
void on_int64( std::int64_t, error_code& ) override {}
void on_uint64( std::uint64_t, error_code& ) override {}
void on_double( double, error_code& ) override {}
void on_bool( bool, error_code& ) override {}
void on_null( error_code& ) override {}
bool on_document_begin( error_code& ) override { return true; }
bool on_document_end( error_code& ) override { return true; }
bool on_object_begin( error_code& ) override { return true; }
bool on_object_end( std::size_t, error_code& ) override { return true; }
bool on_array_begin( error_code& ) override { return true; }
bool on_array_end( std::size_t, error_code& ) override { return true; }
bool on_key_part( string_view, error_code& ) override { return true; }
bool on_key( string_view, error_code& ) override { return true; }
bool on_string_part( string_view, error_code& ) override { return true; }
bool on_string( string_view, error_code& ) override { return true; }
bool on_int64( std::int64_t, error_code& ) override { return true; }
bool on_uint64( std::uint64_t, error_code& ) override { return true; }
bool on_double( double, error_code& ) override { return true; }
bool on_bool( bool, error_code& ) override { return true; }
bool on_null( error_code& ) override { return true; }
};
// Parse with the null parser and return false on error
@ -348,8 +348,11 @@ public:
// escape in key
good(R"jv( {" \n":null} )jv");
// incomplete
bad ("\"");
// illegal control character
bad ("\"" "\x00" "\"");
bad ({ "\"" "\x00" "\"", 3 });
bad ("\"" "\x1f" "\"");
bad ("\"" "\\n" "\x1f" "\"");

View File

@ -147,126 +147,127 @@ class fail_parser
{
std::size_t n_ = std::size_t(-1);
void
bool
maybe_fail(error_code& ec)
{
if(n_ && --n_ > 0)
return;
return true;
ec = error::test_failure;
return false;
}
void
bool
on_document_begin(
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_document_end(
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_object_begin(
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_object_end(
std::size_t,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_array_begin(
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_array_end(
std::size_t,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_key_part(
string_view,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_key(
string_view,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_string_part(
string_view,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_string(
string_view,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_int64(
int64_t,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_uint64(
uint64_t,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_double(
double,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_bool(
bool,
error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
void
bool
on_null(error_code& ec) override
{
maybe_fail(ec);
return maybe_fail(ec);
}
public:
@ -304,126 +305,126 @@ class throw_parser
{
std::size_t n_ = std::size_t(-1);
void
bool
maybe_throw()
{
if(n_ && --n_ > 0)
return;
return true;
throw test_exception{};
}
void
bool
on_document_begin(
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_document_end(
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_object_begin(
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_object_end(
std::size_t,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_array_begin(
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_array_end(
std::size_t,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_key_part(
string_view,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_key(
string_view,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_string_part(
string_view,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_string(
string_view,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_int64(
int64_t,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_uint64(
uint64_t,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_double(
double,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_bool(
bool,
error_code&) override
{
maybe_throw();
return maybe_throw();
}
void
bool
on_null(error_code&) override
{
maybe_throw();
return maybe_throw();
}
public:
@ -445,7 +446,6 @@ class input_iterator
{
FwdIt it_;
public:
using value_type = typename std::iterator_traits<FwdIt>::value_type;
using pointer = typename std::iterator_traits<FwdIt>::pointer;