rapidyaml 0.14.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
c4::yml::extra::EventHandlerInts Struct Reference

A parser event handler that creates a compact representation of the YAML tree in a contiguous buffer of integers. More...

#include <event_handler_ints.hpp>

Public Types

types
enum  { requires_strings_on_buffers = true }
using value_type = ievt::DataType
using state = EventHandlerIntsState

Public Member Functions

construction and resetting
 EventHandlerInts (c4::yml::Callbacks const &cb)
 EventHandlerInts ()
void reset (substr str, substr arena, ievt::DataType *dst, int32_t dst_size)
int required_size_events () const
 get the size needed for the event buffer from the previous parse
size_t required_size_arena () const
 get the size needed for the arena from the previous parse
bool fits_buffers () const
 Predicate to test if the event and arena buffers successfully accomodated all the parse events.
void reserve_arena (int)
TagDirectivestag_directives ()
TagCachetag_cache ()
parse events
void start_parse (const char *filename, substr src)
void finish_parse ()
void cancel_parse ()
YAML stream events
void begin_stream ()
void end_stream ()
YAML document events
void begin_doc ()
 implicit doc start (without —)
void end_doc ()
 implicit doc end (without ...)
void begin_doc_expl ()
 explicit doc start, with —
void end_doc_expl ()
 explicit doc end, with ...
YAML map functions
void begin_map_key_flow ()
void begin_map_key_block ()
void begin_map_val_flow ()
void begin_map_val_block ()
void end_map_block ()
void end_map_flow (bool)
YAML seq events
void begin_seq_key_flow ()
void begin_seq_key_block ()
void begin_seq_val_flow ()
void begin_seq_val_block ()
void end_seq_block ()
void end_seq_flow (bool)
YAML structure events
void add_sibling ()
void actually_val_is_first_key_of_new_map_flow ()
 set the previous val as the first key of a new map, with flow style.
void actually_val_is_first_key_of_new_map_block ()
 like its flow counterpart, but this function can only be called after the end of a flow-val at root or doc level.
YAML scalar events
void set_key_scalar_plain_empty ()
void set_val_scalar_plain_empty ()
void set_key_scalar_plain (csubstr scalar)
void set_val_scalar_plain (csubstr scalar)
void set_key_scalar_dquoted (csubstr scalar)
void set_val_scalar_dquoted (csubstr scalar)
void set_key_scalar_squoted (csubstr scalar)
void set_val_scalar_squoted (csubstr scalar)
void set_key_scalar_literal (csubstr scalar)
void set_val_scalar_literal (csubstr scalar)
void set_key_scalar_folded (csubstr scalar)
void set_val_scalar_folded (csubstr scalar)
void mark_key_scalar_unfiltered ()
void mark_val_scalar_unfiltered ()
YAML anchor/reference events
void set_key_anchor (csubstr anchor)
void set_val_anchor (csubstr anchor)
void set_key_ref (csubstr ref)
void set_val_ref (csubstr ref)
YAML tag events
void set_key_tag (csubstr tag)
void set_val_tag (csubstr tag)
YAML directive events
void add_directive_yaml (csubstr yaml_version)
void add_directive_tag (csubstr handle, csubstr prefix)
arena events
substr arena ()
substr arena_rem ()
substr alloc_arena (size_t len)
 this may fail, in which case an empty string is returned
implementation helpers
void _push ()
 push a new parent, add a child to the new parent, and set the child as the current node
void _pop ()
 end the current scope
template<c4::yml::type_bits bits>
void _enable__ () noexcept
template<c4::yml::type_bits bits>
void _disable__ () noexcept
template<c4::yml::type_bits bits>
bool _has_any__ () const noexcept
int32_t _next (int32_t pos) const noexcept
int32_t _prev (int32_t pos) const noexcept
bool _is_sub_ (csubstr str) const noexcept
void _send_flag_only_ (ievt::DataType flags)
void _send_str_ (csubstr scalar, ievt::DataType flags)
void _mark_parent_with_children_ ()
csubstr _get_latest_empty_scalar () const
int32_t _find_last_bdoc (int32_t pos) const
int32_t _find_matching_open (ievt::DataType open, ievt::DataType close, int32_t pos) const
int32_t _extend_left_to_include_tag_and_or_anchor (int32_t pos) const

Public Attributes

detail::stack< statem_stack
statem_curr
 current stack level: top of the stack. cached here for easier access.
statem_parent
 parent of the current stack level.
substr m_src

Protected Member Functions

void _stack_start_parse (const char *filename, substr ymlsrc)
void _stack_finish_parse ()
void _stack_reset_root ()
void _stack_reset_non_root ()
void _stack_push ()
void _stack_pop ()
bool _stack_should_push_on_begin_doc () const
bool _stack_should_pop_on_end_doc () const

Detailed Description

A parser event handler that creates a compact representation of the YAML tree in a contiguous buffer of integers.

The integers are ievt::EventFlags containing masks (to represent events), interleaved with offset+length (to represent strings in the source buffer).

This is meant for use by other programming languages, and supports container keys (unlike the ryml tree). It parses faster than the ryml tree parser, because the resulting data structure is much simpler.

The resulting integer buffer is a linear array of integers containing events (as a mask of ievt::EventFlags), which in some cases (see ievt::WSTR) are followed by an encoded string (encoded as an offset and length to the parsed source buffer).

For example, parsing [a, bb, ccc] results in the following event buffer (grouped to highlight the event sequence structure):

using namespace c4::yml::extra::ievt;
const DataType arr[] = { // result of parsing: [a, bb, ccc]
BSTR, // begin stream
BDOC, // begin doc
VAL_|BSEQ|FLOW, // begin seq as val, flow
VAL_|SCLR|PLAI, 1, 1, // val scalar, plain style: "a" starts at offset 1 and has length 1
VAL_|SCLR|PLAI|PSTR, 4, 2, // val scalar, plain style: "bb" starts at offset 4 and has length 2; preceded by a string event (PSTR)
VAL_|SCLR|PLAI|PSTR, 8, 3, // val scalar, plain style: "ccc" starts at offset 8 and has length 3; preceded by a string event (PSTR)
ESEQ|PSTR, // end seq; preceded by a string event (PSTR)
EDOC, // end doc
ESTR, // end stream
};
int32_t DataType
data type for integer events.
@ SCLR
scalar (=VAL in test suite events)
@ ESTR
end stream (-STR in test suite events)
@ BSTR
begin stream (+STR in test suite events)
@ BSEQ
begin seq (+SEQ in test suite events)
@ ESEQ
end seq (-SEQ in test suite events)
@ FLOW
container: flow: [] for seqs or {} for maps
@ VAL_
as value special flag to enable look-back in the event array. it signifies that the previous event ha...
@ BDOC
begin doc (+DOC in test suite events)
@ EDOC
end doc (-DOC in test suite events)

Here is a sketch clarifying the meaning of this event sequence:

