rapidyaml 0.15.2
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::evt_bits
using state = EventHandlerIntsState

Public Member Functions

construction and resetting
 EventHandlerInts (c4::yml::Callbacks const &cb) noexcept
 EventHandlerInts () noexcept
void reset (substr str, substr arena, ievt::evt_bits *dst, evt_size dst_size)
evt_size 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, type_bits=FLOW_ML1)
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, type_bits=FLOW_ML1)
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
evt_size _next (evt_size pos) const noexcept
evt_size _prev (evt_size pos) const noexcept
bool _is_sub_ (csubstr str) const noexcept
void _send_flag_only_ (ievt::evt_bits flags)
void _send_str_ (csubstr scalar, ievt::evt_bits flags)
void _mark_parent_with_children_ ()
csubstr _get_latest_empty_scalar () const
evt_size _find_last_bdoc (evt_size pos) const
evt_size _find_matching_open (ievt::evt_bits open, ievt::evt_bits close, evt_size pos) const
evt_size _extend_left_to_include_tag_and_or_anchor (evt_size 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::EventBits 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::EventBits), 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 evt_bits 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 evt_bits
data type for integer events bits.
@ PSTR
Special flag to enable look-back in the event array. It signifies that the previous event has a strin...
@ 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
@ 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 evt_bits 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:2355
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
@ WSTR
WithSTRing: mask of all events that encode a string following the event. For such events,...
@ AREN
Special flag to mark events whose string was placed in the arena. This happens when the filtered stri...
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:502

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,...
evt_size 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 ...
evt_size required_size_events() const
get the size needed for the event buffer from the previous parse
bool fits_buffers() const
Predicate to test if the event and arena buffers successfully accomodated all the parse events.
void reset(substr str, substr arena, ievt::evt_bits *dst, evt_size 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:2376
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 458 of file event_handler_ints.hpp.

Member Typedef Documentation

◆ value_type

◆ state

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

Definition at line 465 of file event_handler_ints.hpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
requires_strings_on_buffers 

Definition at line 466 of file event_handler_ints.hpp.

Constructor & Destructor Documentation

◆ EventHandlerInts() [1/2]

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

◆ EventHandlerInts() [2/2]

c4::yml::extra::EventHandlerInts::EventHandlerInts ( )
inlinenoexcept

Definition at line 499 of file event_handler_ints.hpp.

501 {
502 }
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::evt_bits * dst,
evt_size dst_size )
inline

Definition at line 504 of file event_handler_ints.hpp.

505 {
508 m_curr->evt_type = {};
509 m_curr->evt_id = 0;
510 m_arena = arena;
511 m_arena_pos = 0;
512 m_src = str;
513 m_evt = dst;
514 m_evt_size = dst_size;
515 m_evt_pos = 0;
516 m_evt_prev = 0;
517 m_curr_doc = 0;
518 m_tag_directives.clear();
519 m_tag_cache.clear();
520 }
@ RTOP
reading at top level
@ RUNK
reading unknown state (when starting): must determine whether scalar, map or seq

Referenced by EventHandlerInts().

◆ required_size_events()

evt_size 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 524 of file event_handler_ints.hpp.

525 {
526 return m_evt_pos;
527 }

Referenced by IntsResult::resize_buffers().

◆ 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 531 of file event_handler_ints.hpp.

532 {
533 return m_arena_pos;
534 }

Referenced by IntsResult::resize_buffers().

◆ 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 540 of file event_handler_ints.hpp.

541 {
542 return m_evt_pos <= m_evt_size && m_arena_pos <= m_arena.len;
543 }

◆ reserve_arena()

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

Definition at line 545 of file event_handler_ints.hpp.

546 {
547 // does not apply here
548 }

◆ tag_directives()

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

Definition at line 550 of file event_handler_ints.hpp.

550{ return m_tag_directives; }

◆ tag_cache()

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

Definition at line 551 of file event_handler_ints.hpp.

551{ return m_tag_cache; }

◆ start_parse()

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

Definition at line 560 of file event_handler_ints.hpp.

561 {
562 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, src.str == m_src.str);
563 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, src.len == m_src.len);
564 this->_stack_start_parse(filename, src);
565 }

