node_data.cpp 6.37 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), m_seqSize(0)
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
					reset_sequence();
47
					break;
48
				case NodeType::Map:
49
					reset_map();
50
					break;
51
				case NodeType::Undefined:
52
53
54
55
56
					assert(false);
					break;
			}
		}

Jesse Beder's avatar
Jesse Beder committed
57
58
59
60
61
		void node_data::set_tag(const std::string& tag)
		{
			m_tag = tag;
		}
		
62
63
64
		void node_data::set_null()
		{
			m_isDefined = true;
65
			m_type = NodeType::Null;
66
67
68
69
70
		}
		
		void node_data::set_scalar(const std::string& scalar)
		{
			m_isDefined = true;
71
			m_type = NodeType::Scalar;
72
73
74
			m_scalar = scalar;
		}

Jesse Beder's avatar
Jesse Beder committed
75
76
77
		// size/iterator
		std::size_t node_data::size() const
		{
78
79
80
81
82
			if(!m_isDefined)
				return 0;

			switch(m_type) {
				case NodeType::Sequence: compute_seq_size(); return m_seqSize;
83
				case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size();
84
85
86
				default:
					return 0;
			}
Jesse Beder's avatar
Jesse Beder committed
87
88
89
			return 0;
		}
		
90
91
92
93
94
95
96
97
		void node_data::compute_seq_size() const
		{
			while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
				m_seqSize++;
		}

		void node_data::compute_map_size() const
		{
98
99
100
101
102
103
104
			kv_pairs::iterator it = m_undefinedPairs.begin();
			while(it != m_undefinedPairs.end()) {
				kv_pairs::iterator jt = boost::next(it);
				if(it->first->is_defined() && it->second->is_defined())
					m_undefinedPairs.erase(it);
				it = jt;
			}
105
106
		}
		
107
		const_node_iterator node_data::begin() const
Jesse Beder's avatar
Jesse Beder committed
108
		{
109
110
111
			if(!m_isDefined)
				return const_node_iterator();
			
Jesse Beder's avatar
Jesse Beder committed
112
			switch(m_type) {
113
				case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
114
				case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end());
115
				default: return const_node_iterator();
Jesse Beder's avatar
Jesse Beder committed
116
117
118
			}
		}
		
119
		node_iterator node_data::begin()
Jesse Beder's avatar
Jesse Beder committed
120
		{
121
122
123
			if(!m_isDefined)
				return node_iterator();

Jesse Beder's avatar
Jesse Beder committed
124
			switch(m_type) {
125
				case NodeType::Sequence: return node_iterator(m_sequence.begin());
126
				case NodeType::Map: return node_iterator(m_map.begin(), m_map.end());
127
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
128
129
130
			}
		}
		
131
		const_node_iterator node_data::end() const
Jesse Beder's avatar
Jesse Beder committed
132
		{
133
134
135
			if(!m_isDefined)
				return const_node_iterator();

Jesse Beder's avatar
Jesse Beder committed
136
			switch(m_type) {
137
				case NodeType::Sequence: return const_node_iterator(m_sequence.end());
138
				case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end());
139
				default: return const_node_iterator();
Jesse Beder's avatar
Jesse Beder committed
140
141
142
			}
		}
		
143
		node_iterator node_data::end()
Jesse Beder's avatar
Jesse Beder committed
144
		{
145
146
147
			if(!m_isDefined)
				return node_iterator();

Jesse Beder's avatar
Jesse Beder committed
148
			switch(m_type) {
149
				case NodeType::Sequence: return node_iterator(m_sequence.end());
150
				case NodeType::Map: return node_iterator(m_map.end(), m_map.end());
151
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
152
153
154
155
			}
		}

		// sequence
Jesse Beder's avatar
Jesse Beder committed
156
157
		void node_data::append(node& node, shared_memory_holder /* pMemory */)
		{
158
159
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Sequence;
160
				reset_sequence();
161
162
			}
			
163
			if(m_type != NodeType::Sequence)
Jesse Beder's avatar
Jesse Beder committed
164
165
166
167
168
				throw std::runtime_error("Can't append to a non-sequence node");
			
			m_sequence.push_back(&node);
		}

169
		void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
170
		{
171
172
173
174
175
176
177
178
179
180
			switch(m_type) {
				case NodeType::Map:
					break;
				case NodeType::Undefined:
				case NodeType::Null:
				case NodeType::Sequence:
					convert_to_map(pMemory);
					break;
				case NodeType::Scalar:
					throw std::runtime_error("Can't call operator[] on a scalar");
181
182
			}

183
			insert_map_pair(key, value);
184
185
		}

186
		// indexing
187
		node& node_data::get(node& key, shared_memory_holder pMemory) const
188
		{
189
			if(m_type != NodeType::Map)
190
				return pMemory->create_node();
191
192
			
			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
193
				if(it->first->is(key))
194
					return *it->second;
195
196
			}
			
197
			return pMemory->create_node();
198
199
		}
		
200
		node& node_data::get(node& key, shared_memory_holder pMemory)
201
202
		{
			switch(m_type) {
203
204
				case NodeType::Map:
					break;
205
206
207
				case NodeType::Undefined:
				case NodeType::Null:
				case NodeType::Sequence:
208
					convert_to_map(pMemory);
209
					break;
210
211
				case NodeType::Scalar:
					throw std::runtime_error("Can't call operator[] on a scalar");
212
213
214
			}

			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
215
				if(it->first->is(key))
216
					return *it->second;
217
218
			}
			
219
			node& value = pMemory->create_node();
220
			insert_map_pair(key, value);
221
			return value;
222
223
		}
		
224
		bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
225
		{
226
			if(m_type != NodeType::Map)
227
228
229
				return false;

			for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
230
				if(it->first->is(key)) {
231
232
233
234
235
236
237
238
					m_map.erase(it);
					return true;
				}
			}
			
			return false;
		}

239
240
241
242
243
244
245
246
247
		void node_data::reset_sequence()
		{
			m_sequence.clear();
			m_seqSize = 0;
		}

		void node_data::reset_map()
		{
			m_map.clear();
248
249
250
251
252
253
254
255
			m_undefinedPairs.clear();
		}

		void node_data::insert_map_pair(node& key, node& value)
		{
			m_map[&key] = &value;
			if(!key.is_defined() || !value.is_defined())
				m_undefinedPairs.push_back(kv_pair(&key, &value));
256
257
		}

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
		void node_data::convert_to_map(shared_memory_holder pMemory)
		{
			switch(m_type) {
				case NodeType::Undefined:
				case NodeType::Null:
					reset_map();
					m_type = NodeType::Map;
					break;
				case NodeType::Sequence:
					convert_sequence_to_map(pMemory);
					break;
				case NodeType::Map:
					break;
				case NodeType::Scalar:
					assert(false);
					break;
			}
		}

277
		void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
278
		{
279
			assert(m_type == NodeType::Sequence);
280
281

			reset_map();
282
283
284
285
			for(std::size_t i=0;i<m_sequence.size();i++) {
				std::stringstream stream;
				stream << i;

286
287
				node& key = pMemory->create_node();
				key.set_scalar(stream.str());
288
				insert_map_pair(key, *m_sequence[i]);
289
290
			}
			
291
			reset_sequence();
292
			m_type = NodeType::Map;
293
		}
Jesse Beder's avatar
Jesse Beder committed
294
295
	}
}