source : [a, bb, ccc]
has a string........
| offset "a"
| | length "a"
| | |
event0 event1 event2 [ event3 "a"......|..|
| | | | | |
(start) +--------+-------+------------------+---------------+--+-----> (continued)
arr[i] : BSTR BDOC VAL_|BSEQ|FLOW VAL_|SCLR|PLAI..1..1
i : 0 1 2 3 4 5
has a string............. has a string.............
| offset "bb" | offset "ccc"
| | length "bb" | | length "ccc"
| | | | | |
event4 "bb"..........|..| event5 "ccc".........|..|
| | | | | |
(cont)--> -----+--------------------+--+--------------+--------------------+--+-----> (continued)
arr[i] : VAL_|SCLR|PLAI|PSTR..4..2 VAL_|SCLR|PLAI|PSTR..8..3
i : 6 | 7 8 9 | 10 11
| |
prev event has string prev event has string
(to get to prev, jump (to get to prev, jump
back 3 slots: ie 6->3) back 3 slots: ie 9->6)
event6 ] event7 event8
| | |
(cont)--> -----+-------------+--------+-----| (end)
arr[i] : ESEQ|PSTR EDOC ESTR
i : 12 | 13 14
|
prev event has string
(to get to it, jump
back 3 slots: ie 12->9)

Note that the buffer contains both events and strings encoded as integer pairs. That is, events that have an associated string are immediately followed by two integers providing the offset and length of that string in the source buffer. (In the example above, this happens in the events for the strings a, bb, and ccc at positions 3, 6 and 9, respectively).

The flag ievt::PSTR and the mask ievt::WSTR are provided to enable easier iteration over the array: you can use them to test for presence of a string when iterating over the array.

The flag ievt::PSTR announces that an event is preceded by a string. That is, the previous event has a string, so that when this flag is found while iterating right-to-left, a jump of -3 should be used to get at the bitmask of the previous event. (In the example above, this flag is present for the events for bb and ccc, but not a because it is not preceded by a string).

Likewise, to signify that the current event is followed by a string, there is the mask ievt::WSTR, which is a mask of all the flags of events that have a string: ievt::SCLR, ievt::ALIA, ievt::ANCH and ievt::TAG_. While iterating left-to-right in the array, presence of any of the bits in the mask ievt::WSTR means that a jump of +3 should be employed to get at the bitmask of the next event.

Here's another example with the result of parsing a: bb

const DataType arr[] = { // result of parsing: `a: bb`
BSTR, // begin stream
BDOC, // begin doc
VAL_|BMAP|BLCK, // begin map as val, block
KEY_|SCLR|PLAI, 0, 1, // key scalar, plain style: "a" starts at offset 0 and has length 1
VAL_|SCLR|PLAI|PSTR, 3, 2, // val scalar, plain style: "bb" starts at offset 3 and has length 2
EMAP|PSTR, // end map
EDOC, // end doc
ESTR, // end stream
};
@ EMAP
end map (-MAP in test suite events)
@ BMAP
begin map (+MAP in test suite events)

Typical code to iterate left-to-right over the array will look like this:

// source buffer, modified in place during parsing (IMPORTANT!)
substr src = ...;
substr arena = ...; // arena used for scalars/tags that are extended during filtering
// events resulting from parsing
const int events[] = {...};
int events_size = ...;
for(int i = 0; i < events_size; ++i)
{
if(events[i] & ievt::WSTR) // this event has a string following it
{
size_t offset = (size_t)events[i+1];
size_t length = (size_t)events[i+2];
csubstr region = (events[i] & ievt::AREN) ? arena : src; // is the string in the arena?
csubstr str = region.sub(offset, length); // get the string
...
i += 2; // skip the two ints of the string
// (the jump is three places; the loop adds the other place)
}
else // this is a single-int event
{
...
}
}
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2356
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2357
@ WSTR
WithSTRing: mask of all the events that encode a string following the event. For such events,...
@ AREN
IMPORTANT. Marks events whose string was placed in the arena. This happens when the filtered string i...
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:503

This handler must be initialized with the input source buffer, the output arena, and the output event buffer. This handler will not take ownership nor attempt to resize the output buffer. If the size required for the output buffer or arena are larger than their actual size, parsing goes all way to the end, determining the required buffer sizes without writing anything past the end of the respective buffer. After parsing is finished, the user must ensure that the buffer size was enough to accomodate all the data that needs to be written into it, or react accordingly (eg, throw an error, or resize the buffer then retry the parse).

A couple of functions will be helpful to do this. After parsing, EventHandlerInts::fits_buffers() must be used to verify that the output buffers were enough to accomodate the results. Then, EventHandlerInts::required_size_events() and EventHandlerInts::required_size_arena() can be used to retrieve to necessary information. To get an estimation of the number of events before parsing, see estimate_events_ints_size().

Typical code to parse YAML with this handler will look like this:

csubstr filename = ...;
substr src = ...;
// estimate the size required for the events buffer,
// overpredicting it to be safe.
int estimated_size = extra::estimate_events_ints_size(src);
// example with a vector
std::vector<int> evts;
// ensure we have a fighting chance to acommodate the events
evts.resize((size_t)estimated_size);
// arena to place scalars/tags that may have been extended after filtering
std::vector<char> arena;
arena.resize(src.len); // this is generally enough
// initialize the handler
handler.reset(src, arena, evts.data(), (int)evts.size());
// parse the YAML
parser.parse_in_place_ev(filename, src);
if(handler.fits_buffers()) // were the buffer sizes enough?
{
evts.resize((size_t)handler.required_size_events()); // trim the vector
...
}
else
{
// event size estimation underpredicted, or arena is too small!
// for the first case, open an issue at
// https://github.com/biojppm/rapidyaml/issues
error("buffer could not accomodate all the events");
// NOTE: see below for notes on doing a parse retry.
}
This is the main driver of parsing logic: it scans the YAML or JSON source for tokens,...
int32_t estimate_events_ints_size(csubstr src)
Read YAML source and, without undergoing a full parse, estimate the size of the integer buffer requir...
size_t len
the length of the substring
Definition substr.hpp:218
A parser event handler that creates a compact representation of the YAML tree in a contiguous buffer ...
bool fits_buffers() const
Predicate to test if the event and arena buffers successfully accomodated all the parse events.
int required_size_events() const
get the size needed for the event buffer from the previous parse
void reset(substr str, substr arena, ievt::DataType *dst, int32_t dst_size)

The result of estimate_events_ints_size() (click to see more info) must be an overprediction: it overpredicts for every single case among the many hundreds covered in the unit tests. This is deliberate, and aims at ensuring that a retry parse is not needed. But conceivably, it may underpredict in some instances not found in the out tests. What to do then?

First, open an issue to allow the estimation to be improved! Second, there are two ways to handle this situation in code:

1) throw an error (as sketched above)

2) grow the buffer to the required size (see EventHandlerInts::required_size_events()), and then parse again

If your code must be able to handle any case including where the prediction undershoots before the estimate function is fixed (after you open the issue), that is, if you are considering a parse retry, there is something important that needs attention. The YAML source buffer is mutated in-place during the parse, and cannot be used to parse again. So if you want to retry, you need to keep a pristine copy of the source, and use it for the retry:

