Skip to content

Commit 814bb2d

Browse files
committed
Improve bson_cursor
1 parent 2532652 commit 814bb2d

File tree

9 files changed

+107
-65
lines changed

9 files changed

+107
-65
lines changed

include/jsoncons/json_cursor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class basic_json_cursor : public basic_staj_cursor<CharT>, private virtual ser_c
278278
}
279279

280280
void read_to(basic_json_visitor<CharT>& visitor,
281-
std::error_code& ec) override
281+
std::error_code& ec) override
282282
{
283283
if (is_begin_container(current().event_type()))
284284
{

include/jsoncons_ext/bson/bson_cursor.hpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class basic_bson_cursor : public basic_staj_cursor<char>, private virtual ser_co
3838
private:
3939
basic_bson_parser<Source,Allocator> parser_;
4040
basic_staj_visitor<char_type> cursor_visitor_;
41-
bool eof_;
41+
bool eof_{false};
4242

4343
public:
4444
using string_view_type = string_view;
@@ -52,9 +52,9 @@ class basic_bson_cursor : public basic_staj_cursor<char>, private virtual ser_co
5252
const bson_decode_options& options = bson_decode_options(),
5353
const Allocator& alloc = Allocator())
5454
: parser_(std::forward<Sourceable>(source), options, alloc),
55-
cursor_visitor_(accept_all),
56-
eof_(false)
55+
cursor_visitor_(accept_all)
5756
{
57+
parser_.cursor_mode(true);
5858
if (!done())
5959
{
6060
next();
@@ -90,9 +90,9 @@ class basic_bson_cursor : public basic_staj_cursor<char>, private virtual ser_co
9090
const bson_decode_options& options,
9191
std::error_code& ec)
9292
: parser_(std::forward<Sourceable>(source), options, alloc),
93-
cursor_visitor_(accept_all),
94-
eof_(false)
93+
cursor_visitor_(accept_all)
9594
{
95+
parser_.cursor_mode(true);
9696
if (!done())
9797
{
9898
next(ec);
@@ -183,11 +183,25 @@ class basic_bson_cursor : public basic_staj_cursor<char>, private virtual ser_co
183183
}
184184

185185
void read_to(basic_json_visitor<char_type>& visitor,
186-
std::error_code& ec) override
186+
std::error_code& ec) override
187187
{
188-
if (cursor_visitor_.event().send_json_event(visitor, *this, ec))
188+
if (is_begin_container(current().event_type()))
189189
{
190-
read_next(visitor, ec);
190+
parser_.cursor_mode(false);
191+
parser_.mark_level(parser_.level());
192+
if (cursor_visitor_.event().send_json_event(visitor, *this, ec))
193+
{
194+
read_next(visitor, ec);
195+
}
196+
parser_.cursor_mode(true);
197+
parser_.mark_level(0);
198+
}
199+
else
200+
{
201+
if (cursor_visitor_.event().send_json_event(visitor, *this, ec))
202+
{
203+
read_next(visitor, ec);
204+
}
191205
}
192206
}
193207

include/jsoncons_ext/bson/bson_parser.hpp

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ enum class parse_mode {root,accept,document,array,value};
3737
struct parse_state
3838
{
3939
parse_mode mode;
40-
std::size_t length{0};
41-
std::size_t pos{0};
40+
std::size_t length;
41+
std::size_t pos;
4242
uint8_t type;
4343
std::size_t index{0};
4444

@@ -64,10 +64,13 @@ class basic_bson_parser : public ser_context
6464
using parse_state_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_state>;
6565
using string_type = std::basic_string<char,std::char_traits<char>,char_allocator_type>;
6666

67+
bool more_{true};
68+
bool done_{false};
69+
bool cursor_mode_{false};
70+
int mark_level_{0};
71+
6772
Source source_;
6873
bson_decode_options options_;
69-
bool more_;
70-
bool done_;
7174
std::vector<uint8_t,byte_allocator_type> bytes_buffer_;
7275
string_type name_buffer_;
7376
string_type text_buffer_;
@@ -79,8 +82,6 @@ class basic_bson_parser : public ser_context
7982
const TempAllocator& temp_alloc = TempAllocator())
8083
: source_(std::forward<Sourceable>(source)),
8184
options_(options),
82-
more_(true),
83-
done_(false),
8485
bytes_buffer_(temp_alloc),
8586
name_buffer_(temp_alloc),
8687
text_buffer_(temp_alloc),
@@ -112,6 +113,26 @@ class basic_bson_parser : public ser_context
112113
reset();
113114
}
114115

116+
void cursor_mode(bool value)
117+
{
118+
cursor_mode_ = value;
119+
}
120+
121+
int level() const
122+
{
123+
return static_cast<int>(state_stack_.size());
124+
}
125+
126+
int mark_level() const
127+
{
128+
return mark_level_;
129+
}
130+
131+
void mark_level(int value)
132+
{
133+
mark_level_ = value;
134+
}
135+
115136
bool done() const
116137
{
117138
return done_;
@@ -137,7 +158,8 @@ class basic_bson_parser : public ser_context
137158
if (state_stack_.size() == 2 && state_stack_.back().mode == parse_mode::document)
138159
{
139160
state_stack_.back().mode = parse_mode::array;
140-
more_ = visitor.begin_array(semantic_tag::none, *this, ec);
161+
visitor.begin_array(semantic_tag::none, *this, ec);
162+
more_ = !cursor_mode_;
141163
}
142164
}
143165

@@ -242,15 +264,17 @@ class basic_bson_parser : public ser_context
242264

243265
auto length = binary::little_to_native<int32_t>(buf, sizeof(buf));
244266

245-
more_ = visitor.begin_object(semantic_tag::none, *this, ec);
267+
visitor.begin_object(semantic_tag::none, *this, ec);
268+
more_ = !cursor_mode_;
246269
state_stack_.emplace_back(parse_mode::document,length,n);
247270
}
248271