◆ finish_parse()

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

◆ cancel_parse()

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

Definition at line 572 of file event_handler_ints.hpp.

573 {
574 while(m_stack.size() > 1)
575 _pop();
576 }

◆ begin_stream()

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

Definition at line 585 of file event_handler_ints.hpp.

586 {
588 }
void _send_flag_only_(ievt::evt_bits flags)

◆ end_stream()

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

Definition at line 590 of file event_handler_ints.hpp.

591 {
593 }

◆ begin_doc()

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

implicit doc start (without —)

Definition at line 603 of file event_handler_ints.hpp.

604 {
605 _c4dbgpf("{}/{}: begin_doc", m_evt_pos, m_evt_size);
608 {
609 _c4dbgp("push!");
610 _push();
611 ryml_enable_(DOC);
612 }
613 }
@ DOC
a document
Definition node_type.hpp:37
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 615 of file event_handler_ints.hpp.

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

◆ begin_doc_expl()

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

explicit doc start, with —

Definition at line 628 of file event_handler_ints.hpp.

629 {
630 _c4dbgpf("{}/{}: begin_doc_expl", m_evt_pos, m_evt_size);
632 _c4dbgp("push!");
633 _push();
634 ryml_enable_(DOC);
635 }
@ 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 637 of file event_handler_ints.hpp.

638 {
639 _c4dbgpf("{}/{}: end_doc_expl", m_evt_pos, m_evt_size);
642 {
643 _c4dbgp("pop!");
644 _pop();
645 }
646 ++m_curr_doc;
647 }

◆ begin_map_key_flow()

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

Definition at line 656 of file event_handler_ints.hpp.

657 {
658 _c4dbgpf("{}/{}: bmap key flow", m_evt_pos, m_evt_size);
662 _push();
663 }
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
Definition node_type.hpp:35
@ KEY
the scalar to the left of : in a map's member
Definition node_type.hpp:33
@ FLOW_SL
mark container with single-line flow style
Definition node_type.hpp:56

◆ begin_map_key_block()

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

Definition at line 664 of file event_handler_ints.hpp.

665 {
666 _c4dbgpf("{}/{}: bmap key block", m_evt_pos, m_evt_size);
670 _push();
671 }
@ BLOCK
mark container with block style

◆ begin_map_val_flow()

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

Definition at line 673 of file event_handler_ints.hpp.

674 {
675 _c4dbgpf("{}/{}: bmap flow", m_evt_pos, m_evt_size);
678 ryml_enable_(c4::yml::MAP|c4::yml::FLOW_SL);
679 _push();
680 }

◆ begin_map_val_block()

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

Definition at line 681 of file event_handler_ints.hpp.

682 {
683 _c4dbgpf("{}/{}: bmap block", m_evt_pos, m_evt_size);
686 ryml_enable_(c4::yml::MAP|c4::yml::BLOCK);
687 _push();
688 }

◆ end_map_block()

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

Definition at line 690 of file event_handler_ints.hpp.

691 {
692 _pop();
694 }

◆ end_map_flow()

void c4::yml::extra::EventHandlerInts::end_map_flow ( bool ,
type_bits = FLOW_ML1 )
inline

Definition at line 696 of file event_handler_ints.hpp.

697 {
698 _pop();
700 }

◆ begin_seq_key_flow()

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

Definition at line 709 of file event_handler_ints.hpp.

710 {
711 _c4dbgpf("{}/{}: bseq key flow", m_evt_pos, m_evt_size);
715 _push();
716 }
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
Definition node_type.hpp:36

◆ begin_seq_key_block()

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

Definition at line 717 of file event_handler_ints.hpp.

718 {
719 _c4dbgpf("{}/{}: bseq key block", m_evt_pos, m_evt_size);
723 _push();
724 }

◆ begin_seq_val_flow()

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

Definition at line 726 of file event_handler_ints.hpp.

727 {
728 _c4dbgpf("{}/{}: bseq flow", m_evt_pos, m_evt_size);
731 ryml_enable_(c4::yml::SEQ|c4::yml::FLOW_SL);
732 _push();
733 }

◆ begin_seq_val_block()

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

Definition at line 734 of file event_handler_ints.hpp.

