Skip to content

Commit 4d65f2b

Browse files
committed
json_cursor
1 parent b631784 commit 4d65f2b

File tree

2 files changed

+83
-31
lines changed

2 files changed

+83
-31
lines changed

include/jsoncons/json_cursor.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,14 @@ class basic_json_cursor : public basic_staj_cursor<CharT>, private virtual ser_c
280280
void read_to(basic_json_visitor<CharT>& visitor,
281281
std::error_code& ec) override
282282
{
283+
parser_.cursor_mode(false);
284+
parser_.mark_level(parser_.level());
283285
if (cursor_visitor_.event().send_json_event(visitor, *this, ec))
284286
{
285287
read_next(visitor, ec);
286288
}
289+
parser_.cursor_mode(true);
290+
parser_.mark_level(0);
287291
}
288292

289293
void next() override

include/jsoncons/json_parser.hpp

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class basic_json_parser : public ser_context
129129
basic_json_decode_options<char_type> options_;
130130

131131
std::function<bool(json_errc,const ser_context&)> err_handler_;
132-
int nesting_depth_{0};
132+
int level_{0};
133133
uint32_t cp_{0};
134134
uint32_t cp2_{0};
135135
std::size_t line_{1};
@@ -145,6 +145,7 @@ class basic_json_parser : public ser_context
145145
bool more_{true};
146146
bool done_{false};
147147
bool cursor_mode_{false};
148+
int mark_level_{0};
148149

149150
std::basic_string<char_type,std::char_traits<char_type>,char_allocator_type> string_buffer_;
150151
jsoncons::detail::chars_to to_double_;
@@ -207,6 +208,21 @@ class basic_json_parser : public ser_context
207208
cursor_mode_ = value;
208209
}
209210