const std::string src = ...; // the YAML code to be parsed
std::string parsed_src = src; // this is where we will parse (filter during parsing)
std::vector<int> evts((size_t)estimated_size); // ensure we have a fighting change to acommodate the events
std::vector<char> arena(src.size()); // ensure we have a fighting change to acommodate the events
handler.reset(to_substr(parsed_src), to_substr(arena), evts.data(), (int)evts.size());
parser.parse_in_place_ev(filename, to_substr(parsed_src));
if(handler.fits_buffers()) // were the buffer sizes enough?
{
evts.resize((size_t)handler.required_size()); // trim the vector
...
}
else
{
evts.resize((size_t)handler.required_size_events()); // buffer size was not enough.
arena.resize(handler.required_size_arena()); // buffer size was not enough.
// copy again
parsed_src = src;
// retry parse
handler.reset(to_substr(parsed_src), to_substr(arena), evts.data(), (int)evts.size());
parser.parse_in_place_ev(filename, to_substr(parsed_src));
assert((size_t)handler.fits_buffers()); // must always be true
}
substr to_substr(char(&s)[N]) noexcept
Definition substr.hpp:2377
size_t size() const noexcept
Definition substr.hpp:358
C * data() noexcept
Definition substr.hpp:366
size_t required_size_arena() const
get the size needed for the arena from the previous parse

When bringing this to other programming languages, the semantics will be very similar to this.

Definition at line 436 of file event_handler_ints.hpp.

Member Typedef Documentation

◆ value_type

◆ state

using c4::yml::extra::EventHandlerInts::state = EventHandlerIntsState

Definition at line 443 of file event_handler_ints.hpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
requires_strings_on_buffers 

Definition at line 444 of file event_handler_ints.hpp.

Constructor & Destructor Documentation

◆ EventHandlerInts() [1/2]

c4::yml::extra::EventHandlerInts::EventHandlerInts ( c4::yml::Callbacks const & cb)
inline

◆ EventHandlerInts() [2/2]

c4::yml::extra::EventHandlerInts::EventHandlerInts ( )
inline

Definition at line 477 of file event_handler_ints.hpp.

479 {
480 }
Callbacks const & get_callbacks()
get the global callbacks
Definition common.cpp:94

Member Function Documentation

◆ reset()

void c4::yml::extra::EventHandlerInts::reset ( substr str,
substr arena,
ievt::DataType * dst,
int32_t dst_size )
inline

Definition at line 482 of file event_handler_ints.hpp.

483 {
486 m_curr->evt_type = {};
487 m_curr->evt_id = 0;
488 m_arena = arena;
489 m_arena_pos = 0;
490 m_src = str;
491 m_evt = dst;
492 m_evt_size = dst_size;
493 m_evt_pos = 0;
494 m_evt_prev = 0;
495 m_curr_doc = 0;
496 m_tag_directives.clear();
497 m_tag_cache.clear();
498 }
@ RTOP
reading at top level
@ RUNK
reading unknown state (when starting): must determine whether scalar, map or seq

◆ required_size_events()

int c4::yml::extra::EventHandlerInts::required_size_events ( ) const
inline

get the size needed for the event buffer from the previous parse

Warning
this is valid only until the next parse

Definition at line 502 of file event_handler_ints.hpp.

503 {
504 return m_evt_pos;
505 }

◆ required_size_arena()

size_t c4::yml::extra::EventHandlerInts::required_size_arena ( ) const
inline

get the size needed for the arena from the previous parse

Warning
this is valid only until the next parse

Definition at line 509 of file event_handler_ints.hpp.

510 {
511 return m_arena_pos;
512 }

◆ fits_buffers()

bool c4::yml::extra::EventHandlerInts::fits_buffers ( ) const
inline

Predicate to test if the event and arena buffers successfully accomodated all the parse events.

Warning
this is valid only until the next parse

Definition at line 518 of file event_handler_ints.hpp.

519 {
520 return m_evt_pos <= m_evt_size && m_arena_pos <= m_arena.len;
521 }

◆ reserve_arena()

void c4::yml::extra::EventHandlerInts::reserve_arena ( int )
inline

Definition at line 523 of file event_handler_ints.hpp.

524 {
525 // does not apply here
526 }

◆ tag_directives()

TagDirectives & c4::yml::extra::EventHandlerInts::tag_directives ( )
inline

Definition at line 528 of file event_handler_ints.hpp.

528{ return m_tag_directives; }

◆ tag_cache()

TagCache & c4::yml::extra::EventHandlerInts::tag_cache ( )
inline

Definition at line 529 of file event_handler_ints.hpp.

529{ return m_tag_cache; }

◆ start_parse()

void c4::yml::extra::EventHandlerInts::start_parse ( const char * filename,
substr src )
inline

Definition at line 538 of file event_handler_ints.hpp.

539 {
540 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, src.str == m_src.str);
541 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, src.len == m_src.len);
542 this->_stack_start_parse(filename, src);
543 }

◆ finish_parse()

void c4::yml::extra::EventHandlerInts::finish_parse ( )
inline

◆ cancel_parse()

void c4::yml::extra::EventHandlerInts::cancel_parse ( )
inline

Definition at line 550 of file event_handler_ints.hpp.

551 {
552 while(m_stack.size() > 1)
553 _pop();
554 }

◆ begin_stream()

void c4::yml::extra::EventHandlerInts::begin_stream ( )
inline

Definition at line 563 of file event_handler_ints.hpp.

564 {
566 }
void _send_flag_only_(ievt::DataType flags)

◆ end_stream()

void c4::yml::extra::EventHandlerInts::end_stream ( )
inline

Definition at line 568 of file event_handler_ints.hpp.

569 {
571 }

◆ begin_doc()

void c4::yml::extra::EventHandlerInts::begin_doc ( )
inline

implicit doc start (without —)

Definition at line 581 of file event_handler_ints.hpp.

582 {
583 _c4dbgpf("{}/{}: begin_doc", m_evt_pos, m_evt_size);
586 {
587 _c4dbgp("push!");
588 _push();
589 _enable_(DOC);
590 }
591 }
@ DOC
a document
Definition node_type.hpp:41
void _push()
push a new parent, add a child to the new parent, and set the child as the current node

◆ end_doc()

void c4::yml::extra::EventHandlerInts::end_doc ( )
inline

implicit doc end (without ...)

Definition at line 593 of file event_handler_ints.hpp.

594 {
595 _c4dbgpf("{}/{}: end_doc", m_evt_pos, m_evt_size);
598 {
599 _c4dbgp("pop!");
600 _pop();
601 }
602 ++m_curr_doc;
603 }

◆ begin_doc_expl()

void c4::yml::extra::EventHandlerInts::begin_doc_expl ( )
inline

explicit doc start, with —

Definition at line 606 of file event_handler_ints.hpp.

