"v1-inference.yaml" did not exist on "bb2c64a08c181b450afe61dd88b2f0a575bc414b"
map.cpp 5.38 KB
Newer Older
1
2
3
4
5
#include "map.h"
#include "node.h"
#include "scanner.h"
#include "token.h"
#include "exceptions.h"
6
#include "emitter.h"
7
#include <memory>
8
9
10
11
12
13

namespace YAML
{
	Map::Map()
	{
	}
jbeder's avatar
jbeder committed
14
15
16
17
18
19
	
	Map::Map(const node_map& data)
	{
		for(node_map::const_iterator it=data.begin();it!=data.end();++it) {
			std::auto_ptr<Node> pKey = it->first->Clone();
			std::auto_ptr<Node> pValue = it->second->Clone();
20
			AddEntry(pKey, pValue);
jbeder's avatar
jbeder committed
21
22
		}
	}
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

	Map::~Map()
	{
		Clear();
	}

	void Map::Clear()
	{
		for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
			delete it->first;
			delete it->second;
		}
		m_data.clear();
	}

jbeder's avatar
jbeder committed
38
39
40
41
42
	Content *Map::Clone() const
	{
		return new Map(m_data);
	}
	
43
44
45
46
47
48
49
50
51
52
53
54
	bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
	{
		it = m_data.begin();
		return true;
	}

	bool Map::GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const
	{
		it = m_data.end();
		return true;
	}

55
56
57
58
59
	std::size_t Map::GetSize() const
	{
		return m_data.size();
	}

60
	void Map::Parse(Scanner *pScanner, ParserState& state)
61
62
63
64
65
	{
		Clear();

		// split based on start token
		switch(pScanner->peek().type) {
jbeder's avatar
jbeder committed
66
67
			case Token::BLOCK_MAP_START: ParseBlock(pScanner, state); break;
			case Token::FLOW_MAP_START: ParseFlow(pScanner, state); break;
68
			case Token::KEY: ParseCompact(pScanner, state); break;
69
			case Token::VALUE: ParseCompactWithNoKey(pScanner, state); break;
jbeder's avatar
jbeder committed
70
			default: break;
71
72
73
		}
	}

74
	void Map::ParseBlock(Scanner *pScanner, ParserState& state)
75
76
77
	{
		// eat start token
		pScanner->pop();
78
		state.PushCollectionType(ParserState::BLOCK_MAP);
79
80
81

		while(1) {
			if(pScanner->empty())
82
				throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
83
84

			Token token = pScanner->peek();
jbeder's avatar
jbeder committed
85
			if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
86
				throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
87

jbeder's avatar
jbeder committed
88
			if(token.type == Token::BLOCK_MAP_END) {
jbeder's avatar
jbeder committed
89
				pScanner->pop();
90
				break;
jbeder's avatar
jbeder committed
91
			}
92

93
			std::auto_ptr <Node> pKey(new Node), pValue(new Node);
jbeder's avatar
jbeder committed
94
95
			
			// grab key (if non-null)
jbeder's avatar
jbeder committed
96
			if(token.type == Token::KEY) {
jbeder's avatar
jbeder committed
97
98
99
				pScanner->pop();
				pKey->Parse(pScanner, state);
			}
100

101
			// now grab value (optional)
jbeder's avatar
jbeder committed
102
			if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
103
104
				pScanner->pop();
				pValue->Parse(pScanner, state);
105
			}
106

107
			AddEntry(pKey, pValue);
108
		}
109
110

		state.PopCollectionType(ParserState::BLOCK_MAP);
111
112
	}

113
	void Map::ParseFlow(Scanner *pScanner, ParserState& state)
114
115
116
	{
		// eat start token
		pScanner->pop();
117
		state.PushCollectionType(ParserState::FLOW_MAP);
118
119
120

		while(1) {
			if(pScanner->empty())
121
				throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
122
123
124

			Token& token = pScanner->peek();
			// first check for end
jbeder's avatar
jbeder committed
125
			if(token.type == Token::FLOW_MAP_END) {
126
127
128
				pScanner->pop();
				break;
			}
129
			
130
131
			std::auto_ptr <Node> pKey(new Node), pValue(new Node);

132
133
134
135
136
137
			// grab key (if non-null)
			if(token.type == Token::KEY) {
				pScanner->pop();
				pKey->Parse(pScanner, state);
			}
			
138
			// now grab value (optional)
jbeder's avatar
jbeder committed
139
			if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
140
141
				pScanner->pop();
				pValue->Parse(pScanner, state);
142
			}
143
			
144
145
			// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
			Token& nextToken = pScanner->peek();
jbeder's avatar
jbeder committed
146
			if(nextToken.type == Token::FLOW_ENTRY)
147
				pScanner->pop();
jbeder's avatar
jbeder committed
148
			else if(nextToken.type != Token::FLOW_MAP_END)
149
				throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
150

151
			AddEntry(pKey, pValue);
152
		}
153
154

		state.PopCollectionType(ParserState::FLOW_MAP);
155
156
	}

157
	// ParseCompact
158
	// . Single "key: value" pair in a flow sequence
159
	void Map::ParseCompact(Scanner *pScanner, ParserState& state)
160
	{
161
		state.PushCollectionType(ParserState::COMPACT_MAP);
162
163
		std::auto_ptr <Node> pKey(new Node), pValue(new Node);

164
165
166
		// grab key
		pScanner->pop();
		pKey->Parse(pScanner, state);
167
168
169
170
171
172
173
			
		// now grab value (optional)
		if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
			pScanner->pop();
			pValue->Parse(pScanner, state);
		}
			
174
		AddEntry(pKey, pValue);
175
		state.PopCollectionType(ParserState::COMPACT_MAP);
176
177
	}
	
178
	// ParseCompactWithNoKey
179
	// . Single ": value" pair in a flow sequence
180
	void Map::ParseCompactWithNoKey(Scanner *pScanner, ParserState& state)
181
	{
182
		state.PushCollectionType(ParserState::COMPACT_MAP);
183
184
185
186
187
		std::auto_ptr <Node> pKey(new Node), pValue(new Node);

		// grab value
		pScanner->pop();
		pValue->Parse(pScanner, state);
188
189

		AddEntry(pKey, pValue);
190
		state.PopCollectionType(ParserState::COMPACT_MAP);
191
192
	}
	
193
194
195
196
197
198
199
200
201
	void Map::AddEntry(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue)
	{
		node_map::const_iterator it = m_data.find(pKey.get());
		if(it != m_data.end())
			return;
		
		m_data[pKey.release()] = pValue.release();
	}

202
	void Map::Write(Emitter& out) const
203
	{
204
205
206
207
		out << BeginMap;
		for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it)
			out << Key << *it->first << Value << *it->second;
		out << EndMap;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
	}

	int Map::Compare(Content *pContent)
	{
		return -pContent->Compare(this);
	}

	int Map::Compare(Map *pMap)
	{
		node_map::const_iterator it = m_data.begin(), jt = pMap->m_data.begin();
		while(1) {
			if(it == m_data.end()) {
				if(jt == pMap->m_data.end())
					return 0;
				else
					return -1;
			}
			if(jt == pMap->m_data.end())
				return 1;

			int cmp = it->first->Compare(*jt->first);
			if(cmp != 0)
				return cmp;

			cmp = it->second->Compare(*jt->second);
			if(cmp != 0)
				return cmp;
		}

		return 0;
	}
}