735 {
736 _c4dbgpf("{}/{}: bseq block", m_evt_pos, m_evt_size);
739 ryml_enable_(c4::yml::SEQ|c4::yml::BLOCK);
740 _push();
741 }

◆ end_seq_block()

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

Definition at line 743 of file event_handler_ints.hpp.

744 {
745 _pop();
747 }

◆ end_seq_flow()

void c4::yml::extra::EventHandlerInts::end_seq_flow ( bool ,
type_bits = FLOW_ML1 )
inline

Definition at line 749 of file event_handler_ints.hpp.

750 {
751 _pop();
753 }

◆ add_sibling()

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

Definition at line 762 of file event_handler_ints.hpp.

763 {
764 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, m_parent);
765 m_curr->evt_type = {};
766 }

◆ set_key_scalar_plain_empty()

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

Definition at line 776 of file event_handler_ints.hpp.

777 {
778 _c4dbgpf("{}/{}: set_key_scalar_plain_empty", m_evt_pos, m_evt_size);
781 }
@ KEY_PLAIN
mark key scalar as plain scalar (unquoted, even when multiline)
@ KEYNIL
the key is null (eg { : b} results in a null key)
Definition node_type.hpp:45
void _send_str_(csubstr scalar, ievt::evt_bits flags)

◆ set_val_scalar_plain_empty()

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

Definition at line 782 of file event_handler_ints.hpp.

783 {
784 _c4dbgpf("{}/{}: set_val_scalar_plain_empty", m_evt_pos, m_evt_size);
787 }
@ VALNIL
the val is null (eg {a : } results in a null val)
Definition node_type.hpp:46
@ 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:34
@ VAL_PLAIN
mark val scalar as plain scalar (unquoted, even when multiline)

◆ set_key_scalar_plain()

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

Definition at line 790 of file event_handler_ints.hpp.

791 {
792 _c4dbgpf("{}/{}: set_key_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
794 ryml_enable_(c4::yml::KEY|c4::yml::KEY_PLAIN);
795 }

◆ set_val_scalar_plain()

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

Definition at line 796 of file event_handler_ints.hpp.

797 {
798 _c4dbgpf("{}/{}: set_val_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
800 ryml_enable_(c4::yml::VAL|c4::yml::VAL_PLAIN);
801 }

◆ set_key_scalar_dquoted()

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

Definition at line 804 of file event_handler_ints.hpp.

805 {
806 _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{});
808 ryml_enable_(c4::yml::KEY|c4::yml::KEY_DQUO);
809 }
@ KEY_DQUO
mark key scalar as double quoted "
@ DQUO
scalar: double-quoted ("")

◆ set_val_scalar_dquoted()

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

Definition at line 810 of file event_handler_ints.hpp.

811 {
812 _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{});
814 ryml_enable_(c4::yml::VAL|c4::yml::VAL_DQUO);
815 }
@ VAL_DQUO
mark val scalar as double quoted "

◆ set_key_scalar_squoted()

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

Definition at line 818 of file event_handler_ints.hpp.

819 {
820 _c4dbgpf("{}/{}: set_key_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
822 ryml_enable_(c4::yml::KEY|c4::yml::KEY_SQUO);
823 }
@ KEY_SQUO
mark key scalar as single quoted '
@ SQUO
scalar: single-quoted (')

◆ set_val_scalar_squoted()

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

Definition at line 824 of file event_handler_ints.hpp.

825 {
826 _c4dbgpf("{}/{}: set_val_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.str-m_src.str, scalar.len, scalar);
828 ryml_enable_(c4::yml::VAL|c4::yml::VAL_SQUO);
829 }
@ VAL_SQUO
mark val scalar as single quoted '

◆ set_key_scalar_literal()

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

Definition at line 832 of file event_handler_ints.hpp.

833 {
834 _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{});
837 }
@ KEY_LITERAL
mark key scalar as multiline, block literal |
@ LITL
scalar: block literal (|)

◆ set_val_scalar_literal()

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

Definition at line 838 of file event_handler_ints.hpp.

839 {
840 _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{});
843 }
@ VAL_LITERAL
mark val scalar as multiline, block literal |

◆ set_key_scalar_folded()

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

Definition at line 846 of file event_handler_ints.hpp.

847 {
848 _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{});
850 ryml_enable_(c4::yml::KEY|c4::yml::KEY_FOLDED);
851 }
@ KEY_FOLDED
mark key scalar as multiline, block folded >
@ FOLD
scalar: block folded (>)