607 {
608 _c4dbgpf("{}/{}: begin_doc_expl", m_evt_pos, m_evt_size);
610 _c4dbgp("push!");
611 _push();
612 _enable_(DOC);
613 }
@ EXPL
--- (with BDOC) or ... (with EDOC)

◆ end_doc_expl()

void c4::yml::extra::EventHandlerInts::end_doc_expl ( )
inline

explicit doc end, with ...

Definition at line 615 of file event_handler_ints.hpp.

616 {
617 _c4dbgpf("{}/{}: end_doc_expl", m_evt_pos, m_evt_size);
620 {
621 _c4dbgp("pop!");
622 _pop();
623 }
624 ++m_curr_doc;
625 }

◆ begin_map_key_flow()

void c4::yml::extra::EventHandlerInts::begin_map_key_flow ( )
inline

Definition at line 634 of file event_handler_ints.hpp.

635 {
636 _c4dbgpf("{}/{}: bmap key flow", m_evt_pos, m_evt_size);
640 _push();
641 }
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:39
@ KEY
is member of a map
Definition node_type.hpp:37
@ FLOW_SL
mark container with single-line flow style (seqs as '[val1,val2], maps as '{key: val,...
Definition node_type.hpp:60

◆ begin_map_key_block()

void c4::yml::extra::EventHandlerInts::begin_map_key_block ( )
inline

Definition at line 642 of file event_handler_ints.hpp.

643 {
644 _c4dbgpf("{}/{}: bmap key block", m_evt_pos, m_evt_size);
648 _push();
649 }
@ BLOCK
mark container with block style (seqs as '- val ', maps as 'key: val')
Definition node_type.hpp:62

◆ begin_map_val_flow()

void c4::yml::extra::EventHandlerInts::begin_map_val_flow ( )
inline

Definition at line 651 of file event_handler_ints.hpp.

652 {
653 _c4dbgpf("{}/{}: bmap flow", m_evt_pos, m_evt_size);
657 _push();
658 }

◆ begin_map_val_block()

void c4::yml::extra::EventHandlerInts::begin_map_val_block ( )
inline

Definition at line 659 of file event_handler_ints.hpp.

660 {
661 _c4dbgpf("{}/{}: bmap block", m_evt_pos, m_evt_size);
665 _push();
666 }

◆ end_map_block()

void c4::yml::extra::EventHandlerInts::end_map_block ( )
inline

Definition at line 668 of file event_handler_ints.hpp.

669 {
670 _pop();
672 }

◆ end_map_flow()

void c4::yml::extra::EventHandlerInts::end_map_flow ( bool )
inline

Definition at line 674 of file event_handler_ints.hpp.

675 {
676 _pop();
678 }

◆ begin_seq_key_flow()

void c4::yml::extra::EventHandlerInts::begin_seq_key_flow ( )
inline

Definition at line 687 of file event_handler_ints.hpp.

688 {
689 _c4dbgpf("{}/{}: bseq key flow", m_evt_pos, m_evt_size);
693 _push();
694 }
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:40

◆ begin_seq_key_block()

void c4::yml::extra::EventHandlerInts::begin_seq_key_block ( )
inline

Definition at line 695 of file event_handler_ints.hpp.

696 {
697 _c4dbgpf("{}/{}: bseq key block", m_evt_pos, m_evt_size);
701 _push();
702 }

◆ begin_seq_val_flow()

void c4::yml::extra::EventHandlerInts::begin_seq_val_flow ( )
inline

Definition at line 704 of file event_handler_ints.hpp.

705 {
706 _c4dbgpf("{}/{}: bseq flow", m_evt_pos, m_evt_size);
710 _push();
711 }

◆ begin_seq_val_block()

void c4::yml::extra::EventHandlerInts::begin_seq_val_block ( )
inline

Definition at line 712 of file event_handler_ints.hpp.

713 {
714 _c4dbgpf("{}/{}: bseq block", m_evt_pos, m_evt_size);
718 _push();
719 }

◆ end_seq_block()

void c4::yml::extra::EventHandlerInts::end_seq_block ( )
inline

Definition at line 721 of file event_handler_ints.hpp.

722 {
723 _pop();
725 }

◆ end_seq_flow()

void c4::yml::extra::EventHandlerInts::end_seq_flow ( bool )
inline

Definition at line 727 of file event_handler_ints.hpp.

728 {
729 _pop();
731 }

◆ add_sibling()

void c4::yml::extra::EventHandlerInts::add_sibling ( )
inline

Definition at line 740 of file event_handler_ints.hpp.

741 {
742 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_parent);
743 m_curr->evt_type = {};
744 }

◆ set_key_scalar_plain_empty()

void c4::yml::extra::EventHandlerInts::set_key_scalar_plain_empty ( )
inline

Definition at line 754 of file event_handler_ints.hpp.

755 {
756 _c4dbgpf("{}/{}: set_key_scalar_plain_empty", m_evt_pos, m_evt_size);
759 }
@ KEY_PLAIN
mark key scalar as plain scalar (unquoted, even when multiline)
Definition node_type.hpp:71
@ KEYNIL
the key is null (eg { : b} results in a null key)
Definition node_type.hpp:49
void _send_str_(csubstr scalar, ievt::DataType flags)

◆ set_val_scalar_plain_empty()

void c4::yml::extra::EventHandlerInts::set_val_scalar_plain_empty ( )
inline

Definition at line 760 of file event_handler_ints.hpp.

761 {
762 _c4dbgpf("{}/{}: set_val_scalar_plain_empty", m_evt_pos, m_evt_size);
765 }
@ VALNIL
the val is null (eg {a : } results in a null val)
Definition node_type.hpp:50
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
Definition node_type.hpp:38
@ VAL_PLAIN
mark val scalar as plain scalar (unquoted, even when multiline)
Definition node_type.hpp:72

◆ set_key_scalar_plain()

void c4::yml::extra::EventHandlerInts::set_key_scalar_plain ( csubstr scalar)
inline

Definition at line 768 of file event_handler_ints.hpp.

769 {
770 _c4dbgpf("{}/{}: set_key_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
773 }

◆ set_val_scalar_plain()

void c4::yml::extra::EventHandlerInts::set_val_scalar_plain ( csubstr scalar)
inline

Definition at line 774 of file event_handler_ints.hpp.

775 {
776 _c4dbgpf("{}/{}: set_val_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
779 }

◆ set_key_scalar_dquoted()

void c4::yml::extra::EventHandlerInts::set_key_scalar_dquoted ( csubstr scalar)
inline

Definition at line 782 of file event_handler_ints.hpp.

783 {
784 _c4dbgpf("{}/{}: set_key_scalar_dquo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
787 }
@ KEY_DQUO
mark key scalar as double quoted "
Definition node_type.hpp:69
@ DQUO
scalar: double-quoted ("")

◆ set_val_scalar_dquoted()

void c4::yml::extra::EventHandlerInts::set_val_scalar_dquoted ( csubstr scalar)
inline

Definition at line 788 of file event_handler_ints.hpp.

789 {
790 _c4dbgpf("{}/{}: set_val_scalar_dquo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
793 }
@ VAL_DQUO
mark val scalar as double quoted "
Definition node_type.hpp:70

◆ set_key_scalar_squoted()

void c4::yml::extra::EventHandlerInts::set_key_scalar_squoted ( csubstr scalar)
inline

Definition at line 796 of file event_handler_ints.hpp.

797 {
798 _c4dbgpf("{}/{}: set_key_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
801 }
@ KEY_SQUO
mark key scalar as single quoted '
Definition node_type.hpp:67
@ SQUO
scalar: single-quoted (')

◆ set_val_scalar_squoted()

void c4::yml::extra::EventHandlerInts::set_val_scalar_squoted ( csubstr scalar)
inline

Definition at line 802 of file event_handler_ints.hpp.

803 {
804 _c4dbgpf("{}/{}: set_val_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
807 }
@ VAL_SQUO
mark val scalar as single quoted '
Definition node_type.hpp:68

◆ set_key_scalar_literal()

void c4::yml::extra::EventHandlerInts::set_key_scalar_literal ( csubstr scalar)
inline

Definition at line 810 of file event_handler_ints.hpp.

811 {
812 _c4dbgpf("{}/{}: set_key_scalar_literal: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
815 }
@ KEY_LITERAL
mark key scalar as multiline, block literal |
Definition node_type.hpp:63
@ LITL
scalar: block literal (|)

◆ set_val_scalar_literal()

void c4::yml::extra::EventHandlerInts::set_val_scalar_literal ( csubstr scalar)
inline

Definition at line 816 of file event_handler_ints.hpp.

817 {
818 _c4dbgpf("{}/{}: set_val_scalar_literal: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
821 }
@ VAL_LITERAL
mark val scalar as multiline, block literal |
Definition node_type.hpp:64

◆ set_key_scalar_folded()

void c4::yml::extra::EventHandlerInts::set_key_scalar_folded ( csubstr scalar)
inline

Definition at line 824 of file event_handler_ints.hpp.

825 {
826 _c4dbgpf("{}/{}: set_key_scalar_folded: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
829 }
@ KEY_FOLDED
mark key scalar as multiline, block folded >
Definition node_type.hpp:65
@ FOLD
scalar: block folded (>)

◆ set_val_scalar_folded()

void c4::yml::extra::EventHandlerInts::set_val_scalar_folded ( csubstr scalar)
inline

Definition at line 830 of file event_handler_ints.hpp.

831 {
832 _c4dbgpf("{}/{}: set_val_scalar_folded: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str?size_t(scalar.str-m_src.str):m_src.len, scalar.len, scalar.str?scalar:csubstr{});
835 }
@ VAL_FOLDED
mark val scalar as multiline, block folded >
Definition node_type.hpp:66

◆ mark_key_scalar_unfiltered()

void c4::yml::extra::EventHandlerInts::mark_key_scalar_unfiltered ( )
inline

Definition at line 838 of file event_handler_ints.hpp.

839 {
840 _c4dbgpf("{}/{}: mark_key_scalar_unfiltered", m_evt_pos, m_evt_size);
841 if(m_evt_pos < m_evt_size)
842 m_evt[m_evt_pos] |= ievt::UNFILT;
843 }
@ UNFILT
special flag to mark a scalar as unfiltered (when the parser is set not to filter).

◆ mark_val_scalar_unfiltered()

void c4::yml::extra::EventHandlerInts::mark_val_scalar_unfiltered ( )
inline

Definition at line 844 of file event_handler_ints.hpp.

845 {
846 _c4dbgpf("{}/{}: mark_val_scalar_unfiltered", m_evt_pos, m_evt_size);
847 if(m_evt_pos < m_evt_size)
848 m_evt[m_evt_pos] |= ievt::UNFILT;
849 }

◆ set_key_anchor()

void c4::yml::extra::EventHandlerInts::set_key_anchor ( csubstr anchor)
inline

Definition at line 880 of file event_handler_ints.hpp.

881 {
882 _c4dbgpf("{}/{}: set_key_anchor: {}", m_evt_pos, m_evt_size, anchor);
883 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, !_has_any_(KEYREF));
884 _enable_(c4::yml::KEYANCH);
885 if(m_evt_pos + 3 < m_evt_size)
886 {
887 m_evt[m_evt_pos] |= ievt::KEY_|ievt::ANCH;
888 _add_scalar_(m_evt_pos, anchor);
889 }
890 m_evt_prev = m_evt_pos;
891 m_evt_pos += 3;
892 }
#define _has_any_(bits)
@ KEYREF
a *reference: the key references an &anchor
Definition node_type.hpp:43
@ KEYANCH
the key has an &anchor
Definition node_type.hpp:45

◆ set_val_anchor()

void c4::yml::extra::EventHandlerInts::set_val_anchor ( csubstr anchor)
inline

Definition at line 893 of file event_handler_ints.hpp.

894 {
895 _c4dbgpf("{}/{}: set_val_anchor: {}", m_evt_pos, m_evt_size, anchor);
896 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, !_has_any_(VALREF));
897 _enable_(c4::yml::VALANCH);
898 if(m_evt_pos + 3 < m_evt_size)
899 {
900 m_evt[m_evt_pos] |= ievt::VAL_|ievt::ANCH;
901 _add_scalar_(m_evt_pos, anchor);
902 }
903 m_evt_prev = m_evt_pos;
904 m_evt_pos += 3;
905 }
@ VALANCH
the val has an &anchor
Definition node_type.hpp:46
@ VALREF
a *reference: the val references an &anchor
Definition node_type.hpp:44

◆ set_key_ref()

void c4::yml::extra::EventHandlerInts::set_key_ref ( csubstr ref)
inline

Definition at line 907 of file event_handler_ints.hpp.

908 {
909 _c4dbgpf("{}/{}: set_key_ref: {}", m_evt_pos, m_evt_size, ref);
910 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, ref.begins_with('*'));
911 if(C4_UNLIKELY(_has_any_(KEYANCH)))
912 _RYML_ERR_PARSE_(m_stack.m_callbacks, m_curr->pos, "key cannot have both anchor and ref");
914 _send_str_(ref.sub(1), ievt::KEY_|ievt::ALIA); // skip the leading *
915 }

◆ set_val_ref()

void c4::yml::extra::EventHandlerInts::set_val_ref ( csubstr ref)
inline

Definition at line 916 of file event_handler_ints.hpp.

917 {
918 _c4dbgpf("{}/{}: set_val_ref: {}", m_evt_pos, m_evt_size, ref);
919 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, ref.begins_with('*'));
920 if(C4_UNLIKELY(_has_any_(VALANCH)))
921 _RYML_ERR_PARSE_(m_stack.m_callbacks, m_curr->pos, "val cannot have both anchor and ref");
923 _send_str_(ref.sub(1), ievt::VAL_|ievt::ALIA); // skip the leading *
924 }

◆ set_key_tag()

void c4::yml::extra::EventHandlerInts::set_key_tag ( csubstr tag)
inline

Definition at line 933 of file event_handler_ints.hpp.

934 {
935 _c4dbgpf("{}/{}: set key tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.len, tag.str ? tag : csubstr("(arena full)"));
936 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, _is_sub_(tag));
937 _enable_(c4::yml::KEYTAG);
939 }
@ KEYTAG
the key has a tag
Definition node_type.hpp:47
bool _is_sub_(csubstr str) const noexcept

◆ set_val_tag()

void c4::yml::extra::EventHandlerInts::set_val_tag ( csubstr tag)
inline

Definition at line 940 of file event_handler_ints.hpp.

941 {
942 _c4dbgpf("{}/{}: set val tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.len, tag.str ? tag : csubstr("(arena full)"));
943 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, _is_sub_(tag));
944 _enable_(c4::yml::VALTAG);
946 }
@ VALTAG
the val has a tag
Definition node_type.hpp:48

◆ add_directive_yaml()

void c4::yml::extra::EventHandlerInts::add_directive_yaml ( csubstr yaml_version)
inline

Definition at line 955 of file event_handler_ints.hpp.

956 {
957 _c4dbgpf("{}/{}: %YAML directive! version={}", m_evt_pos, m_evt_size, yaml_version);
958 _send_str_(yaml_version, ievt::YAML);
959 }
@ YAML
yaml directive: \YAML <version>

◆ add_directive_tag()

void c4::yml::extra::EventHandlerInts::add_directive_tag ( csubstr handle,
csubstr prefix )
inline

Definition at line 961 of file event_handler_ints.hpp.

962 {
963 _c4dbgpf("{}/{}: %TAG directive! handle={} prefix={} doc_id={}", m_evt_pos, m_evt_size, handle, prefix, m_curr_doc);
964 if(C4_UNLIKELY(!m_tag_directives.add(handle, prefix, m_curr_doc)))
965 _RYML_ERR_PARSE_(m_stack.m_callbacks, m_curr->pos, "too many %TAG directives");
966 _send_str_(handle, ievt::TAGH);
967 _send_str_(prefix, ievt::TAGP);
968 }
@ TAGH
tag directive, handle: \TAG <handle> ........
@ TAGP
tag directive, prefix: \TAG ........ <prefix>

◆ actually_val_is_first_key_of_new_map_flow()

void c4::yml::extra::EventHandlerInts::actually_val_is_first_key_of_new_map_flow ( )
inline

set the previous val as the first key of a new map, with flow style.

See the documentation for Event Handlers, which has important notes about this event.

Definition at line 982 of file event_handler_ints.hpp.

983 {
984 _c4dbgpf("{}/{}: prev={} actually_val_is_first_key_of_new_map_flow", m_evt_pos, m_evt_size, m_evt_prev);
985 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_evt_pos > 2);
986 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_evt_prev > 0);
987 // BEFORE
988 // ... flag start len (free)
989 // | |
990 // prev curr
991 // AFTER
992 // ... BMAP flag start len (free)
993 // | |
994 // prev curr
995 if(m_evt_pos < m_evt_size)
996 {
997 if(m_evt[m_evt_prev] & ievt::WSTR)
998 {
999 _c4dbgpf("{}/{}: WSTR", m_evt_pos, m_evt_size);
1000 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_evt_prev > 0);
1001 int32_t pos = _extend_left_to_include_tag_and_or_anchor(m_evt_prev);
1002 if(m_evt_pos + 1 < m_evt_size)
1003 {
1004 for(int32_t i = pos; i <= m_evt_prev; i = _next(i))
1005 {
1006 m_evt[i] |= ievt::KEY_;
1007 m_evt[i] &= ~ievt::VAL_;
1008 }
1009 int32_t num_move = m_evt_pos + 1 - pos;
1010 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, num_move > 0);
1011 memmove(m_evt + pos + 1, m_evt + pos, (size_t)num_move * sizeof(ievt::DataType));
1012 }
1013 m_evt[pos] = ievt::BMAP|ievt::FLOW|ievt::VAL_;
1014 // move PSTR to prev
1015 if(m_evt[pos + 1] & ievt::PSTR)
1016 {
1017 m_evt[pos ] |= ievt::PSTR;
1018 m_evt[pos + 1] &= ~ievt::PSTR;
1019 }
1020 }
1021 else
1022 {
1023 _c4dbgpf("{}/{}: container key", m_evt_pos, m_evt_size);
1024 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[m_evt_prev] & (ievt::EMAP|ievt::ESEQ)));
1025 int32_t pos;
1026 _c4dbgpf("{}/{}: find matching open for {}", m_evt_pos, m_evt_size, m_evt_prev);
1027 if((m_evt[m_evt_prev] & ievt::EMAP) == ievt::EMAP)
1028 {
1029 pos = _find_matching_open(ievt::BMAP, ievt::EMAP, m_evt_prev);
1030 }
1031 else
1032 {
1033 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[m_evt_prev] & ievt::ESEQ));
1034 pos = _find_matching_open(ievt::BSEQ, ievt::ESEQ, m_evt_prev);
1035 }
1036 _c4dbgpf("{}/{}: matching open for {}={}", m_evt_pos, m_evt_size, m_evt_prev, pos);
1037 _RYML_CHECK_BASIC_(m_stack.m_callbacks, pos >= 0); // internal error
1038 _RYML_CHECK_BASIC_(m_stack.m_callbacks, pos < m_evt_prev); // internal error
1039 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[pos] & ievt::ESEQ) == (m_evt[m_evt_prev] & ievt::BSEQ));
1040 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[pos] & ievt::EMAP) == (m_evt[m_evt_prev] & ievt::BMAP));
1041 // shift the array one position to the right, starting at pos
1042 int32_t posp1 = pos + 1;
1043 if(m_evt_pos + 1 < m_evt_size)
1044 {
1045 int32_t num_move = m_evt_pos + 1 - pos;
1046 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, num_move > 0);
1047 memmove(m_evt + posp1, m_evt + pos, (size_t)num_move * sizeof(ievt::DataType));
1048 }
1049 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, posp1 < m_evt_pos);
1050 // start the map
1051 m_evt[pos] = ievt::BMAP|ievt::FLOW|ievt::VAL_;
1052 // set next as key, not val
1053 m_evt[posp1] |= ievt::KEY_;
1054 m_evt[posp1] &= ~ievt::VAL_;
1055 // move PSTR to pos
1056 if(m_evt[posp1] & ievt::PSTR)
1057 {
1058 m_evt[pos] |= ievt::PSTR;
1059 m_evt[posp1] &= ~ievt::PSTR;
1060 }
1061 }
1062 }
1063 m_curr->evt_id = m_evt_pos - 2;
1064 ++m_evt_prev;
1065 ++m_evt_pos;
1067 _push();
1068 }
int32_t _next(int32_t pos) const noexcept
int32_t _find_matching_open(ievt::DataType open, ievt::DataType close, int32_t pos) const
int32_t _extend_left_to_include_tag_and_or_anchor(int32_t pos) const

