node_data.cpp 4.67 KB
Newer Older
1
2
3
#include "yaml-cpp/node/detail/node_data.h"
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
4
#include <sstream>
Jesse Beder's avatar
Jesse Beder committed
5
#include <stdexcept>
Jesse Beder's avatar
Jesse Beder committed
6
7
8
9
10

namespace YAML
{
	namespace detail
	{
11
12
		std::string node_data::empty_scalar;

13
		node_data::node_data(): m_isDefined(false), m_type(NodeType::Null)
Jesse Beder's avatar
Jesse Beder committed
14
15
		{
		}
16

17
18
19
20
21
22
23
		void node_data::mark_defined()
		{
			if(m_type == NodeType::Undefined)
				m_type = NodeType::Null;
			m_isDefined = true;
		}

24
		void node_data::set_type(NodeType::value type)
25
		{
26
			if(type == NodeType::Undefined) {
27
28
29
30
31
32
33
34
35
36
37
38
39
				m_type = type;
				m_isDefined = false;
				return;
			}
			

			m_isDefined = true;
			if(type == m_type)
				return;
			
			m_type = type;
			
			switch(m_type) {
40
				case NodeType::Null:
41
					break;
42
				case NodeType::Scalar:
43
44
					m_scalar.clear();
					break;
45
				case NodeType::Sequence:
46
47
					m_sequence.clear();
					break;
48
				case NodeType::Map:
49
50
					m_map.clear();
					break;
51
				case NodeType::Undefined:
52
53
54
55
56
57
58
59
					assert(false);
					break;
			}
		}

		void node_data::set_null()
		{
			m_isDefined = true;
60
			m_type = NodeType::Null;
61
62
63
64
65
		}
		
		void node_data::set_scalar(const std::string& scalar)
		{
			m_isDefined = true;
66
			m_type = NodeType::Scalar;
67
68
69
			m_scalar = scalar;
		}

Jesse Beder's avatar
Jesse Beder committed
70
71
72
73
74
75
		// size/iterator
		std::size_t node_data::size() const
		{
			return 0;
		}
		
76
		const_node_iterator node_data::begin() const
Jesse Beder's avatar
Jesse Beder committed
77
78
		{
			switch(m_type) {
79
80
				case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
				case NodeType::Map: return const_node_iterator(m_map.begin());
81
				default: return const_node_iterator();
Jesse Beder's avatar
Jesse Beder committed
82
83
84
			}
		}
		
85
		node_iterator node_data::begin()
Jesse Beder's avatar
Jesse Beder committed
86
87
		{
			switch(m_type) {
88
89
				case NodeType::Sequence: return node_iterator(m_sequence.begin());
				case NodeType::Map: return node_iterator(m_map.begin());
90
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
91
92
93
			}
		}
		
94
		const_node_iterator node_data::end() const
Jesse Beder's avatar
Jesse Beder committed
95
96
		{
			switch(m_type) {
97
98
				case NodeType::Sequence: return const_node_iterator(m_sequence.end());
				case NodeType::Map: return const_node_iterator(m_map.end());
99
				default: return const_node_iterator();
Jesse Beder's avatar
Jesse Beder committed
100
101
102
			}
		}
		
103
		node_iterator node_data::end()
Jesse Beder's avatar
Jesse Beder committed
104
105
		{
			switch(m_type) {
106
107
				case NodeType::Sequence: return node_iterator(m_sequence.end());
				case NodeType::Map: return node_iterator(m_map.end());
108
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
109
110
111
112
			}
		}

		// sequence
Jesse Beder's avatar
Jesse Beder committed
113
114
		void node_data::append(node& node, shared_memory_holder /* pMemory */)
		{
115
116
117
118
119
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Sequence;
				m_sequence.clear();
			}
			
120
			if(m_type != NodeType::Sequence)
Jesse Beder's avatar
Jesse Beder committed
121
122
123
124
125
				throw std::runtime_error("Can't append to a non-sequence node");
			
			m_sequence.push_back(&node);
		}

126
		void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
127
		{
128
129
130
131
132
133
134
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Map;
				m_map.clear();
			} else if(m_type == NodeType::Sequence) {
				convert_sequence_to_map(pMemory);
			}

135
			if(m_type != NodeType::Map)
136
137
138
139
140
				throw std::runtime_error("Can't insert into a non-map node");

			m_map.push_back(kv_pair(&key, &value));
		}

141
		// indexing
142
		node& node_data::get(node& key, shared_memory_holder pMemory) const
143
		{
144
			if(m_type != NodeType::Map)
145
				return pMemory->create_node();
146
147
			
			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
148
				if(it->first->is(key))
149
					return *it->second;
150
151
			}
			
152
			return pMemory->create_node();
153
154
		}
		
155
		node& node_data::get(node& key, shared_memory_holder pMemory)
156
157
		{
			switch(m_type) {
158
159
160
161
				case NodeType::Undefined:
				case NodeType::Null:
				case NodeType::Scalar:
					m_type = NodeType::Map;
162
163
					m_map.clear();
					break;
164
				case NodeType::Sequence:
165
					convert_sequence_to_map(pMemory);
166
					break;
167
				case NodeType::Map:
168
169
170
171
					break;
			}

			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
172
				if(it->first->is(key))
173
					return *it->second;
174
175
			}
			
176
177
178
			node& value = pMemory->create_node();
			m_map.push_back(kv_pair(&key, &value));
			return value;
179
180
		}
		
181
		bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
182
		{
183
			if(m_type != NodeType::Map)
184
185
186
				return false;

			for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
187
				if(it->first->is(key)) {
188
189
190
191
192
193
194
195
					m_map.erase(it);
					return true;
				}
			}
			
			return false;
		}

196
		void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
197
		{
198
			assert(m_type == NodeType::Sequence);
199
200
201
202
203
204
			
			m_map.clear();
			for(std::size_t i=0;i<m_sequence.size();i++) {
				std::stringstream stream;
				stream << i;

205
206
207
				node& key = pMemory->create_node();
				key.set_scalar(stream.str());
				m_map.push_back(kv_pair(&key, m_sequence[i]));
208
209
210
			}
			
			m_sequence.clear();
211
			m_type = NodeType::Map;
212
		}
Jesse Beder's avatar
Jesse Beder committed
213
214
	}
}