◆ set_val_scalar_folded()

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

Definition at line 852 of file event_handler_ints.hpp.

853 {
854 _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{});
856 ryml_enable_(c4::yml::VAL|c4::yml::VAL_FOLDED);
857 }
@ VAL_FOLDED
mark val scalar as multiline, block folded >

◆ mark_key_scalar_unfiltered()

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

Definition at line 860 of file event_handler_ints.hpp.

861 {
862 _c4dbgpf("{}/{}: mark_key_scalar_unfiltered", m_evt_pos, m_evt_size);
863 if(m_evt_pos < m_evt_size)
864 m_evt[m_evt_pos] |= ievt::UNFILT;
865 }
@ 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 866 of file event_handler_ints.hpp.

867 {
868 _c4dbgpf("{}/{}: mark_val_scalar_unfiltered", m_evt_pos, m_evt_size);
869 if(m_evt_pos < m_evt_size)
870 m_evt[m_evt_pos] |= ievt::UNFILT;
871 }

◆ set_key_anchor()

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

Definition at line 902 of file event_handler_ints.hpp.

903 {
904 _c4dbgpf("{}/{}: set_key_anchor: {}", m_evt_pos, m_evt_size, anchor);
905 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, !ryml_has_any_(KEYREF));
906 ryml_enable_(c4::yml::KEYANCH);
907 if(m_evt_pos + 3 < m_evt_size)
908 {
909 m_evt[m_evt_pos] |= ievt::KEY_|ievt::ANCH;
910 _add_scalar_(m_evt_pos, anchor);
911 }
912 m_evt_prev = m_evt_pos;
913 m_evt_pos += 3;
914 }
#define ryml_has_any_(bits)
@ KEYREF
a *reference: the key references an &anchor
Definition node_type.hpp:39
@ KEYANCH
the key has an &anchor
Definition node_type.hpp:41

◆ set_val_anchor()

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

Definition at line 915 of file event_handler_ints.hpp.

916 {
917 _c4dbgpf("{}/{}: set_val_anchor: {}", m_evt_pos, m_evt_size, anchor);
918 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, !ryml_has_any_(VALREF));
919 ryml_enable_(c4::yml::VALANCH);
920 if(m_evt_pos + 3 < m_evt_size)
921 {
922 m_evt[m_evt_pos] |= ievt::VAL_|ievt::ANCH;
923 _add_scalar_(m_evt_pos, anchor);
924 }
925 m_evt_prev = m_evt_pos;
926 m_evt_pos += 3;
927 }
@ VALANCH
the val has an &anchor
Definition node_type.hpp:42
@ VALREF
a *reference: the val references an &anchor
Definition node_type.hpp:40

◆ set_key_ref()

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

Definition at line 929 of file event_handler_ints.hpp.

930 {
931 _c4dbgpf("{}/{}: set_key_ref: {}", m_evt_pos, m_evt_size, ref);
932 RYML_ASSERT_PARSE_CB_(m_stack.m_callbacks, ref.begins_with('*'), m_curr->pos);
933 RYML_ASSERT_PARSE_CB_(m_stack.m_callbacks, !ryml_has_any_(KEYANCH), m_curr->pos);
934 ryml_enable_(c4::yml::KEY|c4::yml::KEYREF);
935 _send_str_(ref.sub(1), ievt::KEY_|ievt::ALIA); // skip the leading *
936 }

◆ set_val_ref()

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

Definition at line 937 of file event_handler_ints.hpp.

938 {
939 _c4dbgpf("{}/{}: set_val_ref: {}", m_evt_pos, m_evt_size, ref);
940 RYML_ASSERT_PARSE_CB_(m_stack.m_callbacks, ref.begins_with('*'), m_curr->pos);
941 RYML_ASSERT_PARSE_CB_(m_stack.m_callbacks, !ryml_has_any_(VALANCH), m_curr->pos);
942 ryml_enable_(c4::yml::VAL|c4::yml::VALREF);
943 _send_str_(ref.sub(1), ievt::VAL_|ievt::ALIA); // skip the leading *
944 }