◆ actually_val_is_first_key_of_new_map_block()

void c4::yml::extra::EventHandlerInts::actually_val_is_first_key_of_new_map_block ( )
inline

like its flow counterpart, but this function can only be called after the end of a flow-val at root or doc level.

See the documentation for Event Handlers, which has important notes about this event.

Definition at line 1076 of file event_handler_ints.hpp.

1077 {
1078 _c4dbgpf("{}/{}: prev={} actually_val_is_first_key_of_new_map_block", m_evt_pos, m_evt_size, m_evt_prev);
1079 if(m_evt_pos < m_evt_size)
1080 {
1081 // interpolate BMAP|VAL|BLCK after the last BDOC
1082 int32_t pos = _find_last_bdoc(m_evt_pos);
1083 if(pos >= 0)
1084 {
1085 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size);
1086 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_pos);
1087 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[pos] & ievt::BDOC) == ievt::BDOC);
1088 if(m_evt_pos < m_evt_size)
1089 {
1090 ++pos; // add 1 to write after BDOC
1091 int32_t num_move = m_evt_pos - pos;
1092 int32_t posp1 = pos + 1;
1093 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, ((m_evt[pos] & ievt::BSEQ) == ievt::BSEQ) || ((m_evt[pos] & ievt::BMAP) == ievt::BMAP));
1094 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, num_move > 0);
1095 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, 0 == (m_evt[posp1] & ievt::PSTR));
1096 memmove(m_evt + posp1, m_evt + pos, (size_t)num_move * sizeof(ievt::DataType));
1097 m_evt[pos] = ievt::VAL_|ievt::BMAP|ievt::BLCK;
1098 m_evt[posp1] &= ~ievt::VAL_;
1099 m_evt[posp1] |= ievt::KEY_;
1100 }
1101 }
1102 }
1103 ++m_curr->evt_id;
1104 ++m_evt_prev;
1105 ++m_evt_pos;
1106 _push();
1107 }
int32_t _find_last_bdoc(int32_t pos) const

