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_
19 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH(
"-Wold-style-cast")
35 template<
class Writer>
class Emitter;
36 template<
class OStream>
64 typedef enum : uint32_t {
66 JSON_ERR_ON_TAG = 1u << 0u,
67 JSON_ERR_ON_ANCHOR = 1u << 1u,
68 _JSON_ERR_MASK = JSON_ERR_ON_TAG|JSON_ERR_ON_ANCHOR,
90 static constexpr
const id_type max_depth_default = 64;
97 return m_max_depth == that.m_max_depth &&
98 m_option_flags == that.m_option_flags;
104 id_type m_max_depth{max_depth_default};
105 EmitOptionFlags_e m_option_flags{DEFAULT_FLAGS};
116 template<
class Writer>
124 template<
class ...Args>
125 Emitter(Args &&...args) : Writer(std::forward<Args>(args)...), m_tree(), m_opts(), m_flow(false) {}
132 template<
class ...Args>
133 Emitter(
EmitOptions const& opts, Args &&...args) : Writer(std::forward<Args>(args)...), m_tree(), m_opts(opts), m_flow(false) {}
158 return this->emit_as(type, t, t.
root_id(), error_on_excess);
166 return this->emit_as(type, *n.
tree(), n.
id(), error_on_excess);
181 Tree const* C4_RESTRICT m_tree;
200 void _write_scalar_json_dquo(csubstr s);
201 void _write_scalar_literal(csubstr s,
id_type level,
bool as_key);
202 void _write_scalar_folded(csubstr s,
id_type level,
bool as_key);
203 void _write_scalar_squo(csubstr s,
id_type level);
204 void _write_scalar_dquo(csubstr s,
id_type level);
205 void _write_scalar_plain(csubstr s,
id_type level);
207 size_t _write_escaped_newlines(csubstr s,
size_t i);
208 size_t _write_indented_block(csubstr s,
size_t i,
id_type level);
210 void _write_tag(csubstr tag)
212 if(!tag.begins_with(
'!'))
213 this->Writer::_do_write(
'!');
214 this->Writer::_do_write(tag);
220 _keysc_json = (
KEY) | ~(
VAL),
221 _valsc_json = ~(
KEY) | (
VAL),
224 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); }
225 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); }
227 C4_ALWAYS_INLINE
void _writek_json(
id_type id) { _write_json(m_tree->keysc(
id), m_tree->_p(
id)->m_type.type & ~(
VAL)); }
228 C4_ALWAYS_INLINE
void _writev_json(
id_type id) { _write_json(m_tree->valsc(
id), m_tree->_p(
id)->m_type.type & ~(
KEY)); }
230 void _indent(
id_type level,
bool enabled)
233 this->Writer::_do_write(
' ', 2u * (
size_t)level);
238 this->Writer::_do_write(
' ', 2u * (
size_t)level);
361 template<
class OStream>
371 template<
class OStream>
424 template<
class OStream>
435 template<
class OStream>
515 inline substr
emit_yaml(
Tree const& t, substr buf,
bool error_on_excess=
true)
534 inline substr
emit_json(
Tree const& t, substr buf,
bool error_on_excess=
true)
605 template<
class CharOwningContainer>
608 size_t startpos = append ? cont->size() : 0u;
609 cont->resize(cont->capacity());
610 substr buf =
to_substr(*cont).sub(startpos);
611 substr ret =
emit_yaml(t,
id, opts, buf,
false);
612 if(ret.str ==
nullptr && ret.len > 0)
614 cont->resize(startpos + ret.len);
620 cont->resize(startpos + ret.len);
625 template<
class CharOwningContainer>
635 template<
class CharOwningContainer>
638 const size_t startpos = append ? cont->size() : 0u;
639 cont->resize(cont->capacity());
640 substr buf =
to_substr(*cont).sub(startpos);
642 substr ret =
emit_json(t,
id, opts, buf,
false);
643 if(ret.str ==
nullptr && ret.len > 0)
645 cont->resize(startpos + ret.len);
651 cont->resize(startpos + ret.len);
656 template<
class CharOwningContainer>
664 template<
class CharOwningContainer>
667 CharOwningContainer c;
672 template<
class CharOwningContainer>
675 CharOwningContainer c;
686 template<
class CharOwningContainer>
694 template<
class CharOwningContainer>
704 template<
class CharOwningContainer>
712 template<
class CharOwningContainer>
722 template<
class CharOwningContainer>
725 CharOwningContainer c;
732 template<
class CharOwningContainer>
735 CharOwningContainer c;
749 template<
class CharOwningContainer>
758 template<
class CharOwningContainer>
769 template<
class CharOwningContainer>
778 template<
class CharOwningContainer>
789 template<
class CharOwningContainer>
795 CharOwningContainer c;
800 template<
class CharOwningContainer>
806 CharOwningContainer c;
819 #define RYML_DEPRECATE_EMIT \
820 RYML_DEPRECATED("use emit_yaml() instead. " \
821 "See https://github.com/biojppm/rapidyaml/issues/120")
822 #define RYML_DEPRECATE_EMITRS \
823 RYML_DEPRECATED("use emitrs_yaml() instead. " \
824 "See https://github.com/biojppm/rapidyaml/issues/120")
830 #define RYML_TMP_EMIT_
834 RYML_DEPRECATE_EMIT
inline size_t emit(Tree
const& t,
id_type id, FILE *f)
838 RYML_DEPRECATE_EMIT
inline size_t emit(Tree
const& t, FILE *f=
nullptr)
842 RYML_DEPRECATE_EMIT
inline size_t emit(ConstNodeRef
const& r, FILE *f=
nullptr)
847 RYML_DEPRECATE_EMIT
inline substr emit(Tree
const& t,
id_type id, substr buf,
bool error_on_excess=
true)
849 return emit_yaml(t,
id, buf, error_on_excess);
851 RYML_DEPRECATE_EMIT
inline substr emit(Tree
const& t, substr buf,
bool error_on_excess=
true)
853 return emit_yaml(t, buf, error_on_excess);
855 RYML_DEPRECATE_EMIT
inline substr emit(ConstNodeRef
const& r, substr buf,
bool error_on_excess=
true)
857 return emit_yaml(r, buf, error_on_excess);
860 #ifdef RYML_TMP_EMIT_
862 #undef RYML_TMP_EMIT_
865 template<
class CharOwningContainer>
866 RYML_DEPRECATE_EMITRS substr emitrs(Tree
const& t,
id_type id, CharOwningContainer * cont)
870 template<
class CharOwningContainer>
871 RYML_DEPRECATE_EMITRS CharOwningContainer emitrs(Tree
const& t,
id_type id)
873 return emitrs_yaml<CharOwningContainer>(t,
id);
875 template<
class CharOwningContainer>
876 RYML_DEPRECATE_EMITRS substr emitrs(Tree
const& t, CharOwningContainer * cont)
880 template<
class CharOwningContainer>
881 RYML_DEPRECATE_EMITRS CharOwningContainer emitrs(Tree
const& t)
883 return emitrs_yaml<CharOwningContainer>(t);
885 template<
class CharOwningContainer>
886 RYML_DEPRECATE_EMITRS substr emitrs(ConstNodeRef
const& n, CharOwningContainer * cont)
890 template<
class CharOwningContainer>
891 RYML_DEPRECATE_EMITRS CharOwningContainer emitrs(ConstNodeRef
const& n)
893 return emitrs_yaml<CharOwningContainer>(n);
902 C4_SUPPRESS_WARNING_GCC_CLANG_POP
904 #undef RYML_DEPRECATE_EMIT
905 #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.
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<< .