◆ set_key_tag()

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

Definition at line 953 of file event_handler_ints.hpp.

954 {
955 _c4dbgpf("{}/{}: set key tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.len, tag.str ? tag : csubstr("(arena full)"));
956 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, _is_sub_(tag));
957 ryml_enable_(c4::yml::KEYTAG);
959 }
@ KEYTAG
the key has a tag
Definition node_type.hpp:43
bool _is_sub_(csubstr str) const noexcept

◆ set_val_tag()

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

Definition at line 960 of file event_handler_ints.hpp.

961 {
962 _c4dbgpf("{}/{}: set val tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.len, tag.str ? tag : csubstr("(arena full)"));
963 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, _is_sub_(tag));
964 ryml_enable_(c4::yml::VALTAG);
966 }
@ VALTAG
the val has a tag
Definition node_type.hpp:44

◆ add_directive_yaml()

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

Definition at line 975 of file event_handler_ints.hpp.

976 {
977 _c4dbgpf("{}/{}: %YAML directive! version={}", m_evt_pos, m_evt_size, yaml_version);
978 _send_str_(yaml_version, ievt::YAML);
979 }
@ YAML
yaml directive: \YAML <version>

◆ add_directive_tag()

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

Definition at line 981 of file event_handler_ints.hpp.

982 {
983 _c4dbgpf("{}/{}: %TAG directive! handle={} prefix={} doc_id={}", m_evt_pos, m_evt_size, handle, prefix, m_curr_doc);
984 if C4_UNLIKELY(!m_tag_directives.add(handle, prefix, m_curr_doc))
985 RYML_ERR_PARSE_CB_(m_stack.m_callbacks, m_curr->pos, "too many %TAG directives");
986 _send_str_(handle, ievt::TAGH);
987 _send_str_(prefix, ievt::TAGP);
988 }
@ 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 1002 of file event_handler_ints.hpp.

