nodebuilder.cpp 2.74 KB
Newer Older
1
#include "old-api/nodebuilder.h"
2
#include "yaml-cpp/mark.h"
3
#include "yaml-cpp/old-api/node.h"
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <cassert>

namespace YAML
{
	NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false), m_finished(false)
	{
		m_root.Clear();
		m_anchors.push_back(0); // since the anchors start at 1
	}
	
	NodeBuilder::~NodeBuilder()
	{
	}

	void NodeBuilder::OnDocumentStart(const Mark&)
	{
	}

	void NodeBuilder::OnDocumentEnd()
	{
		assert(m_finished);
	}

27
	void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor)
28
29
	{
		Node& node = Push(anchor);
30
		node.Init(NodeType::Null, mark, "");
31
32
33
		Pop();
	}

34
	void NodeBuilder::OnAlias(const Mark& /*mark*/, anchor_t anchor)
35
	{
36
37
38
		Node& node = *m_anchors[anchor];
		Insert(node);
		node.MarkAsAliased();
39
40
41
42
43
	}

	void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
	{
		Node& node = Push(anchor);
44
45
		node.Init(NodeType::Scalar, mark, tag);
		node.SetScalarData(value);
46
47
48
49
50
51
		Pop();
	}

	void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
	{
		Node& node = Push(anchor);
52
		node.Init(NodeType::Sequence, mark, tag);
53
54
55
56
57
58
59
60
61
62
	}

	void NodeBuilder::OnSequenceEnd()
	{
		Pop();
	}

	void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
	{
		Node& node = Push(anchor);
63
		node.Init(NodeType::Map, mark, tag);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
		m_didPushKey.push(false);
	}

	void NodeBuilder::OnMapEnd()
	{
		m_didPushKey.pop();
		Pop();
	}
	
	Node& NodeBuilder::Push(anchor_t anchor)
	{
		Node& node = Push();
		RegisterAnchor(anchor, node);
		return node;
	}
	
	Node& NodeBuilder::Push()
	{
		if(!m_initializedRoot) {
			m_initializedRoot = true;
			return m_root;
		}
		
87
88
89
		Node& node = m_root.CreateNode();
		m_stack.push(&node);
		return node;
90
91
92
93
	}
	
	Node& NodeBuilder::Top()
	{
94
		return m_stack.empty() ? m_root : *m_stack.top();
95
96
97
98
99
100
101
102
103
104
	}
	
	void NodeBuilder::Pop()
	{
		assert(!m_finished);
		if(m_stack.empty()) {
			m_finished = true;
			return;
		}
		
105
106
107
		Node& node = *m_stack.top();
		m_stack.pop();
		Insert(node);
108
109
	}
	
110
	void NodeBuilder::Insert(Node& node)
111
	{
112
113
114
115
116
117
118
119
		Node& curTop = Top();
		switch(curTop.Type()) {
			case NodeType::Null:
			case NodeType::Scalar:
				assert(false);
				break;
			case NodeType::Sequence:
				curTop.Append(node);
120
				break;
121
			case NodeType::Map:
122
123
124
125
				assert(!m_didPushKey.empty());
				if(m_didPushKey.top()) {
					assert(!m_pendingKeys.empty());

126
127
128
					Node& key = *m_pendingKeys.top();
					m_pendingKeys.pop();
					curTop.Insert(key, node);
129
130
					m_didPushKey.top() = false;
				} else {
131
					m_pendingKeys.push(&node);
132
133
134
135
136
137
					m_didPushKey.top() = true;
				}
				break;
		}
	}

138
	void NodeBuilder::RegisterAnchor(anchor_t anchor, Node& node)
139
140
141
142
143
144
145
	{
		if(anchor) {
			assert(anchor == m_anchors.size());
			m_anchors.push_back(&node);
		}
	}
}