◆ arena()

substr c4::yml::extra::EventHandlerInts::arena ( )
inline

Definition at line 1116 of file event_handler_ints.hpp.

1117 {
1118 return m_arena.first(m_arena_pos < m_arena.len ? m_arena_pos : m_arena.len);
1119 }

◆ arena_rem()

substr c4::yml::extra::EventHandlerInts::arena_rem ( )
inline

Definition at line 1120 of file event_handler_ints.hpp.

1121 {
1122 return C4_LIKELY(m_arena_pos <= m_arena.len) ? m_arena.sub(m_arena_pos) : m_arena.last(0);
1123 }

◆ alloc_arena()

substr c4::yml::extra::EventHandlerInts::alloc_arena ( size_t len)
inline

this may fail, in which case an empty string is returned

Definition at line 1125 of file event_handler_ints.hpp.

1126 {
1127 substr s = arena_rem();
1128 if(C4_LIKELY(len <= s.len))
1129 s.len = len;
1130 else
1131 s.str = nullptr;
1132 m_arena_pos += len;
1133 return s;
1134 }

◆ _push()

void c4::yml::extra::EventHandlerInts::_push ( )
inline

push a new parent, add a child to the new parent, and set the child as the current node

Definition at line 1145 of file event_handler_ints.hpp.

