node_data.cpp 5.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
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
		// size/iterator
		std::size_t node_data::size() const
		{
73
74
75
76
77
78
79
80
81
			if(!m_isDefined)
				return 0;

			switch(m_type) {
				case NodeType::Sequence: compute_seq_size(); return m_seqSize;
				case NodeType::Map: compute_map_size(); return m_map.size();
				default:
					return 0;
			}
Jesse Beder's avatar
Jesse Beder committed
82
83
84
			return 0;
		}
		
85
86
87
88
89
90
91
92
93
94
		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
		{
		}
		
95
		const_node_iterator node_data::begin() const
Jesse Beder's avatar
Jesse Beder committed
96
		{
97
98
99
			if(!m_isDefined)
				return const_node_iterator();
			
Jesse Beder's avatar
Jesse Beder committed
100
			switch(m_type) {
101
102
				case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
				case NodeType::Map: return const_node_iterator(m_map.begin());
103
				default: return const_node_iterator();
Jesse Beder's avatar
Jesse Beder committed
104
105
106
			}
		}
		
107
		node_iterator node_data::begin()
Jesse Beder's avatar
Jesse Beder committed
108
		{
109
110
111
			if(!m_isDefined)
				return node_iterator();

Jesse Beder's avatar
Jesse Beder committed
112
			switch(m_type) {
113
114
				case NodeType::Sequence: return node_iterator(m_sequence.begin());
				case NodeType::Map: return node_iterator(m_map.begin());
115
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
116
117
118
			}
		}
		
119
		const_node_iterator node_data::end() const
Jesse Beder's avatar
Jesse Beder committed
120
		{
121
122
123
			if(!m_isDefined)
				return const_node_iterator();

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

Jesse Beder's avatar
Jesse Beder committed
136
			switch(m_type) {
137
138
				case NodeType::Sequence: return node_iterator(m_sequence.end());
				case NodeType::Map: return node_iterator(m_map.end());
139
				default: return node_iterator();
Jesse Beder's avatar
Jesse Beder committed
140
141
142
143
			}
		}

		// sequence
Jesse Beder's avatar
Jesse Beder committed
144
145
		void node_data::append(node& node, shared_memory_holder /* pMemory */)
		{
146
147
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Sequence;
148
				reset_sequence();
149
150
			}
			
151
			if(m_type != NodeType::Sequence)
Jesse Beder's avatar
Jesse Beder committed
152
153
154
155
156
				throw std::runtime_error("Can't append to a non-sequence node");
			
			m_sequence.push_back(&node);
		}

157
		void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
158
		{
159
160
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Map;
161
				reset_map();
162
163
164
165
			} else if(m_type == NodeType::Sequence) {
				convert_sequence_to_map(pMemory);
			}

166
			if(m_type != NodeType::Map)
167
168
				throw std::runtime_error("Can't insert into a non-map node");

169
			m_map[&key] = &value;
170
171
		}

172
		// indexing
173
		node& node_data::get(node& key, shared_memory_holder pMemory) const
174
		{
175
			if(m_type != NodeType::Map)
176
				return pMemory->create_node();
177
178
			
			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
179
				if(it->first->is(key))
180
					return *it->second;
181
182
			}
			
183
			return pMemory->create_node();
184
185
		}
		
186
		node& node_data::get(node& key, shared_memory_holder pMemory)
187
188
		{
			switch(m_type) {
189
190
191
192
				case NodeType::Undefined:
				case NodeType::Null:
				case NodeType::Scalar:
					m_type = NodeType::Map;
193
					reset_map();
194
					break;
195
				case NodeType::Sequence:
196
					convert_sequence_to_map(pMemory);
197
					break;
198
				case NodeType::Map:
199
200
201
202
					break;
			}

			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
203
				if(it->first->is(key))
204
					return *it->second;
205
206
			}
			
207
			node& value = pMemory->create_node();
208
			m_map[&key] = &value;
209
			return value;
210
211
		}
		
212
		bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
213
		{
214
			if(m_type != NodeType::Map)
215
216
217
				return false;

			for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
218
				if(it->first->is(key)) {
219
220
221
222
223
224
225
226
					m_map.erase(it);
					return true;
				}
			}
			
			return false;
		}

227
228
229
230
231
232
233
234
235
236
237
		void node_data::reset_sequence()
		{
			m_sequence.clear();
			m_seqSize = 0;
		}

		void node_data::reset_map()
		{
			m_map.clear();
		}

238
		void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
239
		{
240
			assert(m_type == NodeType::Sequence);
241
242

			reset_map();
243
244
245
246
			for(std::size_t i=0;i<m_sequence.size();i++) {
				std::stringstream stream;
				stream << i;

247
248
				node& key = pMemory->create_node();
				key.set_scalar(stream.str());
249
				m_map[&key] = m_sequence[i];
250
251
			}
			
252
			reset_sequence();
253
			m_type = NodeType::Map;
254
		}
Jesse Beder's avatar
Jesse Beder committed
255
256
	}
}