1003 {
1004 _c4dbgpf("{}/{}: prev={} actually_val_is_first_key_of_new_map_flow", m_evt_pos, m_evt_size, m_evt_prev);
1005 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, m_evt_pos > 2);
1006 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, m_evt_prev > 0);
1007 // BEFORE
1008 // ... flag start len (free)
1009 // | |
1010 // prev curr
1011 // AFTER
1012 // ... BMAP flag start len (free)
1013 // | |
1014 // prev curr
1015 if(m_evt_pos < m_evt_size)
1016 {
1017 if(m_evt[m_evt_prev] & ievt::WSTR)
1018 {
1019 _c4dbgpf("{}/{}: WSTR", m_evt_pos, m_evt_size);
1020 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, m_evt_prev > 0);
1022 if(m_evt_pos + 1 < m_evt_size)
1023 {
1024 for(evt_size i = pos; i <= m_evt_prev; i = _next(i))
1025 {
1026 m_evt[i] |= ievt::KEY_;
1027 m_evt[i] &= ~ievt::VAL_;
1028 }
1029 evt_size num_move = m_evt_pos + 1 - pos;
1030 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, num_move > 0);
1031 memmove(m_evt + pos + 1, m_evt + pos, (size_t)num_move * sizeof(ievt::evt_bits));
1032 }
1033 m_evt[pos] = ievt::BMAP|ievt::FLOW|ievt::VAL_;
1034 // move PSTR to prev
1035 if(m_evt[pos + 1] & ievt::PSTR)
1036 {
1037 m_evt[pos ] |= ievt::PSTR;
1038 m_evt[pos + 1] &= ~ievt::PSTR;
1039 }
1040 }
1041 else
1042 {
1043 _c4dbgpf("{}/{}: container key", m_evt_pos, m_evt_size);
1044 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[m_evt_prev] & (ievt::EMAP|ievt::ESEQ)));
1045 evt_size pos;
1046 _c4dbgpf("{}/{}: find matching open for {}", m_evt_pos, m_evt_size, m_evt_prev);
1047 if((m_evt[m_evt_prev] & ievt::EMAP) == ievt::EMAP)
1048 {
1049 pos = _find_matching_open(ievt::BMAP, ievt::EMAP, m_evt_prev);
1050 }
1051 else
1052 {
1053 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[m_evt_prev] & ievt::ESEQ));
1054 pos = _find_matching_open(ievt::BSEQ, ievt::ESEQ, m_evt_prev);
1055 }
1056 _c4dbgpf("{}/{}: matching open for {}={}", m_evt_pos, m_evt_size, m_evt_prev, pos);
1057 RYML_CHECK_BASIC_CB_(m_stack.m_callbacks, pos >= 0); // internal error
1058 RYML_CHECK_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_prev); // internal error
1059 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[pos] & ievt::ESEQ) == (m_evt[m_evt_prev] & ievt::BSEQ));
1060 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[pos] & ievt::EMAP) == (m_evt[m_evt_prev] & ievt::BMAP));
1061 // shift the array one position to the right, starting at pos
1062 evt_size posp1 = pos + 1;
1063 if(m_evt_pos + 1 < m_evt_size)
1064 {
1065 evt_size num_move = m_evt_pos + 1 - pos;
1066 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, num_move > 0);
1067 memmove(m_evt + posp1, m_evt + pos, (size_t)num_move * sizeof(ievt::evt_bits));
1068 }
1069 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, posp1 < m_evt_pos);
1070 // start the map
1071 m_evt[pos] = ievt::BMAP|ievt::FLOW|ievt::VAL_;
1072 // set next as key, not val
1073 m_evt[posp1] |= ievt::KEY_;
1074 m_evt[posp1] &= ~ievt::VAL_;
1075 // move PSTR to pos
1076 if(m_evt[posp1] & ievt::PSTR)
1077 {
1078 m_evt[pos] |= ievt::PSTR;
1079 m_evt[posp1] &= ~ievt::PSTR;
1080 }
1081 }
1082 }
1083 m_curr->evt_id = m_evt_pos - 2;
1084 ++m_evt_prev;
1085 ++m_evt_pos;
1086 ryml_enable_(c4::yml::MAP|c4::yml::FLOW_SL);
1087 _push();
1088 }
int32_t evt_size
data type for integer events size.
evt_size _extend_left_to_include_tag_and_or_anchor(evt_size pos) const
evt_size _find_matching_open(ievt::evt_bits open, ievt::evt_bits close, evt_size pos) const
evt_size _next(evt_size pos) const noexcept

◆ 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 1096 of file event_handler_ints.hpp.

1097 {
1098 _c4dbgpf("{}/{}: prev={} actually_val_is_first_key_of_new_map_block", m_evt_pos, m_evt_size, m_evt_prev);
1099 if(m_evt_pos < m_evt_size)
1100 {
1101 // interpolate BMAP|VAL|BLCK after the last BDOC
1102 evt_size pos = _find_last_bdoc(m_evt_pos);
1103 if(pos >= 0)
1104 {
1105 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size);
1106 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_pos);
1107 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[pos] & ievt::BDOC) == ievt::BDOC);
1108 if(m_evt_pos < m_evt_size)
1109 {
1110 ++pos; // add 1 to write after BDOC
1111 evt_size num_move = m_evt_pos - pos;
1112 evt_size posp1 = pos + 1;
1113 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, ((m_evt[pos] & ievt::BSEQ) == ievt::BSEQ) || ((m_evt[pos] & ievt::BMAP) == ievt::BMAP));
1114 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, num_move > 0);
1115 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, 0 == (m_evt[posp1] & ievt::PSTR));
1116 memmove(m_evt + posp1, m_evt + pos, (size_t)num_move * sizeof(ievt::evt_bits));
1117 m_evt[pos] = ievt::VAL_|ievt::BMAP|ievt::BLCK;
1118 m_evt[posp1] &= ~ievt::VAL_;
1119 m_evt[posp1] |= ievt::KEY_;
1120 }
1121 }
1122 }
1123 ++m_curr->evt_id;
1124 ++m_evt_prev;
1125 ++m_evt_pos;
1126 _push();
1127 }
evt_size _find_last_bdoc(evt_size pos) const

◆ arena()

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

Definition at line 1136 of file event_handler_ints.hpp.

