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