node_data.cpp 4.22 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
			if(m_type != NodeType::Sequence)
Jesse Beder's avatar
Jesse Beder committed
109
110
111
112
113
				throw std::runtime_error("Can't append to a non-sequence node");
			
			m_sequence.push_back(&node);
		}

114
115
		void node_data::insert(node& key, node& value, shared_memory_holder /* pMemory */)
		{
116
			if(m_type != NodeType::Map)
117
118
119
120
121
				throw std::runtime_error("Can't insert into a non-map node");

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

122
		// indexing
123
		node& node_data::get(node& key, shared_memory_holder pMemory) const
124
		{
125
			if(m_type != NodeType::Map)
126
				return pMemory->create_node();
127
128
			
			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
129
				if(it->first->is(key))
130
					return *it->second;
131
132
			}
			
133
			return pMemory->create_node();
134
135
		}
		
136
		node& node_data::get(node& key, shared_memory_holder pMemory)
137
138
		{
			switch(m_type) {
139
140
141
142
				case NodeType::Undefined:
				case NodeType::Null:
				case NodeType::Scalar:
					m_type = NodeType::Map;
143
144
					m_map.clear();
					break;
145
				case NodeType::Sequence:
146
					convert_sequence_to_map(pMemory);
147
					break;
148
				case NodeType::Map:
149
150
151
152
					break;
			}

			for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
153
				if(it->first->is(key))
154
					return *it->second;
155
156
			}
			
157
158
159
			node& value = pMemory->create_node();
			m_map.push_back(kv_pair(&key, &value));
			return value;
160
161
		}
		
162
		bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
163
		{
164
			if(m_type != NodeType::Map)
165
166
167
				return false;

			for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
168
				if(it->first->is(key)) {
169
170
171
172
173
174
175
176
					m_map.erase(it);
					return true;
				}
			}
			
			return false;
		}

177
		void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
178
		{
179
			assert(m_type == NodeType::Sequence);
180
181
182
183
184
185
			
			m_map.clear();
			for(std::size_t i=0;i<m_sequence.size();i++) {
				std::stringstream stream;
				stream << i;

186
187
188
				node& key = pMemory->create_node();
				key.set_scalar(stream.str());
				m_map.push_back(kv_pair(&key, m_sequence[i]));
189
190
191
			}
			
			m_sequence.clear();
192
			m_type = NodeType::Map;
193
		}
Jesse Beder's avatar
Jesse Beder committed
194
195
	}
}