Skip to content

Commit

Permalink
parse_false parse_true parse_null
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Nov 7, 2024
1 parent 9fd5505 commit 9fc63b3
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 68 deletions.
264 changes: 202 additions & 62 deletions include/jsoncons/json_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1451,117 +1451,257 @@ class basic_json_parser : public ser_context

void parse_null(basic_json_visitor<char_type>& visitor, std::error_code& ec)
{
static const char_type value[] = {'n','u','l','l'};

saved_position_ = position_;

if (JSONCONS_LIKELY(input_end_ - input_ptr_ < 4))
std::ptrdiff_t n = input_end_ - input_ptr_;
std::ptrdiff_t m = 4 - n;
if (JSONCONS_UNLIKELY(n < 4))
{
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < 4)
bool matches = true;
for (std::ptrdiff_t i = 1; i < n && matches; ++i)
{
std::ptrdiff_t diff = input_end_ - input_ptr_;
input_ptr_ += diff;
position_ += diff;
ec = json_errc::invalid_value;
more_ = false;
return;
if (*(input_ptr_+(i)) != value[i])
{
matches = false;
}
}
}

if (*(input_ptr_+1) == 'u' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 'l')
{
input_ptr_ += 4;
position_ += 4;
more_ = visitor.null_value(semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
input_ptr_ += n;
position_ += n;
if (!matches)
{
state_ = json_parse_state::accept;
ec = json_errc::invalid_value;
more_ = false;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < m)
{
ec = json_errc::invalid_value;
more_ = false;
}
else
{
matches = true;
for (std::ptrdiff_t i = 0; i < m && matches; ++i)
{
if (*(input_ptr_+(i)) != value[n+i])
{
matches = false;
}
}
input_ptr_ += m;
position_ += m;
if (!matches)
{
ec = json_errc::invalid_value;
more_ = false;
}
more_ = visitor.null_value(semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
}
}
else
{
err_handler_(json_errc::invalid_value, *this);
ec = json_errc::invalid_value;
more_ = false;
if (*(input_ptr_+1) == 'u' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 'l')
{
input_ptr_ += 4;
position_ += 4;
more_ = visitor.null_value(semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
else
{
ec = json_errc::invalid_value;
more_ = false;
}
}
}

void parse_true(basic_json_visitor<char_type>& visitor, std::error_code& ec)
{
static const char_type value[] = {'t','r','u','e'};

saved_position_ = position_;
if (JSONCONS_LIKELY(input_end_ - input_ptr_ < 4))

std::ptrdiff_t n = input_end_ - input_ptr_;
std::ptrdiff_t m = 4 - n;
if (JSONCONS_UNLIKELY(n < 4))
{
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < 4)
bool matches = true;
for (std::ptrdiff_t i = 1; i < n && matches; ++i)
{
std::ptrdiff_t diff = input_end_ - input_ptr_;
input_ptr_ += diff;
position_ += diff;
ec = json_errc::invalid_value;
more_ = false;
return;
if (*(input_ptr_+(i)) != value[i])
{
matches = false;
}
}
}

if (*(input_ptr_+1) == 'r' && *(input_ptr_+2) == 'u' && *(input_ptr_+3) == 'e')
{
input_ptr_ += 4;
position_ += 4;
more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
input_ptr_ += n;
position_ += n;
if (!matches)
{
state_ = json_parse_state::accept;
ec = json_errc::invalid_value;
more_ = false;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < m)
{
ec = json_errc::invalid_value;
more_ = false;
}
else
{
matches = true;
for (std::ptrdiff_t i = 0; i < m && matches; ++i)
{
if (*(input_ptr_+(i)) != value[n+i])
{
matches = false;
}
}
input_ptr_ += m;
position_ += m;
if (!matches)
{
ec = json_errc::invalid_value;
more_ = false;
}
more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
}
}
else
{
err_handler_(json_errc::invalid_value, *this);
ec = json_errc::invalid_value;
more_ = false;
if (*(input_ptr_+1) == 'r' && *(input_ptr_+2) == 'u' && *(input_ptr_+3) == 'e')
{
input_ptr_ += 4;
position_ += 4;
more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
else
{
ec = json_errc::invalid_value;
more_ = false;
}
}
}

void parse_false(basic_json_visitor<char_type>& visitor, std::error_code& ec)
{
static const char_type value[] = {'f','a','l','s','e'};

saved_position_ = position_;
if (JSONCONS_LIKELY(input_end_ - input_ptr_ < 5))

std::ptrdiff_t n = input_end_ - input_ptr_;
std::ptrdiff_t m = 5 - n;
if (JSONCONS_UNLIKELY(n < 5))
{
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < 5)
bool matches = true;
for (std::ptrdiff_t i = 1; i < n && matches; ++i)
{
if (*(input_ptr_+(i)) != value[i])
{
matches = false;
}
}
input_ptr_ += n;
position_ += n;
if (!matches)
{
std::ptrdiff_t diff = input_end_ - input_ptr_;
input_ptr_ += diff;
position_ += diff;
ec = json_errc::invalid_value;
more_ = false;
return;
}
else
{
if (!chunk_rdr_->read_chunk(ec) || (input_end_ - input_ptr_) < m)
{
ec = json_errc::invalid_value;
more_ = false;
}
else
{
matches = true;
for (std::ptrdiff_t i = 0; i < m && matches; ++i)
{
if (*(input_ptr_+(i)) != value[n+i])
{
matches = false;
}
}
input_ptr_ += m;
position_ += m;
if (!matches)
{
ec = json_errc::invalid_value;
more_ = false;
}
more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
}
}

if (*(input_ptr_+1) == 'a' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 's' && *(input_ptr_+4) == 'e')
else
{
input_ptr_ += 5;
position_ += 5;
more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
if (*(input_ptr_+1) == 'a' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 's' && *(input_ptr_+4) == 'e')
{
state_ = json_parse_state::accept;
input_ptr_ += 5;
position_ += 5;
more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
if (parent() == json_parse_state::root)
{
state_ = json_parse_state::accept;
}
else
{
state_ = json_parse_state::expect_comma_or_end;
}
}
else
{
state_ = json_parse_state::expect_comma_or_end;
ec = json_errc::invalid_value;
more_ = false;
}
}
else
{
err_handler_(json_errc::invalid_value, *this);
ec = json_errc::invalid_value;
more_ = false;
}
}

void parse_number(basic_json_visitor<char_type>& visitor, std::error_code& ec)
Expand Down
2 changes: 1 addition & 1 deletion include/jsoncons/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ namespace jsoncons {
bool success = false;
if (!parser_.stopped())
{
if (parser_.source_exhausted())
//if (parser_.source_exhausted())
{
auto s = source_.read_buffer(ec);
if (ec) return false;
Expand Down
Loading

0 comments on commit 9fc63b3

Please sign in to comment.