249272
void end_document(json_visitor& visitor, std::error_code& ec)
250273
{
251274
JSONCONS_ASSERT(state_stack_.size() >= 2);
252275

253-
more_ = visitor.end_object(*this,ec);
276+
visitor.end_object(*this,ec);
277+
more_ = !cursor_mode_;
254278
if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length))
255279
{
256280
ec = bson_errc::size_mismatch;
@@ -280,7 +304,8 @@ class basic_bson_parser : public ser_context
280304
}
281305
auto length = binary::little_to_native<int32_t>(buf, sizeof(buf));
282306

283-
more_ = visitor.begin_array(semantic_tag::none, *this, ec);
307+
visitor.begin_array(semantic_tag::none, *this, ec);
308+
more_ = !cursor_mode_;
284309
if (ec)
285310
{
286311
return;
@@ -292,7 +317,8 @@ class basic_bson_parser : public ser_context
292317
{
293318
JSONCONS_ASSERT(state_stack_.size() >= 2);
294319

295-
more_ = visitor.end_array(*this, ec);
320+
visitor.end_array(*this, ec);
321+
more_ = !cursor_mode_;
296322
if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length))
297323
{
298324
ec = bson_errc::size_mismatch;
@@ -321,7 +347,8 @@ class basic_bson_parser : public ser_context
321347
more_ = false;
322348
return;
323349
}
324-
more_ = visitor.key(jsoncons::basic_string_view<char>(name_buffer_.data(),name_buffer_.length()), *this, ec);
350+
visitor.key(jsoncons::basic_string_view<char>(name_buffer_.data(),name_buffer_.length()), *this, ec);
351+
more_ = !cursor_mode_;
325352
}
326353
}
327354

