rapidyaml
0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
reference_resolver.hpp
Go to the documentation of this file.
1
#ifndef C4_YML_REFERENCE_RESOLVER_HPP_
2
#define C4_YML_REFERENCE_RESOLVER_HPP_
3
4
#include "
c4/yml/tree.hpp
"
5
#include "c4/yml/detail/stack.hpp"
6
7
8
namespace
c4
{
9
namespace
yml
{
10
11
/** @addtogroup doc_ref_utils
12
* @{
13
*/
14
15
/** Reusable object to resolve references/aliases in a @ref Tree. */
16
struct
ReferenceResolver
17
{
18
ReferenceResolver
() =
default
;
19
20
/** Resolve references: for each reference, look for a matching
21
* anchor, and copy its contents to the ref node.
22
*
23
* @p tree the subject tree
24
*
25
* @p clear_anchors whether to clear existing anchors after
26
* resolving
27
*
28
* This method first does a full traversal of the tree to gather
29
* all anchors and references in a separate collection, then it
30
* goes through that collection to locate the names, which it does
31
* by obeying the YAML standard diktat that "an alias node refers
32
* to the most recent node in the serialization having the
33
* specified anchor"
34
*
35
* So, depending on the number of anchor/alias nodes, this is a
36
* potentially expensive operation, with a best-case linear
37
* complexity (from the initial traversal). This potential cost is
38
* one of the reasons for requiring an explicit call.
39
*
40
* The @ref Tree has an `Tree::resolve()` overload set forwarding
41
* here. Previously this operation was done there, using a
42
* discarded object; using this separate class offers opportunity
43
* for reuse of the object.
44
*
45
* @warning resolving references opens an attack vector when the
46
* data is malicious or severely malformed, as the tree can expand
47
* exponentially. See for example the [Billion Laughs
48
* Attack](https://en.wikipedia.org/wiki/Billion_laughs_attack).
49
*
50
*/
51
RYML_EXPORT
void
resolve
(
Tree
*tree,
bool
clear_anchors=
true
);
52
53
public
:
54
55
/** @cond dev */
56
57
struct
RefData
58
{
59
NodeType
type;
60
id_type
node;
61
id_type
prev_anchor;
62
id_type
target;
63
id_type
parent_ref;
64
id_type
parent_ref_sibling;
65
};
66
67
void
reset_(
Tree
*t_);
68
void
resolve_();
69
void
gather_anchors_and_refs_();
70
void
gather_anchors_and_refs_(
id_type
n);
71
id_type
count_anchors_and_refs_(
id_type
n);
72
73
id_type
lookup_(RefData
const
* C4_RESTRICT ra);
74
75
Tree
*C4_RESTRICT m_tree;
76
/** We're using this stack purely as an array. */
77
detail::stack<RefData> m_refs;
78
79
/** @endcond */
80
};
81
82
/** @} */
83
84
}
// namespace ryml
85
}
// namespace c4
86
87
88
#endif
// C4_YML_REFERENCE_RESOLVER_HPP_
c4::yml::Tree
Definition
tree.hpp:308
RYML_EXPORT
#define RYML_EXPORT
Definition
export.hpp:18
c4::yml
Definition
doxy_common.hpp:2
c4::yml::id_type
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...
Definition
common.hpp:124
c4
Definition
doxy_common.hpp:1
c4::yml::NodeType
Wraps a type_bits mask of NodeTypeBits flags with some syntactic sugar and predicates.
Definition
node_type.hpp:214
c4::yml::ReferenceResolver::ReferenceResolver
ReferenceResolver()=default
c4::yml::ReferenceResolver::resolve
void resolve(Tree *tree, bool clear_anchors=true)
Resolve references: for each reference, look for a matching anchor, and copy its contents to the ref ...
tree.hpp
src
c4
yml
reference_resolver.hpp
Generated by
1.15.0