node_data.cpp 4.54 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
		void node_data::set_type(NodeType::value type)
18
		{
19
			if(type == NodeType::Undefined) {
20
21
22
23
24
25
26
27
28
29
30
31
32
				m_type = type;
				m_isDefined = false;
				return;
			}
			

			m_isDefined = true;
			if(type == m_type)
				return;
			
			m_type = type;
			
			switch(m_type) {
33
				case NodeType::Null:
34
					break;
35
				case NodeType::Scalar:
36
37
					m_scalar.clear();
					break;
38
				case NodeType::Sequence:
39
40
					m_sequence.clear();
					break;
41
				case NodeType::Map:
42
43
					m_map.clear();
					break;
44
				case NodeType::Undefined:
45
46
47
48
49
50
51
52
					assert(false);
					break;
			}
		}

		void node_data::set_null()
		{
			m_isDefined = true;
53
			m_type = NodeType::Null;
54
55
56
57
58
		}
		
		void node_data::set_scalar(const std::string& scalar)
		{
			m_isDefined = true;
59
			m_type = NodeType::Scalar;
60
61
62
			m_scalar = scalar;
		}

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

		// sequence
Jesse Beder's avatar
Jesse Beder committed
106
107
		void node_data::append(node& node, shared_memory_holder /* pMemory */)
		{
108
109
110
111
112
			if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
				m_type = NodeType::Sequence;
				m_sequence.clear();
			}
			
113
			if(m_type != NodeType::Sequence)
Jesse Beder's avatar
Jesse Beder committed
114
115
116
117
118
				throw std::runtime_error("Can't append to a non-sequence node");
			
			m_sequence.push_back(&node);
		}

119
		void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
120
		{
121
122
123
124
125
126
127
			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);
			}

128
			if(m_type != NodeType::Map)
129
130
131
132
133
				throw std::runtime_error("Can't insert into a non-map node");

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

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

			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
165
				if(it->first->is(key))
166
					return *it->second;
167
168
			}
			
169
170
171
			node& value = pMemory->create_node();
			m_map.push_back(kv_pair(&key, &value));
			return value;
172
173
		}
		
174
		bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
175
		{
176
			if(m_type != NodeType::Map)
177
178
179
				return false;

			for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
180
				if(it->first->is(key)) {
181
182
183
184
185
186
187
188
					m_map.erase(it);
					return true;
				}
			}
			
			return false;
		}

189
		void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
190
		{
191
			assert(m_type == NodeType::Sequence);
192
193
194
195
196
197
			
			m_map.clear();
			for(std::size_t i=0;i<m_sequence.size();i++) {
				std::stringstream stream;
				stream << i;

198
199
200
				node& key = pMemory->create_node();
				key.set_scalar(stream.str());
				m_map.push_back(kv_pair(&key, m_sequence[i]));
201
202
203
			}
			
			m_sequence.clear();
204
			m_type = NodeType::Map;
205
		}
Jesse Beder's avatar
Jesse Beder committed
206
207
	}
}