1 #ifndef C4_YML_EXTRA_EVENT_HANDLER_INTS_HPP_
2 #define C4_YML_EXTRA_EVENT_HANDLER_INTS_HPP_
6 #ifndef RYML_SINGLE_HEADER
7 #ifndef C4_YML_NODE_TYPE_HPP_
10 #ifndef C4_YML_EVENT_HANDLER_STACK_HPP_
13 #ifndef C4_YML_TAG_HPP_
16 #ifndef C4_YML_DETAIL_DBGPRINT_HPP_
17 #include <c4/yml/detail/dbgprint.hpp>
275 using DataType RYML_DEPRECATED(
"use evt_bits") =
evt_bits;
276 using EventFlags RYML_DEPRECATED(
"use EventBits") =
EventBits;
322 C4_SUPPRESS_WARNING_GCC_CLANG_PUSH
323 C4_SUPPRESS_WARNING_GCC_CLANG(
"-Wold-style-cast")
324 C4_SUPPRESS_WARNING_GCC("-Wuseless-cast")
467 using state = EventHandlerIntsState;
486 #define ryml_enable_(bits) enable_<bits>()
487 #define ryml_disable_(bits) disable_<bits>()
488 #define ryml_has_any_(bits) has_any_<bits>()
516 m_evt_size = dst_size;
520 m_tag_directives.
clear();
544 return m_evt_pos <= m_evt_size && m_arena_pos <= m_arena.
len;
607 _c4dbgpf(
"{}/{}: begin_doc", m_evt_pos, m_evt_size);
619 _c4dbgpf(
"{}/{}: end_doc", m_evt_pos, m_evt_size);
632 _c4dbgpf(
"{}/{}: begin_doc_expl", m_evt_pos, m_evt_size);
641 _c4dbgpf(
"{}/{}: end_doc_expl", m_evt_pos, m_evt_size);
660 _c4dbgpf(
"{}/{}: bmap key flow", m_evt_pos, m_evt_size);
668 _c4dbgpf(
"{}/{}: bmap key block", m_evt_pos, m_evt_size);
677 _c4dbgpf(
"{}/{}: bmap flow", m_evt_pos, m_evt_size);
685 _c4dbgpf(
"{}/{}: bmap block", m_evt_pos, m_evt_size);
713 _c4dbgpf(
"{}/{}: bseq key flow", m_evt_pos, m_evt_size);
721 _c4dbgpf(
"{}/{}: bseq key block", m_evt_pos, m_evt_size);
730 _c4dbgpf(
"{}/{}: bseq flow", m_evt_pos, m_evt_size);
738 _c4dbgpf(
"{}/{}: bseq block", m_evt_pos, m_evt_size);
780 _c4dbgpf(
"{}/{}: set_key_scalar_plain_empty", m_evt_pos, m_evt_size);
786 _c4dbgpf(
"{}/{}: set_val_scalar_plain_empty", m_evt_pos, m_evt_size);
794 _c4dbgpf(
"{}/{}: set_key_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.
str-
m_src.
str, scalar.
len, scalar);
800 _c4dbgpf(
"{}/{}: set_val_scalar_plain: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.
str-
m_src.
str, scalar.
len, scalar);
808 _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{});
814 _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{});
822 _c4dbgpf(
"{}/{}: set_key_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.
str-
m_src.
str, scalar.
len, scalar);
828 _c4dbgpf(
"{}/{}: set_val_scalar_squo: @{} [{}]~~~{}~~~", m_evt_pos, m_evt_size, scalar.
str-
m_src.
str, scalar.
len, scalar);
836 _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{});
842 _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{});
850 _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{});
856 _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{});
864 _c4dbgpf(
"{}/{}: mark_key_scalar_unfiltered", m_evt_pos, m_evt_size);
865 if(m_evt_pos < m_evt_size)
870 _c4dbgpf(
"{}/{}: mark_val_scalar_unfiltered", m_evt_pos, m_evt_size);
871 if(m_evt_pos < m_evt_size)
880 #define _add_scalar_(i, scalar) \
881 _c4dbgpf("{}/{}: scalar!", i, m_evt_size); \
882 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, _is_sub_(scalar)); \
883 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, m_evt[i] & ievt::WSTR); \
884 RYML_ASSERT_BASIC_CB_(m_stack.m_callbacks, ((i) + 3) < m_evt_size); \
885 if C4_LIKELY((scalar).is_sub(m_src)) \
887 m_evt[(i) + 1] = (ievt::evt_bits)((scalar).str - m_src.str); \
891 m_evt[i] |= ievt::AREN; \
892 m_evt[(i) + 1] = (ievt::evt_bits)((scalar).str - m_arena.str); \
893 _c4dbgpf("{}/{}: arena! ->{}", i, m_evt_size, m_evt[(i)+1]); \
895 m_evt[(i) + 2] = (ievt::evt_bits)(scalar).len; \
896 m_evt[(i) + 3] = ievt::PSTR
906 _c4dbgpf(
"{}/{}: set_key_anchor: {}", m_evt_pos, m_evt_size, anchor);
909 if(m_evt_pos + 3 < m_evt_size)
912 _add_scalar_(m_evt_pos, anchor);
914 m_evt_prev = m_evt_pos;
919 _c4dbgpf(
"{}/{}: set_val_anchor: {}", m_evt_pos, m_evt_size, anchor);
922 if(m_evt_pos + 3 < m_evt_size)
925 _add_scalar_(m_evt_pos, anchor);
927 m_evt_prev = m_evt_pos;
933 _c4dbgpf(
"{}/{}: set_key_ref: {}", m_evt_pos, m_evt_size, ref);
941 _c4dbgpf(
"{}/{}: set_val_ref: {}", m_evt_pos, m_evt_size, ref);
957 _c4dbgpf(
"{}/{}: set key tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.
len, tag.
str ? tag :
csubstr(
"(arena full)"));
964 _c4dbgpf(
"{}/{}: set val tag [{}]~~~{}~~~", m_evt_pos, m_evt_size, tag.
len, tag.
str ? tag :
csubstr(
"(arena full)"));
979 _c4dbgpf(
"{}/{}: %YAML directive! version={}", m_evt_pos, m_evt_size, yaml_version);
985 _c4dbgpf(
"{}/{}: %TAG directive! handle={} prefix={} doc_id={}", m_evt_pos, m_evt_size, handle, prefix, m_curr_doc);
986 if C4_UNLIKELY(!m_tag_directives.
add(handle, prefix, m_curr_doc))
987 RYML_ERR_PARSE_CB_(
m_stack.m_callbacks,
m_curr->pos,
"too many %TAG directives");
1006 _c4dbgpf(
"{}/{}: prev={} actually_val_is_first_key_of_new_map_flow", m_evt_pos, m_evt_size, m_evt_prev);
1007 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, m_evt_pos > 2);
1008 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, m_evt_prev > 0);
1017 if(m_evt_pos < m_evt_size)
1021 _c4dbgpf(
"{}/{}: WSTR", m_evt_pos, m_evt_size);
1022 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, m_evt_prev > 0);
1024 if(m_evt_pos + 1 < m_evt_size)
1031 evt_size num_move = m_evt_pos + 1 - pos;
1032 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, num_move > 0);
1033 memmove(m_evt + pos + 1, m_evt + pos, (
size_t)num_move *
sizeof(
ievt::evt_bits));
1040 m_evt[pos + 1] &= ~ievt
::PSTR;
1045 _c4dbgpf(
"{}/{}: container key", m_evt_pos, m_evt_size);
1048 _c4dbgpf(
"{}/{}: find matching open for {}", m_evt_pos, m_evt_size, m_evt_prev);
1049 if((m_evt[m_evt_prev] &
ievt::EMAP) == ievt::EMAP)
1058 _c4dbgpf(
"{}/{}: matching open for {}={}", m_evt_pos, m_evt_size, m_evt_prev, pos);
1059 RYML_CHECK_BASIC_CB_(
m_stack.m_callbacks, pos >= 0);
1060 RYML_CHECK_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_prev);
1062 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, (m_evt[pos] & ievt::EMAP) == (m_evt[m_evt_prev] &
ievt::BMAP));
1065 if(m_evt_pos + 1 < m_evt_size)
1067 evt_size num_move = m_evt_pos + 1 - pos;
1068 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, num_move > 0);
1069 memmove(m_evt + posp1, m_evt + pos, (
size_t)num_move *
sizeof(
ievt::evt_bits));
1071 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, posp1 < m_evt_pos);
1076 m_evt[posp1] &= ~ievt
::VAL_;
1081 m_evt[posp1] &= ~ievt
::PSTR;
1085 m_curr->evt_id = m_evt_pos - 2;
1100 _c4dbgpf(
"{}/{}: prev={} actually_val_is_first_key_of_new_map_block", m_evt_pos, m_evt_size, m_evt_prev);
1101 if(m_evt_pos < m_evt_size)
1107 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1108 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_pos);
1109 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, (m_evt[pos] &
ievt::BDOC) == ievt::BDOC);
1110 if(m_evt_pos < m_evt_size)
1113 evt_size num_move = m_evt_pos - pos;
1115 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, ((m_evt[pos] &
ievt::BSEQ) == ievt::BSEQ) || ((m_evt[pos] &
ievt::BMAP) == ievt::BMAP));
1116 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, num_move > 0);
1118 memmove(m_evt + posp1, m_evt + pos, (
size_t)num_move *
sizeof(
ievt::evt_bits));
1120 m_evt[posp1] &= ~ievt
::VAL_;
1140 return m_arena.
first(m_arena_pos < m_arena.
len ? m_arena_pos : m_arena.
len);
1144 return C4_EXPECT(m_arena_pos <= m_arena.
len, 1) ? m_arena.
sub(m_arena_pos) : m_arena.
last(0);
1150 if C4_LIKELY(len <= s.
len)
1179 template<c4::yml::type_bits bits> C4_ALWAYS_INLINE
void enable_() noexcept
1183 template<c4::yml::type_bits bits> C4_ALWAYS_INLINE
void disable_() noexcept
1187 template<c4::yml::type_bits bits> C4_ALWAYS_INLINE
bool has_any_() const noexcept
1194 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1195 return pos + ((m_evt[pos] &
ievt::WSTR) ? 3 : 1);
1200 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1201 return pos - ((m_evt[pos] &
ievt::PSTR) ? 3 : 1);
1211 _c4dbgpf(
"{}/{}: flag only", m_evt_pos, m_evt_size);
1212 if(m_evt_pos < m_evt_size)
1213 m_evt[m_evt_pos] |=
flags;
1214 m_curr->evt_id = m_evt_pos;
1215 m_evt_prev = m_evt_pos;
1217 if(m_evt_pos < m_evt_size)
1218 m_evt[m_evt_pos] = {};
1223 _c4dbgpf(
"{}/{}: send str", m_evt_pos, m_evt_size);
1224 if(m_evt_pos + 3 < m_evt_size)
1226 m_evt[m_evt_pos] |=
flags;
1227 _add_scalar_(m_evt_pos, scalar);
1229 m_curr->evt_id = m_evt_pos;
1230 m_evt_prev = m_evt_pos;
1250 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1263 _c4dbgpf(
"find_matching: start at {}", pos);
1264 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1265 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, (m_evt[pos] & close) == close);
1266 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, (m_evt[pos] & open) == (close & ~
ievt::END_));
1272 _c4dbgpf(
"find_matching: pos={} count={} e={}", pos, count, m_evt[pos]);
1273 if((e & close) == close)
1275 _c4dbgpf(
".............: pos={} close! count={} e={}", pos, count, m_evt[pos]);
1278 else if((e & open) == open)
1280 _c4dbgpf(
".............: pos={} open! count={} e={}", pos, count, m_evt[pos]);
1288 _c4dbgpf(
"find_matching: not found!", 0);
1294 RYML_ASSERT_BASIC_CB_(
m_stack.m_callbacks, pos < m_evt_size);
1298 _c4dbgpf(
"{}/{}: {} is anchor/tag. extend to {}", m_evt_pos, m_evt_size, prev, prev);
1308 #undef ryml_disable_
1309 #undef ryml_has_any_
1322 C4_SUPPRESS_WARNING_GCC_CLANG_POP
void reset(substr str, substr arena, ievt::evt_bits *dst, evt_size dst_size)
void add_directive_yaml(csubstr yaml_version)
bool has_any_() const noexcept
mark val scalar as plain scalar (unquoted, even when multiline)
bool _is_sub_(csubstr str) const noexcept
void end_seq_flow(bool, type_bits=FLOW_ML1)
bool _stack_should_pop_on_end_doc() const
void end_map_flow(bool, type_bits=FLOW_ML1)
reading unknown state (when starting): must determine whether scalar, map or seq
evt_size _find_matching_open(ievt::evt_bits open, ievt::evt_bits close, evt_size pos) const
mark key scalar as double quoted "
void set_val_scalar_plain_empty()
void begin_map_key_block()
mark key scalar as multiline, block literal |
mark val scalar as single quoted '
void begin_doc_expl()
explicit doc start, with —
void set_key_scalar_squoted(csubstr scalar)
#define ryml_has_any_(bits)
void set_val_ref(csubstr ref)
void mark_key_scalar_unfiltered()
size_t required_size_arena() const
get the size needed for the arena from the previous parse
C * str
a restricted pointer to the first character of the substring
Use this class a base of implementations of event handler to simplify the stack logic.
void set_key_scalar_folded(csubstr scalar)
void set_val_scalar_dquoted(csubstr scalar)
A c-style callbacks class to customize behavior on errors or allocation.
A parser event handler that creates a compact representation of the YAML tree in a contiguous buffer ...
void begin_seq_key_flow()
bool fits_buffers() const
Predicate to test if the event and arena buffers successfully accomodated all the parse events...
void end_doc()
implicit doc end (without ...)
mark val scalar as double quoted "
void _send_flag_only_(ievt::evt_bits flags)
a non-owning string-view, consisting of a character pointer and a length.
void set_key_anchor(csubstr anchor)
Accelerator structure to reduce memory requirements by enabling reuse of resolved tags...
evt_size required_size_events() const
get the size needed for the event buffer from the previous parse
basic_substring first(size_t num) const noexcept
return the first num elements: [0,num[
EventHandlerIntsState state
the key is null (eg { : b} results in a null key)
void _stack_start_parse(const char *filename, substr ymlsrc)
void _stack_finish_parse()
void begin_map_val_flow()
void set_val_scalar_literal(csubstr scalar)
substr alloc_arena(size_t len)
this may fail, in which case an empty string is returned
void begin_seq_val_flow()
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
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...
csubstr _get_latest_empty_scalar() const
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
void set_key_scalar_literal(csubstr scalar)
mark val scalar as multiline, block folded >
void set_key_scalar_plain_empty()
mark key scalar as multiline, block folded >
void set_key_tag(csubstr tag)
basic_substring sub(size_t first) const noexcept
return [first,len[
TagDirectives & tag_directives()
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.
evt_size _prev(evt_size pos) const noexcept
basic_substring< const char > csubstr
an immutable string view
void _send_str_(csubstr scalar, ievt::evt_bits flags)
void begin_seq_key_block()
void set_key_scalar_dquoted(csubstr scalar)
void begin_map_val_block()
the val is null (eg {a : } results in a null val)
a *reference: the val references an &anchor
mark container with block style < - seqs as <
void set_val_scalar_folded(csubstr scalar)
EventHandlerInts(c4::yml::Callbacks const &cb) noexcept
void mark_val_scalar_unfiltered()
the scalar to the left of : in a map's member
void start_parse(const char *filename, substr src)
void begin_map_key_flow()
void set_val_scalar_squoted(csubstr scalar)
a *reference: the key references an &anchor
void _mark_parent_with_children_()
void set_val_tag(csubstr tag)
state * m_parent
parent of the current stack level.
size_t len
the length of the substring
void add_directive_tag(csubstr handle, csubstr prefix)
mark key scalar as plain scalar (unquoted, even when multiline)
int32_t evt_size
data type for integer events size.
void _pop()
end the current scope
void begin_seq_val_block()
evt_size _extend_left_to_include_tag_and_or_anchor(evt_size pos) const
Callbacks const & get_callbacks()
get the global callbacks
void end_doc_expl()
explicit doc end, with ...
mark val scalar as multiline, block literal |
void begin_doc()
implicit doc start (without —)
uint32_t type_bits
the integral type necessary to cover all the bits for NodeType_e
basic_substring last(size_t num) const noexcept
return the last num elements: [len-num,len[
ievt::evt_bits value_type
void set_val_anchor(csubstr anchor)
void _push()
push a new parent, add a child to the new parent, and set the child as the current node ...
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 o...
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
evt_size _find_last_bdoc(evt_size pos) const
detail::stack< state > m_stack
mark key scalar as single quoted '
void set_val_scalar_plain(csubstr scalar)
bool _stack_should_push_on_begin_doc() const
bool begins_with(const C c) const noexcept
true if the first character of the string is c
TagDirective const * add(csubstr handle, csubstr prefix, id_type doc_id) noexcept
mark container with multi-line flow style, 1 element per line < - seqs as <
a seq: a parent of VAL/SEQ/MAP nodes
void set_key_scalar_plain(csubstr scalar)
EventHandlerInts() noexcept
void set_key_ref(csubstr ref)
state * m_curr
current stack level: top of the stack. cached here for easier access.
mark container with single-line flow style < - seqs as <
evt_size _next(evt_size pos) const noexcept