1137 {
1138 return m_arena.first(m_arena_pos < m_arena.len ? m_arena_pos : m_arena.len);
1139 }

Referenced by reset().

◆ arena_rem()

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

Definition at line 1140 of file event_handler_ints.hpp.

1141 {
1142 return C4_EXPECT(m_arena_pos <= m_arena.len, 1) ? m_arena.sub(m_arena_pos) : m_arena.last(0);
1143 }

Referenced by alloc_arena().

◆ 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 1145 of file event_handler_ints.hpp.

1146 {
1147 substr s = arena_rem();
1148 if C4_LIKELY(len <= s.len)
1149 s.len = len;
1150 else
1151 s.str = nullptr;
1152 m_arena_pos += len;
1153 return s;
1154 }

◆ _push()

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

◆ _pop()

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

◆ enable_()

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

Definition at line 1177 of file event_handler_ints.hpp.

1178 {
1179 m_curr->evt_type |= bits;
1180 }

◆ disable_()

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

Definition at line 1181 of file event_handler_ints.hpp.

1182 {
1183 m_curr->evt_type &= ~bits;
1184 }

◆ has_any_()

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

Definition at line 1185 of file event_handler_ints.hpp.

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

◆ _next()

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

Definition at line 1190 of file event_handler_ints.hpp.

1191 {
1192 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size);
1193 return pos + ((m_evt[pos] & ievt::WSTR) ? 3 : 1);
1194 }

Referenced by actually_val_is_first_key_of_new_map_flow().

◆ _prev()

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

Definition at line 1196 of file event_handler_ints.hpp.

1197 {
1198 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size);
1199 return pos - ((m_evt[pos] & ievt::PSTR) ? 3 : 1);
1200 }

Referenced by _extend_left_to_include_tag_and_or_anchor(), and _find_matching_open().

◆ _is_sub_()

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

Definition at line 1202 of file event_handler_ints.hpp.

1203 {
1204 return (!str.str || str.is_sub(m_src) || str.is_sub(m_arena));
1205 }

Referenced by set_key_tag(), and set_val_tag().

◆ _send_flag_only_()

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

Definition at line 1207 of file event_handler_ints.hpp.

1208 {
1209 _c4dbgpf("{}/{}: flag only", m_evt_pos, m_evt_size);
1210 if(m_evt_pos < m_evt_size)
1211 m_evt[m_evt_pos] |= flags;
1212 m_curr->evt_id = m_evt_pos;
1213 m_evt_prev = m_evt_pos;
1214 ++m_evt_pos;
1215 if(m_evt_pos < m_evt_size)
1216 m_evt[m_evt_pos] = {};
1217 }

Referenced by begin_doc(), begin_doc_expl(), begin_map_key_block(), begin_map_key_flow(), begin_map_val_block(), begin_map_val_flow(), begin_seq_key_block(), begin_seq_key_flow(), begin_seq_val_block(), begin_seq_val_flow(), begin_stream(), end_doc(), end_doc_expl(), end_map_block(), end_map_flow(), end_seq_block(), end_seq_flow(), and end_stream().

◆ _send_str_()

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

Definition at line 1219 of file event_handler_ints.hpp.

1220 {
1221 _c4dbgpf("{}/{}: send str", m_evt_pos, m_evt_size);
1222 if(m_evt_pos + 3 < m_evt_size)
1223 {
1224 m_evt[m_evt_pos] |= flags;
1225 _add_scalar_(m_evt_pos, scalar);
1226 }
1227 m_curr->evt_id = m_evt_pos;
1228 m_evt_prev = m_evt_pos;
1229 m_evt_pos += 3;
1230 }

Referenced by add_directive_tag(), add_directive_yaml(), set_key_ref(), set_key_scalar_dquoted(), set_key_scalar_folded(), set_key_scalar_literal(), set_key_scalar_plain(), set_key_scalar_plain_empty(), set_key_scalar_squoted(), set_key_tag(), set_val_ref(), set_val_scalar_dquoted(), set_val_scalar_folded(), set_val_scalar_literal(), set_val_scalar_plain(), set_val_scalar_plain_empty(), set_val_scalar_squoted(), and set_val_tag().