@@ -341,7 +368,8 @@ class basic_bson_parser : public ser_context
341368
return;
342369
}
343370
double res = binary::little_to_native<double>(buf, sizeof(buf));
344-
more_ = visitor.double_value(res, semantic_tag::none, *this, ec);
371+
visitor.double_value(res, semantic_tag::none, *this, ec);
372+
more_ = !cursor_mode_;
345373
break;
346374
}
347375
case jsoncons::bson::bson_type::symbol_type:
@@ -362,7 +390,8 @@ class basic_bson_parser : public ser_context
362390
more_ = false;
363391
return;
364392
}
365-
more_ = visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
393+
visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
394+
more_ = !cursor_mode_;
366395
break;
367396
}
368397
case jsoncons::bson::bson_type::javascript_type:
@@ -380,7 +409,8 @@ class basic_bson_parser : public ser_context
380409
more_ = false;
381410
return;
382411
}
383-
more_ = visitor.string_value(text_buffer_, semantic_tag::code, *this, ec);
412+
visitor.string_value(text_buffer_, semantic_tag::code, *this, ec);
413+
more_ = !cursor_mode_;
384414
break;
385415
}
386416
case jsoncons::bson::bson_type::regex_type:
@@ -398,7 +428,8 @@ class basic_bson_parser : public ser_context
398428
{
399429
return;
400430
}
401-
more_ = visitor.string_value(text_buffer_, semantic_tag::regex, *this, ec);
431+
visitor.string_value(text_buffer_, semantic_tag::regex, *this, ec);
432+
more_ = !cursor_mode_;
402433
break;
403434
}
404435
case jsoncons::bson::bson_type::document_type:
@@ -414,12 +445,14 @@ class basic_bson_parser : public ser_context
414445
}
415446
case jsoncons::bson::bson_type::undefined_type:
416447
{
417-
more_ = visitor.null_value(semantic_tag::undefined, *this, ec);
448+
visitor.null_value(semantic_tag::undefined, *this, ec);
449+
more_ = !cursor_mode_;
418450
break;
419451
}
420452
case jsoncons::bson::bson_type::null_type:
421453
{
422-
more_ = visitor.null_value(semantic_tag::none, *this, ec);
454+
visitor.null_value(semantic_tag::none, *this, ec);
455+
more_ = !cursor_mode_;
423456
break;
424457
}
425458
case jsoncons::bson::bson_type::bool_type:
@@ -433,7 +466,8 @@ class basic_bson_parser : public ser_context
433466
more_ = false;
434467
return;
435468
}
436-
more_ = visitor.bool_value(c != 0, semantic_tag::none, *this, ec);
469+
visitor.bool_value(c != 0, semantic_tag::none, *this, ec);
470+
more_ = !cursor_mode_;
437471
break;
438472
}
439473
case jsoncons::bson::bson_type::int32_type:
@@ -448,7 +482,8 @@ class basic_bson_parser : public ser_context
448482
return;
449483
}
450484
auto val = binary::little_to_native<int32_t>(buf, sizeof(buf));
451-
more_ = visitor.int64_value(val, semantic_tag::none, *this, ec);
485+
visitor.int64_value(val, semantic_tag::none, *this, ec);
486+
more_ = !cursor_mode_;
452487
break;
453488
}
454489

@@ -464,7 +499,8 @@ class basic_bson_parser : public ser_context
464499
return;
465500
}
466501
auto val = binary::little_to_native<uint64_t>(buf, sizeof(buf));
467-
more_ = visitor.uint64_value(val, semantic_tag::none, *this, ec);
502+
visitor.uint64_value(val, semantic_tag::none, *this, ec);
503+
more_ = !cursor_mode_;
468504
break;
469505
}
470506

@@ -480,7 +516,8 @@ class basic_bson_parser : public ser_context
480516
return;
481517
}
482518
auto val = binary::little_to_native<int64_t>(buf, sizeof(buf));
483-
more_ = visitor.int64_value(val, semantic_tag::none, *this, ec);
519+
visitor.int64_value(val, semantic_tag::none, *this, ec);
520+
more_ = !cursor_mode_;
484521
break;
485522
}
486523

@@ -496,7 +533,8 @@ class basic_bson_parser : public ser_context
496533
return;
497534
}
498535
auto val = binary::little_to_native<int64_t>(buf, sizeof(buf));
499-
more_ = visitor.int64_value(val, semantic_tag::epoch_milli, *this, ec);
536+
visitor.int64_value(val, semantic_tag::epoch_milli, *this, ec);
537+
more_ = !cursor_mode_;
500538
break;
501539
}
502540
case jsoncons::bson::bson_type::binary_type:
@@ -537,10 +575,11 @@ class basic_bson_parser : public ser_context
537575
return;
538576
}
539577

