"...composable_kernel_rocm.git" did not exist on "08eb17692978f2af709deb59c98aae6db4c82b6b"
map.cpp 5.36 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
8
9
10
11
12

namespace YAML
{
	Map::Map()
	{
	}
jbeder's avatar
jbeder committed
13
14
15
16
17
18
	
	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();
19
			AddEntry(pKey, pValue);
jbeder's avatar
jbeder committed
20
21
		}
	}
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

	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
37
38
39
40
41
	Content *Map::Clone() const
	{
		return new Map(m_data);
	}
	
42
43
44
45
46
47
48
49
50
51
52
53
	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;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

131
132
133
134
135
136
			// grab key (if non-null)
			if(token.type == Token::KEY) {
				pScanner->pop();
				pKey->Parse(pScanner, state);
			}
			
137
			// now grab value (optional)
jbeder's avatar
jbeder committed
138
			if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
139
140
				pScanner->pop();
				pValue->Parse(pScanner, state);
141
			}
142
			
143
144
			// 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
145
			if(nextToken.type == Token::FLOW_ENTRY)
146
				pScanner->pop();
jbeder's avatar
jbeder committed
147
			else if(nextToken.type != Token::FLOW_MAP_END)
148
				throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
149

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

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

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

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

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

		AddEntry(pKey, pValue);
189
		state.PopCollectionType(ParserState::COMPACT_MAP);
190
191
	}
	
192
193
194
195
196
197
198
199
200
	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();
	}

201
	void Map::Write(Emitter& out) const
202
	{
203
204
205
206
		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;
207
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
	}

	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;
	}
}