/src/yaml-cpp/src/nodebuilder.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include <cassert> |
2 | | |
3 | | #include "nodebuilder.h" |
4 | | #include "yaml-cpp/node/detail/node.h" |
5 | | #include "yaml-cpp/node/impl.h" |
6 | | #include "yaml-cpp/node/node.h" |
7 | | #include "yaml-cpp/node/type.h" |
8 | | |
9 | | namespace YAML { |
10 | | struct Mark; |
11 | | |
12 | | NodeBuilder::NodeBuilder() |
13 | 72.3k | : m_pMemory(new detail::memory_holder), |
14 | 72.3k | m_pRoot(nullptr), |
15 | 72.3k | m_stack{}, |
16 | 72.3k | m_anchors{}, |
17 | 72.3k | m_keys{}, |
18 | 72.3k | m_mapDepth(0) { |
19 | 72.3k | m_anchors.push_back(nullptr); // since the anchors start at 1 |
20 | 72.3k | } |
21 | | |
22 | 72.3k | NodeBuilder::~NodeBuilder() = default; |
23 | | |
24 | 132k | Node NodeBuilder::Root() { |
25 | 132k | if (!m_pRoot) |
26 | 0 | return Node(); |
27 | | |
28 | 132k | return Node(*m_pRoot, m_pMemory); |
29 | 132k | } |
30 | | |
31 | 68.7k | void NodeBuilder::OnDocumentStart(const Mark&) {} |
32 | | |
33 | 66.5k | void NodeBuilder::OnDocumentEnd() {} |
34 | | |
35 | 3.52M | void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { |
36 | 3.52M | detail::node& node = Push(mark, anchor); |
37 | 3.52M | node.set_null(); |
38 | 3.52M | Pop(); |
39 | 3.52M | } |
40 | | |
41 | 2.30k | void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { |
42 | 2.30k | detail::node& node = *m_anchors[anchor]; |
43 | 2.30k | Push(node); |
44 | 2.30k | Pop(); |
45 | 2.30k | } |
46 | | |
47 | | void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, |
48 | 395k | anchor_t anchor, const std::string& value) { |
49 | 395k | detail::node& node = Push(mark, anchor); |
50 | 395k | node.set_scalar(value); |
51 | 395k | node.set_tag(tag); |
52 | 395k | Pop(); |
53 | 395k | } |
54 | | |
55 | | void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, |
56 | 52.2k | anchor_t anchor, EmitterStyle::value style) { |
57 | 52.2k | detail::node& node = Push(mark, anchor); |
58 | 52.2k | node.set_tag(tag); |
59 | 52.2k | node.set_type(NodeType::Sequence); |
60 | 52.2k | node.set_style(style); |
61 | 52.2k | } |
62 | | |
63 | 5.40k | void NodeBuilder::OnSequenceEnd() { Pop(); } |
64 | | |
65 | | void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, |
66 | 198k | anchor_t anchor, EmitterStyle::value style) { |
67 | 198k | detail::node& node = Push(mark, anchor); |
68 | 198k | node.set_type(NodeType::Map); |
69 | 198k | node.set_tag(tag); |
70 | 198k | node.set_style(style); |
71 | 198k | m_mapDepth++; |
72 | 198k | } |
73 | | |
74 | 83.0k | void NodeBuilder::OnMapEnd() { |
75 | 83.0k | assert(m_mapDepth > 0); |
76 | 83.0k | m_mapDepth--; |
77 | 83.0k | Pop(); |
78 | 83.0k | } |
79 | | |
80 | 4.16M | detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { |
81 | 4.16M | detail::node& node = m_pMemory->create_node(); |
82 | 4.16M | node.set_mark(mark); |
83 | 4.16M | RegisterAnchor(anchor, node); |
84 | 4.16M | Push(node); |
85 | 4.16M | return node; |
86 | 4.16M | } |
87 | | |
88 | 4.17M | void NodeBuilder::Push(detail::node& node) { |
89 | 4.17M | const bool needsKey = |
90 | 4.17M | (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && |
91 | 4.17M | m_keys.size() < m_mapDepth); |
92 | | |
93 | 4.17M | m_stack.push_back(&node); |
94 | 4.17M | if (needsKey) |
95 | 220k | m_keys.emplace_back(&node, false); |
96 | 4.17M | } |
97 | | |
98 | 4.00M | void NodeBuilder::Pop() { |
99 | 4.00M | assert(!m_stack.empty()); |
100 | 4.00M | if (m_stack.size() == 1) { |
101 | 66.5k | m_pRoot = m_stack[0]; |
102 | 66.5k | m_stack.pop_back(); |
103 | 66.5k | return; |
104 | 66.5k | } |
105 | | |
106 | 3.94M | detail::node& node = *m_stack.back(); |
107 | 3.94M | m_stack.pop_back(); |
108 | | |
109 | 3.94M | detail::node& collection = *m_stack.back(); |
110 | | |
111 | 3.94M | if (collection.type() == NodeType::Sequence) { |
112 | 3.68M | collection.push_back(node, m_pMemory); |
113 | 3.68M | } else if (collection.type() == NodeType::Map) { |
114 | 253k | assert(!m_keys.empty()); |
115 | 253k | PushedKey& key = m_keys.back(); |
116 | 253k | if (key.second) { |
117 | 106k | collection.insert(*key.first, node, m_pMemory); |
118 | 106k | m_keys.pop_back(); |
119 | 146k | } else { |
120 | 146k | key.second = true; |
121 | 146k | } |
122 | 253k | } else { |
123 | 0 | assert(false); |
124 | 0 | m_stack.clear(); |
125 | 0 | } |
126 | 3.94M | } |
127 | | |
128 | 4.16M | void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { |
129 | 4.16M | if (anchor) { |
130 | 586k | assert(anchor == m_anchors.size()); |
131 | 586k | m_anchors.push_back(&node); |
132 | 586k | } |
133 | 4.16M | } |
134 | | } // namespace YAML |