◆ _mark_parent_with_children_()

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

◆ _get_latest_empty_scalar()

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

Definition at line 1238 of file event_handler_ints.hpp.

1239 {
1240 // ideally we should search back in the latest event that has
1241 // a scalar, then select a zero-length scalar immediately
1242 // after that scalar. But this also works for now:
1243 return m_src.first(0);
1244 }

Referenced by set_key_scalar_plain_empty(), and set_val_scalar_plain_empty().

◆ _find_last_bdoc()

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

Definition at line 1246 of file event_handler_ints.hpp.

1247 {
1248 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size); // it's safe to read from the array
1249 while(pos >= 0)
1250 {
1251 ievt::evt_bits e = m_evt[pos];
1252 if((e & ievt::BDOC) == ievt::BDOC)
1253 return pos;
1254 pos -= (e & ievt::PSTR) ? 3 : 1;
1255 }
1256 return -1; // LCOV_EXCL_LINE
1257 }

Referenced by actually_val_is_first_key_of_new_map_block().

◆ _find_matching_open()

evt_size c4::yml::extra::EventHandlerInts::_find_matching_open ( ievt::evt_bits open,
ievt::evt_bits close,
evt_size pos ) const
inline

Definition at line 1259 of file event_handler_ints.hpp.

1260 {
1261 _c4dbgpf("find_matching: start at {}", pos);
1262 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size);
1263 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[pos] & close) == close);
1264 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, (m_evt[pos] & open) == (close & ~ievt::END_));
1265 pos = _prev(pos); // don't count the starting close token
1266 uint32_t count = 0;
1267 while(pos >= 0)
1268 {
1269 ievt::evt_bits e = m_evt[pos];
1270 _c4dbgpf("find_matching: pos={} count={} e={}", pos, count, m_evt[pos]);
1271 if((e & close) == close)
1272 {
1273 _c4dbgpf(".............: pos={} close! count={} e={}", pos, count, m_evt[pos]);
1274 ++count;
1275 }
1276 else if((e & open) == open)
1277 {
1278 _c4dbgpf(".............: pos={} open! count={} e={}", pos, count, m_evt[pos]);
1279 if(!count)
1280 return pos;
1281 else
1282 --count;
1283 }
1284 pos = _prev(pos);
1285 }
1286 _c4dbgpf("find_matching: not found!", 0); // LCOV_EXCL_LINE
1287 return -1; // LCOV_EXCL_LINE
1288 }
evt_size _prev(evt_size pos) const noexcept

Referenced by actually_val_is_first_key_of_new_map_flow().

◆ _extend_left_to_include_tag_and_or_anchor()

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

Definition at line 1290 of file event_handler_ints.hpp.

1291 {
1292 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, pos < m_evt_size);
1293 evt_size prev = _prev(pos);
1294 while((prev > 0) && (m_evt[prev] & (ievt::TAG_|ievt::ANCH)))
1295 {
1296 _c4dbgpf("{}/{}: {} is anchor/tag. extend to {}", m_evt_pos, m_evt_size, prev, prev);
1297 pos = prev;
1298 prev = _prev(prev);
1299 }
1300 return pos;
1301 }

Referenced by actually_val_is_first_key_of_new_map_flow().

◆ _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_CB_(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.

Referenced by c4::yml::extra::EventHandlerInts::start_parse().

◆ _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 }

Referenced by c4::yml::extra::EventHandlerInts::finish_parse().

◆ _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 }

Referenced by c4::yml::extra::EventHandlerInts::reset().

◆ _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 }

Referenced by c4::yml::extra::EventHandlerInts::_push().

◆ _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_CB_(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 }

Referenced by c4::yml::extra::EventHandlerInts::_pop().

◆ _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 || ryml_has_any_(DOC|VAL|MAP|SEQ));
125 }

Referenced by c4::yml::extra::EventHandlerInts::begin_doc().

◆ _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 && ryml_has_any_(DOC);
131 }

Referenced by c4::yml::extra::EventHandlerInts::end_doc(), and c4::yml::extra::EventHandlerInts::end_doc_expl().

Member Data Documentation

◆ m_stack

◆ m_curr

◆ m_parent

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

◆ m_src


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