1 #ifndef _C4_YML_EMIT_HPP_
2 #define _C4_YML_EMIT_HPP_
6 #ifndef _C4_YML_WRITER_HPP_
10 #ifndef _C4_YML_TREE_HPP_
14 #ifndef _C4_YML_NODE_HPP_
18 #define RYML_DEPRECATE_EMIT \
19 RYML_DEPRECATED("use emit_yaml() instead. " \
20 "See https://github.com/biojppm/rapidyaml/issues/120")
21 #define RYML_DEPRECATE_EMITRS \
22 RYML_DEPRECATED("use emitrs_yaml() instead. " \
23 "See https://github.com/biojppm/rapidyaml/issues/120")
26 #error "emit is defined, likely from a Qt include. " \
27 "This will cause a compilation error. " \
28 "See https://github.com/biojppm/rapidyaml/issues/120"
32 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH(
"-Wold-style-cast")
48 template<
class Writer>
class Emitter;
49 template<
class OStream>
77 typedef enum : uint32_t {
79 JSON_ERR_ON_TAG = 1u << 0u,
80 JSON_ERR_ON_ANCHOR = 1u << 1u,
81 _JSON_ERR_MASK = JSON_ERR_ON_TAG|JSON_ERR_ON_ANCHOR,
103 static constexpr
const id_type max_depth_default = 64;
110 return m_max_depth == that.m_max_depth &&
111 m_option_flags == that.m_option_flags;
117 id_type m_max_depth{max_depth_default};
118 EmitOptionFlags_e m_option_flags{DEFAULT_FLAGS};
129 template<
class Writer>
137 template<
class ...Args>
138 Emitter(Args &&...args) : Writer(std::forward<Args>(args)...), m_tree(), m_opts(), m_flow(false) {}
145 template<
class ...Args>
146 Emitter(
EmitOptions const& opts, Args &&...args) : Writer(std::forward<Args>(args)...), m_tree(), m_opts(opts), m_flow(false) {}
171 return this->emit_as(type, t, t.
root_id(), error_on_excess);
179 return this->emit_as(type, *n.
tree(), n.
id(), error_on_excess);
194 Tree const* C4_RESTRICT m_tree;
213 void _write_scalar_json_dquo(csubstr s);
214 void _write_scalar_literal(csubstr s,
id_type level,
bool as_key);
215 void _write_scalar_folded(csubstr s,
id_type level,
bool as_key);
216 void _write_scalar_squo(csubstr s,
id_type level);
217 void _write_scalar_dquo(csubstr s,
id_type level);
218 void _write_scalar_plain(csubstr s,
id_type level);
220 size_t _write_escaped_newlines(csubstr s,
size_t i);
221 size_t _write_indented_block(csubstr s,
size_t i,
id_type level);
223 void _write_tag(csubstr tag)
225 if(!tag.begins_with(
'!'))
226 this->Writer::_do_write(
'!');
227 this->Writer::_do_write(tag);
233 _keysc_json = (
KEY) | ~(
VAL),
234 _valsc_json = ~(
KEY) | (
VAL),
237 C4_ALWAYS_INLINE
void _writek(
id_type id,
id_type level) { _write(m_tree->keysc(
id), (m_tree->_p(
id)->m_type.type & ~_valsc), level); }
238 C4_ALWAYS_INLINE
void _writev(
id_type id,
id_type level) { _write(m_tree->valsc(
id), (m_tree->_p(
id)->m_type.type & ~_keysc), level); }
240 C4_ALWAYS_INLINE
void _writek_json(
id_type id) { _write_json(m_tree->keysc(
id), m_tree->_p(
id)->m_type.type & ~(
VAL)); }
241 C4_ALWAYS_INLINE
void _writev_json(
id_type id) { _write_json(m_tree->valsc(
id), m_tree->_p(
id)->m_type.type & ~(
KEY)); }
243 void _indent(
id_type level,
bool enabled)
246 this->Writer::_do_write(
' ', 2u * (
size_t)level);
251 this->Writer::_do_write(
' ', 2u * (
size_t)level);
374 template<
class OStream>
384 template<
class OStream>
437 template<
class OStream>
448 template<
class OStream>
528 inline substr
emit_yaml(
Tree const& t, substr buf,
bool error_on_excess=
true)
547 inline substr
emit_json(
Tree const& t, substr buf,
bool error_on_excess=
true)
618 template<
class CharOwningContainer>
621 size_t startpos = append ? cont->size() : 0u;
622 cont->resize(cont->capacity());
623 substr buf =
to_substr(*cont).sub(startpos);
624 substr ret =
emit_yaml(t,
id, opts, buf,
false);
625 if(ret.str ==
nullptr && ret.len > 0)
627 cont->resize(startpos + ret.len);
633 cont->resize(startpos + ret.len);
638 template<
class CharOwningContainer>
648 template<
class CharOwningContainer>
651 const size_t startpos = append ? cont->size() : 0u;
652 cont->resize(cont->capacity());
653 substr buf =
to_substr(*cont).sub(startpos);
655 substr ret =
emit_json(t,
id, opts, buf,
false);
656 if(ret.str ==
nullptr && ret.len > 0)
658 cont->resize(startpos + ret.len);
664 cont->resize(startpos + ret.len);
669 template<
class CharOwningContainer>
677 template<
class CharOwningContainer>
680 CharOwningContainer c;
685 template<
class CharOwningContainer>
688 CharOwningContainer c;
699 template<
class CharOwningContainer>
707 template<
class CharOwningContainer>
717 template<
class CharOwningContainer>
725 template<
class CharOwningContainer>
735 template<
class CharOwningContainer>
738 CharOwningContainer c;
745 template<
class CharOwningContainer>
748 CharOwningContainer c;
762 template<
class CharOwningContainer>
771 template<
class CharOwningContainer>
782 template<
class CharOwningContainer>
791 template<
class CharOwningContainer>
802 template<
class CharOwningContainer>
808 CharOwningContainer c;
813 template<
class CharOwningContainer>
819 CharOwningContainer c;
847 return emit_yaml(t,
id, buf, error_on_excess);
849 RYML_DEPRECATE_EMIT inline substr emit(Tree
const& t, substr buf,
bool error_on_excess=
true)
851 return emit_yaml(t, buf, error_on_excess);
853 RYML_DEPRECATE_EMIT inline substr emit(ConstNodeRef
const& r, substr buf,
bool error_on_excess=
true)
855 return emit_yaml(r, buf, error_on_excess);
858 template<
class CharOwningContainer>
863 template<
class CharOwningContainer>
866 return emitrs_yaml<CharOwningContainer>(t,
id);
868 template<
class CharOwningContainer>
873 template<
class CharOwningContainer>
876 return emitrs_yaml<CharOwningContainer>(t);
878 template<
class CharOwningContainer>
883 template<
class CharOwningContainer>
886 return emitrs_yaml<CharOwningContainer>(n);
894 C4_SUPPRESS_WARNING_GCC_CLANG_POP
896 #undef RYML_DEPRECATE_EMIT
897 #undef RYML_DEPRECATE_EMITRS
Holds a pointer to an existing tree, and a node id.
Tree const * tree() const noexcept
id_type id() const noexcept
bool readable() const noexcept
because a ConstNodeRef cannot be used to write to the tree, readable() has the same meaning as !...
A stateful emitter, for use with a writer such as WriterBuf, WriterFile, or WriterOStream.
Callbacks const & callbacks() const
id_type root_id()
Get the id of the root node.
Definitions for emit functions.
#define RYML_DEPRECATE_EMIT
#define RYML_DEPRECATE_EMITRS
EmitOptionFlags_e json_error_flags() const noexcept
id_type max_depth() const noexcept
get the max depth for emitted trees (to prevent a stack overflow)
substr emit_as(EmitType_e type, ConstNodeRef const &n, bool error_on_excess=true)
emit starting at the given node
as_yaml(Tree const &t, size_t id, EmitOptions const &opts={})
Emitter(EmitOptions const &opts, Args &&...args)
Construct the emitter and its internal Writer state.
void max_depth(id_type max_depth) noexcept
set the max depth for emitted trees (to prevent a stack overflow)
as_yaml(Tree const &t, EmitOptions const &opts={})
substr emit_as(EmitType_e type, Tree const &t, bool error_on_excess=true)
emit starting at the root node
Emitter(Args &&...args)
Construct the emitter and its internal Writer state, using default emit options.
id_type max_depth() const noexcept
substr emit_as(EmitType_e type, Tree const &t, id_type id, bool error_on_excess)
emit!
bool is_set_(ConstNodeRef n)
as_json(Tree const &t, EmitOptions const &opts={})
as_yaml(ConstNodeRef const &n, EmitOptions const &opts={})
substr emit_yaml(ConstNodeRef const &r, substr buf, bool error_on_excess=true)
(2) like (1), but use default emit options
as_json(ConstNodeRef const &n, EmitOptions const &opts={})
EmitOptions const & options() const noexcept
get the emit options for this object
substr emit_json(ConstNodeRef const &r, substr buf, bool error_on_excess=true)
(2) like (1), but use default emit options
EmitOptions & max_depth(id_type d) noexcept
EmitOptions & json_error_flags(EmitOptionFlags_e d) noexcept
as_json(Tree const &t, size_t id, EmitOptions const &opts={})
CharOwningContainer emitrs_yaml(ConstNodeRef const &n, EmitOptions const &opts={})
(3) emit+resize: YAML to a newly-created std::string/std::vector-like container.
CharOwningContainer emitrs_json(ConstNodeRef const &n, EmitOptions const &opts={})
(3) emit+resize: JSON to a newly-created std::string/std::vector-like container.
OStream & operator<<(OStream &s, as_yaml const &y)
emit yaml to an STL-like stream
EmitType_e
Specifies the type of content to emit.
uint32_t type_bits
the integral type necessary to cover all the bits for NodeType_e
@ VALANCH
the val has an &anchor
@ VALREF
a *reference: the val references an &anchor
@ KEYQUO
key style is one of ', ", > or |
@ VAL_STYLE
mask of all the scalar styles for val (not container styles!)
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
@ KEY_STYLE
mask of all the scalar styles for key (not container styles!)
@ KEYREF
a *reference: the key references an &anchor
@ KEYANCH
the key has an &anchor
@ VALQUO
val style is one of ', ", > or |
substr to_substr(substr s) noexcept
neutral version for use in generic code
bool operator==(const char(&s)[N], basic_substring< C > const that) noexcept
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...
A lightweight object containing options to be used when emitting.
a node scalar is a csubstr, which may be tagged and anchored.
wraps a NodeType_e element with some syntactic sugar and predicates
mark a tree or node to be emitted as yaml when using operator<<, with options.
mark a tree or node to be emitted as yaml when using operator<< .