◆ _pop()

void c4::yml::extra::EventHandlerInts::_pop ( )
inline

end the current scope

Definition at line 1152 of file event_handler_ints.hpp.

◆ _enable__()

template<c4::yml::type_bits bits>
void c4::yml::extra::EventHandlerInts::_enable__ ( )
inlinenoexcept

Definition at line 1157 of file event_handler_ints.hpp.

1158 {
1159 m_curr->evt_type |= bits;
1160 }

◆ _disable__()

template<c4::yml::type_bits bits>
void c4::yml::extra::EventHandlerInts::_disable__ ( )
inlinenoexcept

Definition at line 1161 of file event_handler_ints.hpp.

1162 {
1163 m_curr->evt_type &= ~bits;
1164 }

◆ _has_any__()

template<c4::yml::type_bits bits>
bool c4::yml::extra::EventHandlerInts::_has_any__ ( ) const
inlinenoexcept

Definition at line 1165 of file event_handler_ints.hpp.

1166 {
1167 return (m_curr->evt_type & bits) != c4::yml::type_bits(0);
1168 }
uint32_t type_bits
the integral type necessary to cover all the bits for NodeType_e
Definition node_type.hpp:30

◆ _next()

int32_t c4::yml::extra::EventHandlerInts::_next ( int32_t pos) const
inlinenoexcept

Definition at line 1170 of file event_handler_ints.hpp.

1171 {
1172 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size);
1173 return pos + ((m_evt[pos] & ievt::WSTR) ? 3 : 1);
1174 }

◆ _prev()

int32_t c4::yml::extra::EventHandlerInts::_prev ( int32_t pos) const
inlinenoexcept

Definition at line 1176 of file event_handler_ints.hpp.

1177 {
1178 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size);
1179 return pos - ((m_evt[pos] & ievt::PSTR) ? 3 : 1);
1180 }

◆ _is_sub_()

bool c4::yml::extra::EventHandlerInts::_is_sub_ ( csubstr str) const
inlinenoexcept

Definition at line 1182 of file event_handler_ints.hpp.

1183 {
1184 return (!str.str || str.is_sub(m_src) || str.is_sub(m_arena));
1185 }

◆ _send_flag_only_()

void c4::yml::extra::EventHandlerInts::_send_flag_only_ ( ievt::DataType flags)
inline

Definition at line 1187 of file event_handler_ints.hpp.

1188 {
1189 _c4dbgpf("{}/{}: flag only", m_evt_pos, m_evt_size);
1190 if(m_evt_pos < m_evt_size)
1191 m_evt[m_evt_pos] |= flags;
1192 m_curr->evt_id = m_evt_pos;
1193 m_evt_prev = m_evt_pos;
1194 ++m_evt_pos;
1195 if(m_evt_pos < m_evt_size)
1196 m_evt[m_evt_pos] = {};
1197 }

◆ _send_str_()

void c4::yml::extra::EventHandlerInts::_send_str_ ( csubstr scalar,
ievt::DataType flags )
inline

Definition at line 1199 of file event_handler_ints.hpp.

1200 {
1201 _c4dbgpf("{}/{}: send str", m_evt_pos, m_evt_size);
1202 if(m_evt_pos + 3 < m_evt_size)
1203 {
1204 m_evt[m_evt_pos] |= flags;
1205 _add_scalar_(m_evt_pos, scalar);
1206 }
1207 m_curr->evt_id = m_evt_pos;
1208 m_evt_prev = m_evt_pos;
1209 m_evt_pos += 3;
1210 }

◆ _mark_parent_with_children_()

void c4::yml::extra::EventHandlerInts::_mark_parent_with_children_ ( )
inline

Definition at line 1212 of file event_handler_ints.hpp.

1213 {
1214 if(m_parent)
1215 m_parent->has_children = true;
1216 }

◆ _get_latest_empty_scalar()

