/src/yaml-cpp/src/nodebuilder.cpp
Line | Count | Source |
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 | 13.9k | : m_pMemory(std::make_shared<detail::memory_holder>()), |
14 | 13.9k | m_pRoot(nullptr), |
15 | 13.9k | m_stack{}, |
16 | 13.9k | m_anchors{}, |
17 | 13.9k | m_keys{}, |
18 | 13.9k | m_mapDepth(0) { |
19 | 13.9k | m_anchors.push_back(nullptr); // since the anchors start at 1 |
20 | 13.9k | } |
21 | | |
22 | 13.9k | NodeBuilder::~NodeBuilder() = default; |
23 | | |
24 | 7.44k | Node NodeBuilder::Root() { |
25 | 7.44k | if (!m_pRoot) |
26 | 0 | return Node(); |
27 | | |
28 | 7.44k | return Node(*m_pRoot, m_pMemory); |
29 | 7.44k | } |
30 | | |
31 | 10.5k | void NodeBuilder::OnDocumentStart(const Mark&) {} |
32 | | |
33 | 8.26k | void NodeBuilder::OnDocumentEnd() {} |
34 | | |
35 | 787k | void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { |
36 | 787k | detail::node& node = Push(mark, anchor); |
37 | 787k | node.set_null(); |
38 | 787k | Pop(); |
39 | 787k | } |
40 | | |
41 | 1.06k | void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { |
42 | 1.06k | detail::node& node = *m_anchors[anchor]; |
43 | 1.06k | Push(node); |
44 | 1.06k | Pop(); |
45 | 1.06k | } |
46 | | |
47 | | void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, |
48 | 15.7k | anchor_t anchor, const std::string& value) { |
49 | 15.7k | detail::node& node = Push(mark, anchor); |
50 | 15.7k | node.set_scalar(value); |
51 | 15.7k | node.set_tag(tag); |
52 | 15.7k | Pop(); |
53 | 15.7k | } |
54 | | |
55 | | void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, |
56 | 46.1k | anchor_t anchor, EmitterStyle::value style) { |
57 | 46.1k | detail::node& node = Push(mark, anchor); |
58 | 46.1k | node.set_tag(tag); |
59 | 46.1k | node.set_type(NodeType::Sequence); |
60 | 46.1k | node.set_style(style); |
61 | 46.1k | } |
62 | | |
63 | 2.33k | void NodeBuilder::OnSequenceEnd() { Pop(); } |
64 | | |
65 | | void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, |
66 | 95.1k | anchor_t anchor, EmitterStyle::value style) { |
67 | 95.1k | detail::node& node = Push(mark, anchor); |
68 | 95.1k | node.set_type(NodeType::Map); |
69 | 95.1k | node.set_tag(tag); |
70 | 95.1k | node.set_style(style); |
71 | 95.1k | m_mapDepth++; |
72 | 95.1k | } |
73 | | |
74 | 13.2k | void NodeBuilder::OnMapEnd() { |
75 | 13.2k | assert(m_mapDepth > 0); |
76 | 13.2k | m_mapDepth--; |
77 | 13.2k | Pop(); |
78 | 13.2k | } |
79 | | |
80 | 944k | detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { |
81 | 944k | detail::node& node = m_pMemory->create_node(); |
82 | 944k | node.set_mark(mark); |
83 | 944k | RegisterAnchor(anchor, node); |
84 | 944k | Push(node); |
85 | 944k | return node; |
86 | 944k | } |
87 | | |
88 | 945k | void NodeBuilder::Push(detail::node& node) { |
89 | 945k | const bool needsKey = |
90 | 945k | (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && |
91 | 205k | m_keys.size() < m_mapDepth); |
92 | | |
93 | 945k | m_stack.push_back(&node); |
94 | 945k | if (needsKey) |
95 | 143k | m_keys.emplace_back(&node, false); |
96 | 945k | } |
97 | | |
98 | 820k | void NodeBuilder::Pop() { |
99 | 820k | assert(!m_stack.empty()); |
100 | 820k | if (m_stack.size() == 1) { |
101 | 8.26k | m_pRoot = m_stack[0]; |
102 | 8.26k | m_stack.pop_back(); |
103 | 8.26k | return; |
104 | 8.26k | } |
105 | | |
106 | 812k | detail::node& node = *m_stack.back(); |
107 | 812k | m_stack.pop_back(); |
108 | | |
109 | 812k | detail::node& collection = *m_stack.back(); |
110 | | |
111 | 812k | if (collection.type() == NodeType::Sequence) { |
112 | 687k | collection.push_back(node, m_pMemory); |
113 | 687k | } else if (collection.type() == NodeType::Map) { |
114 | 124k | assert(!m_keys.empty()); |
115 | 124k | PushedKey& key = m_keys.back(); |
116 | 124k | if (key.second) { |
117 | 62.2k | collection.insert(*key.first, node, m_pMemory); |
118 | 62.2k | m_keys.pop_back(); |
119 | 62.7k | } else { |
120 | 62.7k | key.second = true; |
121 | 62.7k | } |
122 | 124k | } else { |
123 | 0 | assert(false); |
124 | 0 | m_stack.clear(); |
125 | 0 | } |
126 | 812k | } |
127 | | |
128 | 944k | void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { |
129 | 944k | if (anchor) { |
130 | | assert(anchor == m_anchors.size()); |
131 | 672k | m_anchors.push_back(&node); |
132 | 672k | } |
133 | 944k | } |
134 | | } // namespace YAML |