211+
int level() const
212+
{
213+
return level_;
214+
}
215+
216+
int mark_level() const
217+
{
218+
return mark_level_;
219+
}
220+
221+
void mark_level(int value)
222+
{
223+
mark_level_ = value;
224+
}
225+
210226
bool source_exhausted() const
211227
{
212228
return input_ptr_ == end_input_;
@@ -341,7 +357,7 @@ class basic_json_parser : public ser_context
341357

342358
void begin_object(basic_json_visitor<char_type>& visitor, std::error_code& ec)
343359
{
344-
if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
360+
if (JSONCONS_UNLIKELY(++level_ > options_.max_nesting_depth()))
345361
{
346362
more_ = err_handler_(json_errc::max_nesting_depth_exceeded, *this);
347363
if (!more_)
@@ -353,23 +369,24 @@ class basic_json_parser : public ser_context
353369

354370
push_state(parse_state::object);
355371
state_ = parse_state::expect_member_name_or_end;
356-
more_ = visitor.begin_object(semantic_tag::none, *this, ec);
372+
visitor.begin_object(semantic_tag::none, *this, ec);
373+
more_ = !cursor_mode_;
357374
}
358375

359376
void end_object(basic_json_visitor<char_type>& visitor, std::error_code& ec)
360377
{
361-
if (JSONCONS_UNLIKELY(nesting_depth_ < 1))
378+
if (JSONCONS_UNLIKELY(level_ < 1))
362379
{
363380
err_handler_(json_errc::unexpected_rbrace, *this);
364381
ec = json_errc::unexpected_rbrace;
365382
more_ = false;
366383
return;
367384
}
368-
--nesting_depth_;
385+
--level_;
369386
state_ = pop_state();
370387
if (state_ == parse_state::object)
371388
{
372-
more_ = visitor.end_object(*this, ec);
389+
visitor.end_object(*this, ec);
373390
}
374391
else if (state_ == parse_state::array)
375392
{
@@ -394,11 +411,16 @@ class basic_json_parser : public ser_context
394411
{
395412
state_ = parse_state::expect_comma_or_end;
396413
}
414+
more_ = !cursor_mode_;
415+
if (level_ <= mark_level_)
416+
{
417+
more_ = false;
418+
}
397419
}
398420

399421
void begin_array(basic_json_visitor<char_type>& visitor, std::error_code& ec)
400422
{
401-
if (++nesting_depth_ > options_.max_nesting_depth())
423+
if (++level_ > options_.max_nesting_depth())
402424
{
403425
more_ = err_handler_(json_errc::max_nesting_depth_exceeded, *this);
404426
if (!more_)
@@ -410,23 +432,25 @@ class basic_json_parser : public ser_context
410432

411433
push_state(parse_state::array);
412434
state_ = parse_state::expect_value_or_end;
413-
more_ = visitor.begin_array(semantic_tag::none, *this, ec);
435+
visitor.begin_array(semantic_tag::none, *this, ec);
436+
437+
more_ = !cursor_mode_;
414438
}
415439

416440
void end_array(basic_json_visitor<char_type>& visitor, std::error_code& ec)
417441
{
418-
if (nesting_depth_ < 1)
442+
if (level_ < 1)
419443
{
420444
err_handler_(json_errc::unexpected_rbracket, *this);
421445
ec = json_errc::unexpected_rbracket;
422446
more_ = false;
423447
return;
424448
}
425-
--nesting_depth_;
449+
--level_;
426450
state_ = pop_state();
427451
if (state_ == parse_state::array)
428452
{
429-
more_ = visitor.end_array(*this, ec);
453+
visitor.end_array(*this, ec);
430454
}
431455
else if (state_ == parse_state::object)
432456
{
@@ -450,6 +474,12 @@ class basic_json_parser : public ser_context
450474
{
451475
state_ = parse_state::expect_comma_or_end;
452476
}
477+
478+
more_ = !cursor_mode_;
479+
if (level_ <= mark_level_)
480+
{
481+
more_ = false;
482+
}
453483
}
454484

455485
void reinitialize()
@@ -474,7 +504,7 @@ class basic_json_parser : public ser_context
474504
line_ = 1;
475505
position_ = 0;
476506
mark_position_ = 0;
477-
nesting_depth_ = 0;
507+
level_ = 0;
478508
}
479509

480510
void restart()
@@ -1394,7 +1424,7 @@ class basic_json_parser : public ser_context
13941424
case 'e':
13951425
++input_ptr_;
13961426
++position_;
1397-
more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
1427+
visitor.bool_value(true, semantic_tag::none, *this, ec);
13981428
if (parent() == parse_state::root)
13991429
{
14001430
state_ = parse_state::accept;
@@ -1403,6 +1433,7 @@ class basic_json_parser : public ser_context
14031433
{
14041434
state_ = parse_state::expect_comma_or_end;
14051435
}
1436+
more_ = !cursor_mode_;
14061437
break;
14071438
default:
14081439
err_handler_(json_errc::invalid_value, *this);
@@ -1462,7 +1493,7 @@ class basic_json_parser : public ser_context
14621493
case 'e':
14631494
++input_ptr_;
14641495
++position_;
1465-
more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
1496+
visitor.bool_value(false, semantic_tag::none, *this, ec);
14661497
if (parent() == parse_state::root)
14671498
{
14681499
state_ = parse_state::accept;
@@ -1471,6 +1502,7 @@ class basic_json_parser : public ser_context
14711502
{
14721503
state_ = parse_state::expect_comma_or_end;
14731504
}
1505+
more_ = !cursor_mode_;
14741506
break;
14751507
default:
14761508
err_handler_(json_errc::invalid_value, *this);
@@ -1514,7 +1546,7 @@ class basic_json_parser : public ser_context
15141546
switch (*input_ptr_)
15151547
{
15161548
case 'l':
1517-
more_ = visitor.null_value(semantic_tag::none, *this, ec);
1549+
visitor.null_value(semantic_tag::none, *this, ec);
15181550
if (parent() == parse_state::root)
15191551
{
15201552
state_ = parse_state::accept;
@@ -1523,6 +1555,7 @@ class basic_json_parser : public ser_context
15231555
{
15241556
state_ = parse_state::expect_comma_or_end;
15251557
}
1558+
more_ = !cursor_mode_;
15261559
break;
15271560
default:
15281561
err_handler_(json_errc::invalid_value, *this);
@@ -1650,7 +1683,7 @@ class basic_json_parser : public ser_context
16501683
{
16511684
input_ptr_ += 4;
16521685
position_ += 4;
1653-
more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
1686+
visitor.bool_value(true, semantic_tag::none, *this, ec);
16541687
if (parent() == parse_state::root)
16551688
{
16561689
state_ = parse_state::accept;
@@ -1659,6 +1692,7 @@ class basic_json_parser : public ser_context
16591692
{
16601693
state_ = parse_state::expect_comma_or_end;
16611694
}
1695+
more_ = !cursor_mode_;
16621696
}
16631697
else
16641698
{
@@ -1685,7 +1719,8 @@ class basic_json_parser : public ser_context
16851719
{
16861720
input_ptr_ += 4;
16871721
position_ += 4;
1688-
more_ = visitor.null_value(semantic_tag::none, *this, ec);
1722+
visitor.null_value(semantic_tag::none, *this, ec);
1723+
more_ = !cursor_mode_;
16891724
if (parent() == parse_state::root)
16901725
{
16911726
state_ = parse_state::accept;
@@ -1720,7 +1755,8 @@ class basic_json_parser : public ser_context
17201755
{
17211756
input_ptr_ += 5;
17221757
position_ += 5;
1723-
more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
1758+
visitor.bool_value(false, semantic_tag::none, *this, ec);
1759+
more_ = !cursor_mode_;
17241760
if (parent() == parse_state::root)
17251761
{
17261762
state_ = parse_state::accept;
@@ -2624,11 +2660,13 @@ class basic_json_parser : public ser_context
26242660
auto result = jsoncons::detail::to_integer_unchecked(string_buffer_.data(), string_buffer_.length(), val);
26252661
if (result)
26262662
{
2627-
more_ = visitor.int64_value(val, semantic_tag::none, *this, ec);
2663+
visitor.int64_value(val, semantic_tag::none, *this, ec);
2664+
more_ = !cursor_mode_;
26282665
}
26292666
else // Must be overflow
26302667
{
2631-
more_ = visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec);
2668+
visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec);
2669+
more_ = !cursor_mode_;
26322670
}
26332671
after_value(ec);
26342672
}
@@ -2639,11 +2677,13 @@ class basic_json_parser : public ser_context
26392677
auto result = jsoncons::detail::to_integer_unchecked(string_buffer_.data(), string_buffer_.length(), val);
26402678
if (result)
26412679
{
2642-
more_ = visitor.uint64_value(val, semantic_tag::none, *this, ec);
2680+
visitor.uint64_value(val, semantic_tag::none, *this, ec);
2681+
more_ = !cursor_mode_;
26432682
}
26442683
else // Must be overflow
26452684
{
2646-
more_ = visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec);
2685+
visitor.string_value(string_buffer_, semantic_tag::bigint, *this, ec);
2686+
more_ = !cursor_mode_;
26472687
}
26482688
after_value(ec);
26492689
}
@@ -2654,12 +2694,14 @@ class basic_json_parser : public ser_context
26542694
{
26552695
if (options_.lossless_number())
26562696
{
2657-
more_ = visitor.string_value(string_buffer_, semantic_tag::bigdec, *this, ec);
2697+
visitor.string_value(string_buffer_, semantic_tag::bigdec, *this, ec);
2698+
more_ = !cursor_mode_;
26582699
}
26592700
else
26602701
{
26612702
double d = to_double_(string_buffer_.c_str(), string_buffer_.length());
2662-
more_ = visitor.double_value(d, semantic_tag::none, *this, ec);
2703+
visitor.double_value(d, semantic_tag::none, *this, ec);
2704+
more_ = !cursor_mode_;
26632705
}
26642706
}
26652707
JSONCONS_CATCH(...)
@@ -2670,7 +2712,8 @@ class basic_json_parser : public ser_context
26702712
ec = json_errc::invalid_number;
26712713
return;
26722714
}
2673-
more_ = visitor.null_value(semantic_tag::none, *this, ec); // recovery
2715+
visitor.null_value(semantic_tag::none, *this, ec); // recovery
2716+
more_ = !cursor_mode_;
26742717
}
26752718

26762719
after_value(ec);
@@ -2689,7 +2732,8 @@ class basic_json_parser : public ser_context
26892732
switch (parent())
26902733
{
26912734
case parse_state::member_name:
2692-
more_ = visitor.key(sv, *this, ec);
2735+
visitor.key(sv, *this, ec);
2736+
more_ = !cursor_mode_;
26932737
pop_state();
26942738
state_ = parse_state::expect_colon;
26952739
break;
@@ -2699,11 +2743,13 @@ class basic_json_parser : public ser_context
26992743
auto it = std::find_if(string_double_map_.begin(), string_double_map_.end(), string_maps_to_double{ sv });
27002744
if (it != string_double_map_.end())
27012745
{
2702-
more_ = visitor.double_value((*it).second, semantic_tag::none, *this, ec);
2746+
visitor.double_value((*it).second, semantic_tag::none, *this, ec);
2747+
more_ = !cursor_mode_;
27032748
}
27042749
else
27052750
{
2706-
more_ = visitor.string_value(sv, semantic_tag::none, *this, ec);
2751+
visitor.string_value(sv, semantic_tag::none, *this, ec);
2752+
more_ = !cursor_mode_;
27072753
}
27082754
state_ = parse_state::expect_comma_or_end;
27092755
break;
@@ -2713,11 +2759,13 @@ class basic_json_parser : public ser_context
27132759
auto it = std::find_if(string_double_map_.begin(),string_double_map_.end(),string_maps_to_double{sv});
27142760
if (it != string_double_map_.end())
27152761
{
2716-
more_ = visitor.double_value((*it).second, semantic_tag::none, *this, ec);
2762+
visitor.double_value((*it).second, semantic_tag::none, *this, ec);
2763+
more_ = !cursor_mode_;
27172764
}
27182765
else
27192766
{
2720-
more_ = visitor.string_value(sv, semantic_tag::none, *this, ec);
2767+
visitor.string_value(sv, semantic_tag::none, *this, ec);
2768+
more_ = !cursor_mode_;
27212769
}
27222770
state_ = parse_state::accept;
27232771
break;
@@ -2781,7 +2829,7 @@ class basic_json_parser : public ser_context
27812829
void push_state(parse_state state)
27822830
{
27832831
state_stack_.push_back(state);
2784-
//std::cout << "max_nesting_depth: " << options_.max_nesting_depth() << ", capacity: " << state_stack_.capacity() << ", nesting_depth: " << nesting_depth_ << ", stack size: " << state_stack_.size() << "\n";
2832+
//std::cout << "max_nesting_depth: " << options_.max_nesting_depth() << ", capacity: " << state_stack_.capacity() << ", nesting_depth: " << level_ << ", stack size: " << state_stack_.size() << "\n";
27852833
}
27862834

27872835
parse_state pop_state()

0 commit comments

Comments
 (0)