csubstr c4::yml::extra::EventHandlerInts::_get_latest_empty_scalar ( ) const
inline

Definition at line 1218 of file event_handler_ints.hpp.

1219 {
1220 // ideally we should search back in the latest event that has
1221 // a scalar, then select a zero-length scalar immediately
1222 // after that scalar. But this also works for now:
1223 return m_src.first(0);
1224 }

◆ _find_last_bdoc()

int32_t c4::yml::extra::EventHandlerInts::_find_last_bdoc ( int32_t pos) const
inline

Definition at line 1226 of file event_handler_ints.hpp.

1227 {
1228 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size); // it's safe to read from the array
1229 while(pos >= 0)
1230 {
1231 ievt::DataType e = m_evt[pos];
1232 if((e & ievt::BDOC) == ievt::BDOC)
1233 return pos;
1234 pos -= (e & ievt::PSTR) ? 3 : 1;
1235 }
1236 return -1; // LCOV_EXCL_LINE
1237 }

◆ _find_matching_open()

int32_t c4::yml::extra::EventHandlerInts::_find_matching_open ( ievt::DataType open,
ievt::DataType close,
int32_t pos ) const
inline

Definition at line 1239 of file event_handler_ints.hpp.

1240 {
1241 _c4dbgpf("find_matching: start at {}", pos);
1242 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size);
1243 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[pos] & close) == close);
1244 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, (m_evt[pos] & open) == (close & ~ievt::END_));
1245 pos = _prev(pos); // don't count the starting close token
1246 uint32_t count = 0;
1247 while(pos >= 0)
1248 {
1249 ievt::DataType e = m_evt[pos];
1250 _c4dbgpf("find_matching: pos={} count={} e={}", pos, count, m_evt[pos]);
1251 if((e & close) == close)
1252 {
1253 _c4dbgpf(".............: pos={} close! count={} e={}", pos, count, m_evt[pos]);
1254 ++count;
1255 }
1256 else if((e & open) == open)
1257 {
1258 _c4dbgpf(".............: pos={} open! count={} e={}", pos, count, m_evt[pos]);
1259 if(!count)
1260 return pos;
1261 else
1262 --count;
1263 }
1264 pos = _prev(pos);
1265 }
1266 _c4dbgpf("find_matching: not found!", 0); // LCOV_EXCL_LINE
1267 return -1; // LCOV_EXCL_LINE
1268 }
int32_t _prev(int32_t pos) const noexcept

◆ _extend_left_to_include_tag_and_or_anchor()

int32_t c4::yml::extra::EventHandlerInts::_extend_left_to_include_tag_and_or_anchor ( int32_t pos) const
inline

Definition at line 1270 of file event_handler_ints.hpp.

1271 {
1272 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, pos < m_evt_size);
1273 int32_t prev = _prev(pos);
1274 while((prev > 0) && (m_evt[prev] & (ievt::TAG_|ievt::ANCH)))
1275 {
1276 _c4dbgpf("{}/{}: {} is anchor/tag. extend to {}", m_evt_pos, m_evt_size, prev, prev);
1277 pos = prev;
1278 prev = _prev(prev);
1279 }
1280 return pos;
1281 }

◆ _stack_start_parse()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_start_parse ( const char * filename,
substr ymlsrc )
inlineprotectedinherited

Definition at line 58 of file event_handler_stack.hpp.

59 {
60 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_curr != nullptr);
61 m_curr->start_parse(filename, m_curr->node_id);
62 m_src = ymlsrc;
63 }
Use this class a base of implementations of event handler to simplify the stack logic.

◆ _stack_finish_parse()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_finish_parse ( )
inlineprotectedinherited

Definition at line 65 of file event_handler_stack.hpp.

66 {
67 }

◆ _stack_reset_root()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_reset_root ( )
inlineprotectedinherited

Definition at line 71 of file event_handler_stack.hpp.

72 {
73 m_stack.clear();
74 m_stack.push({});
75 m_parent = nullptr;
76 m_curr = &m_stack.top();
77 }

◆ _stack_reset_non_root()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_reset_non_root ( )
inlineprotectedinherited

Definition at line 79 of file event_handler_stack.hpp.

80 {
81 m_stack.clear();
82 m_stack.push({}); // parent
83 m_stack.push({}); // node
84 m_parent = &m_stack.top(1);
85 m_curr = &m_stack.top();
86 }

◆ _stack_push()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_push ( )
inlineprotectedinherited

Definition at line 88 of file event_handler_stack.hpp.

89 {
90 m_stack.push_top();
91 m_parent = &m_stack.top(1); // don't use m_curr. watch out for relocations inside the prev push
92 m_curr = &m_stack.top();
93 m_curr->reset_after_push();
94 }

◆ _stack_pop()

void c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_pop ( )
inlineprotectedinherited

Definition at line 96 of file event_handler_stack.hpp.

97 {
99 _RYML_ASSERT_BASIC_(m_stack.m_callbacks, m_stack.size() > 1);
100 m_parent->reset_before_pop(*m_curr);
101 m_stack.pop();
102 m_parent = m_stack.size() > 1 ? &m_stack.top(1) : nullptr;
103 m_curr = &m_stack.top();
104 #ifdef RYML_DBG
105 if(m_parent)
106 _c4dbgpf("popped! top is now node={} (parent={})", m_curr->node_id, m_parent->node_id);
107 else
108 _c4dbgpf("popped! top is now node={} @ ROOT", m_curr->node_id);
109 #endif
110 }

◆ _stack_should_push_on_begin_doc()

bool c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_should_push_on_begin_doc ( ) const
inlineprotectedinherited

Definition at line 121 of file event_handler_stack.hpp.

122 {
123 const bool is_root = (m_stack.size() == 1u);
124 return is_root && (m_curr->has_children || _has_any_(DOC|VAL|MAP|SEQ));
125 }

◆ _stack_should_pop_on_end_doc()

bool c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::_stack_should_pop_on_end_doc ( ) const
inlineprotectedinherited

Definition at line 127 of file event_handler_stack.hpp.

128 {
129 const bool is_root = (m_stack.size() == 1u);
130 return !is_root && _has_any_(DOC);
131 }

Member Data Documentation

◆ m_stack

detail::stack<state> c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::m_stack
inherited

Definition at line 46 of file event_handler_stack.hpp.

◆ m_curr

state* c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::m_curr
inherited

current stack level: top of the stack. cached here for easier access.

Definition at line 47 of file event_handler_stack.hpp.

◆ m_parent

state* c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::m_parent
inherited

parent of the current stack level.

Definition at line 48 of file event_handler_stack.hpp.

◆ m_src

substr c4::yml::EventHandlerStack< EventHandlerInts, EventHandlerIntsState >::m_src
inherited

Definition at line 49 of file event_handler_stack.hpp.


The documentation for this struct was generated from the following file:
  • /home/docs/checkouts/readthedocs.org/user_builds/rapidyaml/checkouts/v0.14.0/src_extra/c4/yml/extra/event_handler_ints.hpp