169 |
181 |
170 // Graph reader |
182 // Graph reader |
171 |
183 |
172 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
184 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
173 class GraphReader { |
185 class GraphReader { |
174 |
|
175 public: |
186 public: |
176 |
187 |
177 typedef _Graph Graph; |
188 typedef _Graph Graph; |
178 typedef typename Graph::Node Node; |
189 typedef typename Graph::Node Node; |
179 typedef typename Graph::Edge Edge; |
190 typedef typename Graph::Edge Edge; |
180 |
191 |
181 typedef _ReaderTraits ReaderTraits; |
192 typedef _ReaderTraits ReaderTraits; |
182 typedef typename ReaderTraits::DefaultReader DefaultReader; |
193 typedef typename ReaderTraits::DefaultReader DefaultReader; |
183 |
194 |
184 GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) |
195 GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) |
185 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
196 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
186 |
197 |
187 |
198 |
188 ~GraphReader() { |
199 ~GraphReader() { |
189 |
200 |
190 for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) { |
201 for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) { |
191 delete it->second; |
202 delete it->second; |
192 } |
203 } |
193 |
204 |
194 for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) { |
205 for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) { |
195 delete it->second; |
206 delete it->second; |
196 } |
207 } |
197 |
208 |
198 } |
209 } |
|
210 |
|
211 // Node map rules |
199 |
212 |
200 template <typename Map> |
213 template <typename Map> |
201 GraphReader& readNodeMap(std::string name, Map& map) { |
214 GraphReader& readNodeMap(std::string name, Map& map) { |
202 return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
215 return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
203 } |
216 } |
204 |
217 |
205 template <typename Reader, typename Map> |
218 template <typename Reader, typename Map> |
206 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
219 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
207 if (node_readers.find(name) != node_readers.end()) { |
220 if (node_map_readers.find(name) != node_map_readers.end()) { |
208 Exception e; |
221 throw Exception() << "Multiple read rule for node map: " << name; |
209 e << "Multiple read rule for node map: " << name; |
222 } |
210 throw e; |
223 node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
211 } |
|
212 node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
|
213 return *this; |
224 return *this; |
214 } |
225 } |
215 |
226 |
216 template <typename Reader> |
227 template <typename Reader> |
217 GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { |
228 GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { |
218 if (node_readers.find(name) != node_readers.end()) { |
229 if (node_map_readers.find(name) != node_map_readers.end()) { |
219 Exception e; |
230 throw Exception() << "Multiple read rule for node map: " << name; |
220 e << "Multiple read rule for node map: " << name; |
231 } |
221 throw e; |
232 node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |
222 } |
|
223 node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |
|
224 return *this; |
233 return *this; |
225 } |
234 } |
|
235 |
|
236 // Edge map rules |
226 |
237 |
227 template <typename Map> |
238 template <typename Map> |
228 GraphReader& readEdgeMap(std::string name, Map& map) { |
239 GraphReader& readEdgeMap(std::string name, Map& map) { |
229 return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
240 return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
230 } |
241 } |
231 |
242 |
232 |
243 |
233 template <typename Reader, typename Map> |
244 template <typename Reader, typename Map> |
234 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
245 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
235 if (edge_readers.find(name) != edge_readers.end()) { |
246 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
236 Exception e; |
247 throw Exception() << "Multiple read rule for edge map: " << name; |
237 e << "Multiple read rule for edge map: " << name; |
248 } |
238 throw e; |
249 edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
239 } |
|
240 edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
|
241 return *this; |
250 return *this; |
242 } |
251 } |
243 |
252 |
244 template <typename Reader> |
253 template <typename Reader> |
245 GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { |
254 GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { |
|
255 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
|
256 throw Exception() << "Multiple read rule for edge map: " << name; |
|
257 } |
|
258 edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |
|
259 return *this; |
|
260 } |
|
261 |
|
262 // Node rules |
|
263 GraphReader& readNode(std::string name, Node& node) { |
|
264 if (node_readers.find(name) != node_readers.end()) { |
|
265 throw Exception() << "Multiple read rule for node"; |
|
266 } |
|
267 node_readers.insert(make_pair(name, &node)); |
|
268 } |
|
269 |
|
270 // Edge rules |
|
271 |
|
272 GraphReader& readEdge(std::string name, Edge& edge) { |
246 if (edge_readers.find(name) != edge_readers.end()) { |
273 if (edge_readers.find(name) != edge_readers.end()) { |
247 Exception e; |
274 throw Exception() << "Multiple read rule for edge"; |
248 e << "Multiple read rule for edge map: " << name; |
275 } |
249 throw e; |
276 edge_readers.insert(make_pair(name, &edge)); |
250 } |
|
251 edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |
|
252 return *this; |
|
253 } |
277 } |
254 |
278 |
255 void read() { |
279 void read() { |
256 int line_num = 0; |
280 int line_num = 0; |
257 InverterBase<Node>* nodeInverter = 0; |
281 std::auto_ptr<InverterBase<Node> > nodeInverter; |
258 InverterBase<Edge>* edgeInverter = 0; |
282 std::auto_ptr<InverterBase<Edge> > edgeInverter; |
259 // \todo delete the inverters |
283 try { |
260 // try { |
284 std::string line = readNotEmptyLine(is, line_num); |
261 { |
285 if (line.find("@nodeset") == 0) { |
262 std::string line = readNotEmptyLine(is, line_num); |
286 line = readNodeSet(line_num, nodeInverter); |
263 } |
287 } |
264 readNodeSet(line_num, nodeInverter); |
288 if (line.find("@edgeset") == 0) { |
265 readEdgeSet(line_num, edgeInverter, nodeInverter); |
289 line = readEdgeSet(line_num, edgeInverter, nodeInverter); |
266 // } catch (...){ |
290 } |
267 if (nodeInverter != 0) delete nodeInverter; |
291 if (line.find("@nodes") == 0) { |
268 if (edgeInverter != 0) delete edgeInverter; |
292 line = readNodes(line_num, nodeInverter); |
269 // } |
293 } |
|
294 if (line.find("@edges") == 0) { |
|
295 line = readEdges(line_num, edgeInverter); |
|
296 } |
|
297 if (line.find("@end") != 0) { |
|
298 throw DataFormatException("Invalid control sequence: " + line); |
|
299 } |
|
300 } catch (DataFormatException e) { |
|
301 throw StreamException<DataFormatException>(line_num, e); |
|
302 } |
270 } |
303 } |
271 |
304 |
272 private: |
305 private: |
273 |
306 |
274 template <typename Item> class InverterBase; |
307 template <typename Item> class InverterBase; |
275 // template <typename Item> class InverterBase; |
308 |
276 |
309 std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) { |
277 void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) { |
310 std::vector<ReaderBase<Node>* > index; |
278 int n = 0; |
|
279 std::vector<ReaderBase<Node>*> index; |
|
280 { |
311 { |
281 std::string line = readNotEmptyLine(is, line_num); |
312 std::string line = readNotEmptyLine(is, line_num); |
282 std::string id; |
313 std::string id; |
283 std::istringstream ls(line); |
314 std::istringstream ls(line); |
284 while (ls >> id) { |
315 while (ls >> id) { |
285 if (id[0] == '#') break; |
316 if (id[0] == '#') break; |
286 typename NodeReaders::iterator it = node_readers.find(id); |
317 typename NodeMapReaders::iterator it = node_map_readers.find(id); |
287 if (it != node_readers.end()) { |
318 if (it != node_map_readers.end()) { |
288 index.push_back(it->second); |
319 index.push_back(it->second); |
|
320 node_map_readers.erase(it); |
289 } else { |
321 } else { |
290 index.push_back(&nodeSkipper); |
322 index.push_back(&nodeSkipper); |
291 } |
323 } |
292 ++n; |
324 } |
293 } |
325 } |
294 } |
326 |
295 |
327 if (index.size() == 0) { |
296 nodeInverter = index[0]->getInverter(); |
328 throw DataFormatException("No node map found"); |
|
329 } |
|
330 |
|
331 nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter()); |
297 std::string line; |
332 std::string line; |
298 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
333 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
299 Node node = graph.addNode(); |
334 Node node = graph.addNode(); |
300 std::istringstream ls(line); |
335 std::istringstream ls(line); |
301 nodeInverter->read(ls, node); |
336 nodeInverter->read(ls, node); |
302 for (int i = 1; i < n; ++i) { |
337 for (int i = 1; i < index.size(); ++i) { |
303 index[i]->read(ls, node); |
338 index[i]->read(ls, node); |
304 } |
339 } |
305 } |
340 } |
306 } |
341 return line; |
307 |
342 } |
308 void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) { |
343 |
309 int n = 0; |
344 std::string readEdgeSet(int& line_num, |
|
345 auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) { |
310 std::vector<ReaderBase<Edge>*> index; |
346 std::vector<ReaderBase<Edge>*> index; |
311 { |
347 { |
312 std::string line = readNotEmptyLine(is, line_num); |
348 std::string line = readNotEmptyLine(is, line_num); |
313 std::string id; |
349 std::string id; |
314 std::istringstream ls(line); |
350 std::istringstream ls(line); |
315 while (ls >> id) { |
351 while (ls >> id) { |
316 if (id[0] == '#') break; |
352 if (id[0] == '#') break; |
317 typename EdgeReaders::iterator it = edge_readers.find(id); |
353 typename EdgeMapReaders::iterator it = edge_map_readers.find(id); |
318 if (it != edge_readers.end()) { |
354 if (it != edge_map_readers.end()) { |
319 index.push_back(it->second); |
355 index.push_back(it->second); |
|
356 edge_map_readers.erase(it); |
320 } else { |
357 } else { |
321 index.push_back(&edgeSkipper); |
358 index.push_back(&edgeSkipper); |
322 } |
359 } |
323 ++n; |
360 } |
324 } |
361 } |
325 } |
362 |
326 edgeInverter = index[0]->getInverter(); |
363 if (index.size() == 0) { |
|
364 throw DataFormatException("No edge map found"); |
|
365 } |
|
366 |
|
367 edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter()); |
327 std::string line; |
368 std::string line; |
328 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
369 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
329 std::istringstream ls(line); |
370 std::istringstream ls(line); |
330 Node source = nodeInverter->read(ls); |
371 Node source = nodeInverter->read(ls); |
331 Node target = nodeInverter->read(ls); |
372 Node target = nodeInverter->read(ls); |
332 Edge edge = graph.addEdge(source, target); |
373 Edge edge = graph.addEdge(source, target); |
333 edgeInverter->read(ls, edge); |
374 edgeInverter->read(ls, edge); |
334 for (int i = 1; i < n; ++i) { |
375 for (int i = 1; i < index.size(); ++i) { |
335 index[i]->read(ls, edge); |
376 index[i]->read(ls, edge); |
336 } |
377 } |
337 } |
378 } |
|
379 return line; |
|
380 } |
|
381 |
|
382 std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) { |
|
383 std::string line; |
|
384 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
|
385 std::istringstream ls(line); |
|
386 std::string name; |
|
387 ls >> name; |
|
388 typename NodeReaders::iterator it = node_readers.find(name); |
|
389 if (it != node_readers.end()) { |
|
390 *(it -> second) = nodeInverter->read(ls); |
|
391 } |
|
392 } |
|
393 return line; |
|
394 } |
|
395 |
|
396 std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) { |
|
397 std::string line; |
|
398 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
|
399 std::istringstream ls(line); |
|
400 std::string name; |
|
401 ls >> name; |
|
402 typename EdgeReaders::iterator it = edge_readers.find(name); |
|
403 if (it != edge_readers.end()) { |
|
404 *(it -> second) = edgeInverter->read(ls); |
|
405 } |
|
406 } |
|
407 return line; |
338 } |
408 } |
339 |
409 |
340 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
410 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
341 std::string line; |
411 std::string line; |
342 while (++line_num, getline(is, line)) { |
412 while (++line_num, getline(is, line)) { |
343 int vi = line.find_first_not_of(" \t"); |
413 int vi = line.find_first_not_of(" \t"); |
344 if (vi != string::npos && line[vi] != '#') { |
414 if (vi != string::npos && line[vi] != '#') { |
345 return line.substr(vi); |
415 return line.substr(vi); |
346 } |
416 } |
347 } |
417 } |
348 throw Exception(); |
418 throw DataFormatException("End of stream"); |
349 } |
419 } |
|
420 |
|
421 // Inverters store and give back the Item from the id, |
|
422 // and may put the ids into a map. |
350 |
423 |
351 template <typename _Item> |
424 template <typename _Item> |
352 class InverterBase { |
425 class InverterBase { |
353 public: |
426 public: |
354 typedef _Item Item; |
427 typedef _Item Item; |
355 virtual void read(istream&, const Item&) = 0; |
428 virtual void read(std::istream&, const Item&) = 0; |
356 virtual Item read(istream&) = 0; |
429 virtual Item read(std::istream&) = 0; |
357 }; |
430 }; |
358 |
431 |
359 template <typename _Item, typename _Map, typename _Reader> |
432 template <typename _Item, typename _Map, typename _Reader> |
360 class MapReaderInverter : public InverterBase<_Item> { |
433 class MapReaderInverter : public InverterBase<_Item> { |
361 public: |
434 public: |