540-
more_ = visitor.byte_string_value(bytes_buffer_,
578+
visitor.byte_string_value(bytes_buffer_,
541579
subtype,
542580
*this,
543581
ec);
582+
more_ = !cursor_mode_;
544583
break;
545584
}
546585
case jsoncons::bson::bson_type::decimal128_type:
@@ -562,7 +601,8 @@ class basic_bson_parser : public ser_context
562601
text_buffer_.clear();
563602
text_buffer_.resize(bson::decimal128_limits::buf_size);
564603
auto r = bson::decimal128_to_chars(&text_buffer_[0], &text_buffer_[0]+text_buffer_.size(), dec);
565-
more_ = visitor.string_value(string_view(text_buffer_.data(),static_cast<std::size_t>(r.ptr-text_buffer_.data())), semantic_tag::float128, *this, ec);
604+
visitor.string_value(string_view(text_buffer_.data(),static_cast<std::size_t>(r.ptr-text_buffer_.data())), semantic_tag::float128, *this, ec);
605+
more_ = !cursor_mode_;
566606
break;
567607
}
568608
case jsoncons::bson::bson_type::object_id_type:
@@ -580,7 +620,8 @@ class basic_bson_parser : public ser_context
580620
oid_t oid(buf);
581621
to_string(oid, text_buffer_);
582622

583-
more_ = visitor.string_value(text_buffer_, semantic_tag::id, *this, ec);
623+
visitor.string_value(text_buffer_, semantic_tag::id, *this, ec);
624+
more_ = !cursor_mode_;
584625
break;
585626
}
586627
default:

include/jsoncons_ext/cbor/cbor_cursor.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class basic_cbor_cursor : public basic_staj_cursor<char>, private virtual ser_co
3636
basic_cbor_parser<Source,Allocator> parser_;
3737
basic_staj_visitor<char_type> cursor_visitor_;
3838
basic_item_event_visitor_to_json_visitor<char_type,Allocator> cursor_handler_adaptor_;
39-
bool eof_;
39+
bool eof_{false};
4040

4141
public:
4242
using string_view_type = string_view;
@@ -51,8 +51,7 @@ class basic_cbor_cursor : public basic_staj_cursor<char>, private virtual ser_co
5151
const Allocator& alloc = Allocator())
5252
: parser_(std::forward<Sourceable>(source), options, alloc),
5353
cursor_visitor_(accept_all),
54-
cursor_handler_adaptor_(cursor_visitor_, alloc),
55-
eof_(false)
54+
cursor_handler_adaptor_(cursor_visitor_, alloc)
5655
{
5756
if (!done())
5857
{

include/jsoncons_ext/cbor/cbor_parser.hpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,12 @@ class basic_cbor_parser : public ser_context
134134
bool done_{false};
135135
string_type text_buffer_;
136136
byte_string_type bytes_buffer_;
137-
uint64_t raw_tag_;
137+
uint64_t raw_tag_{0};
138138
std::vector<parse_state,parse_state_allocator_type> state_stack_;
139139
byte_string_type typed_array_;
140140
std::vector<std::size_t> shape_;
141-
std::size_t index_; // TODO: Never used!
142141
std::vector<stringref_map,stringref_map_allocator_type> stringref_map_stack_;
143-
int nesting_depth_;
142+
int nesting_depth_{0};
144143

145144
struct read_byte_string_from_buffer
146145
{
@@ -187,12 +186,9 @@ class basic_cbor_parser : public ser_context
187186
options_(options),
188187
text_buffer_(alloc),
189188
bytes_buffer_(alloc),
190-
raw_tag_(0),
191189
state_stack_(alloc),
192190
typed_array_(alloc),
193-
index_(0),
194-
stringref_map_stack_(alloc),
195-
nesting_depth_(0)
191+
stringref_map_stack_(alloc)
196192
{
197193
state_stack_.emplace_back(parse_mode::root,0);
198194
}

0 commit comments

Comments
 (0)