node_data.cpp 4.35 KB
Newer Older
Jesse Beder's avatar
Jesse Beder committed
1
#include "yaml-cpp/value/detail/node_data.h"
2
#include "yaml-cpp/value/detail/memory.h"
3
4
#include "yaml-cpp/value/detail/node.h"
#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(ValueType::Null)
Jesse Beder's avatar
Jesse Beder committed
14
15
		{
		}
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

		void node_data::set_type(ValueType::value type)
		{
			if(type == ValueType::Undefined) {
				m_type = type;
				m_isDefined = false;
				return;
			}
			

			m_isDefined = true;
			if(type == m_type)
				return;
			
			m_type = type;
			
			switch(m_type) {
				case ValueType::Null:
					break;
				case ValueType::Scalar:
					m_scalar.clear();
					break;
				case ValueType::Sequence:
					m_sequence.clear();
					break;
				case ValueType::Map:
					m_map.clear();
					break;
				case ValueType::Undefined:
					assert(false);
					break;
			}
		}

		void node_data::set_null()
		{
			m_isDefined = true;
			m_type = ValueType::Null;
		}
		
		void node_data::set_scalar(const std::string& scalar)
		{
			m_isDefined = true;
			m_type = ValueType::Scalar;
			m_scalar = scalar;
		}

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

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

114
115
116
117
118
119
120
121
		void node_data::insert(node& key, node& value, shared_memory_holder /* pMemory */)
		{
			if(m_type != ValueType::Map)
				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 != ValueType::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
139
140
141
142
143
144
145
		{
			switch(m_type) {
				case ValueType::Undefined:
				case ValueType::Null:
				case ValueType::Scalar:
					m_type = ValueType::Map;
					m_map.clear();
					break;
				case ValueType::Sequence:
146
					convert_sequence_to_map(pMemory);
147
148
149
150
151
152
					break;
				case ValueType::Map:
					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
165
166
167
		{
			if(m_type != ValueType::Map)
				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
180
181
182
183
184
185
		{
			assert(m_type == ValueType::Sequence);
			
			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
192
193
			}
			
			m_sequence.clear();
			m_type = ValueType::Map;
		}
Jesse Beder's avatar
Jesse Beder committed
194
195
	}
}