changeset 1115 | 444f69240539 |
parent 1037 | 3eaff8d04171 |
child 1133 | 9fd485470fee |
2:9c1cd501315a | 3:1bc79fcb3372 |
---|---|
35 |
35 |
36 // Exceptions |
36 // Exceptions |
37 |
37 |
38 class IOException { |
38 class IOException { |
39 public: |
39 public: |
40 virtual ~IOException() {} |
|
40 virtual string what() const = 0; |
41 virtual string what() const = 0; |
41 }; |
42 }; |
42 |
43 |
43 class DataFormatException : public IOException { |
44 class DataFormatException : public IOException { |
44 std::string message; |
45 std::string message; |
53 template <typename _Exception> |
54 template <typename _Exception> |
54 class StreamException : public _Exception { |
55 class StreamException : public _Exception { |
55 public: |
56 public: |
56 typedef _Exception Exception; |
57 typedef _Exception Exception; |
57 StreamException(int _line, Exception _exception) |
58 StreamException(int _line, Exception _exception) |
58 : line_num(_line), Exception(_exception) {} |
59 : Exception(_exception), line_num(_line) {} |
59 virtual int line() const { |
60 virtual int line() const { |
60 return line_num; |
61 return line_num; |
61 } |
62 } |
63 |
|
64 virtual ~StreamException() {} |
|
65 |
|
62 virtual std::string what() const { |
66 virtual std::string what() const { |
63 ostringstream os; |
67 ostringstream os; |
64 os << Exception::what() << " in line " << line(); |
68 os << Exception::what() << " in line " << line(); |
65 return os.str(); |
69 return os.str(); |
66 } |
70 } |
68 int line_num; |
72 int line_num; |
69 }; |
73 }; |
70 |
74 |
71 |
75 |
72 // Readers and ReaderTraits |
76 // Readers and ReaderTraits |
73 |
77 /// \brief Standard ReaderTraits for the GraphReader class. |
78 /// |
|
79 /// |
|
80 |
|
74 struct DefaultReaderTraits { |
81 struct DefaultReaderTraits { |
75 |
82 |
76 template <typename _Value> |
83 template <typename _Value> |
77 struct Reader { |
84 struct Reader { |
78 typedef _Value Value; |
85 typedef _Value Value; |
94 |
101 |
95 void read(std::istream& is, std::string& value) { |
102 void read(std::istream& is, std::string& value) { |
96 char c; |
103 char c; |
97 value.clear(); |
104 value.clear(); |
98 is >> ws; |
105 is >> ws; |
99 if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format"); |
106 if (!is.get(c) || c != '\"') |
107 throw DataFormatException("Quoted string format"); |
|
100 while (is.get(c) && c != '\"') { |
108 while (is.get(c) && c != '\"') { |
101 if (escaped && c == '\\') { |
109 if (escaped && c == '\\') { |
102 value += readEscape(is); |
110 value += readEscape(is); |
103 } else { |
111 } else { |
104 value += c; |
112 value += c; |
190 typedef typename Graph::Edge Edge; |
198 typedef typename Graph::Edge Edge; |
191 |
199 |
192 typedef _ReaderTraits ReaderTraits; |
200 typedef _ReaderTraits ReaderTraits; |
193 typedef typename ReaderTraits::DefaultReader DefaultReader; |
201 typedef typename ReaderTraits::DefaultReader DefaultReader; |
194 |
202 |
195 GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) |
203 GraphReader(std::istream& _is, Graph& _graph, |
204 const DefaultReader& _reader = DefaultReader()) |
|
196 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
205 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
197 |
206 |
198 |
207 |
199 ~GraphReader() { |
208 ~GraphReader() { |
200 |
209 |
201 for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) { |
210 for (typename NodeMapReaders::iterator it = node_map_readers.begin(); |
211 it != node_map_readers.end(); ++it) { |
|
202 delete it->second; |
212 delete it->second; |
203 } |
213 } |
204 |
214 |
205 for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) { |
215 for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); |
216 it != edge_map_readers.end(); ++it) { |
|
206 delete it->second; |
217 delete it->second; |
207 } |
218 } |
208 |
219 |
209 } |
220 } |
210 |
221 |
211 // Node map rules |
222 // Node map rules |
212 |
223 |
213 template <typename Map> |
224 template <typename Map> |
214 GraphReader& readNodeMap(std::string name, Map& map) { |
225 GraphReader& addNodeMap(std::string name, Map& map) { |
215 return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
226 return addNodeMap<typename ReaderTraits::template |
227 Reader<typename Map::Value>, Map>(name, map); |
|
216 } |
228 } |
217 |
229 |
218 template <typename Reader, typename Map> |
230 template <typename Reader, typename Map> |
219 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
231 GraphReader& addNodeMap(std::string name, Map& map, |
232 const Reader& reader = Reader()) { |
|
220 if (node_map_readers.find(name) != node_map_readers.end()) { |
233 if (node_map_readers.find(name) != node_map_readers.end()) { |
221 throw Exception() << "Multiple read rule for node map: " << name; |
234 throw Exception() << "Multiple read rule for node map: " << name; |
222 } |
235 } |
223 node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
236 node_map_readers.insert( |
237 make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
|
224 return *this; |
238 return *this; |
225 } |
239 } |
226 |
240 |
227 template <typename Reader> |
241 template <typename Reader> |
228 GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { |
242 GraphReader& skipNodeMap(std::string name, |
243 const Reader& reader = Reader()) { |
|
229 if (node_map_readers.find(name) != node_map_readers.end()) { |
244 if (node_map_readers.find(name) != node_map_readers.end()) { |
230 throw Exception() << "Multiple read rule for node map: " << name; |
245 throw Exception() << "Multiple read rule for node map: " << name; |
231 } |
246 } |
232 node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |
247 node_map_readers.insert( |
248 make_pair(name, new SkipReader<Node, Reader>(reader))); |
|
233 return *this; |
249 return *this; |
234 } |
250 } |
235 |
251 |
236 // Edge map rules |
252 // Edge map rules |
237 |
253 |
238 template <typename Map> |
254 template <typename Map> |
239 GraphReader& readEdgeMap(std::string name, Map& map) { |
255 GraphReader& addEdgeMap(std::string name, Map& map) { |
240 return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
256 return addEdgeMap<typename ReaderTraits::template |
257 Reader<typename Map::Value>, Map>(name, map); |
|
241 } |
258 } |
242 |
259 |
243 |
260 |
244 template <typename Reader, typename Map> |
261 template <typename Reader, typename Map> |
245 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
262 GraphReader& addEdgeMap(std::string name, Map& map, |
263 const Reader& reader = Reader()) { |
|
246 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
264 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
247 throw Exception() << "Multiple read rule for edge map: " << name; |
265 throw Exception() << "Multiple read rule for edge map: " << name; |
248 } |
266 } |
249 edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
267 edge_map_readers.insert( |
268 make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
|
250 return *this; |
269 return *this; |
251 } |
270 } |
252 |
271 |
253 template <typename Reader> |
272 template <typename Reader> |
254 GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { |
273 GraphReader& skipEdgeMap(std::string name, |
274 const Reader& reader = Reader()) { |
|
255 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
275 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
256 throw Exception() << "Multiple read rule for edge map: " << name; |
276 throw Exception() << "Multiple read rule for edge map: " << name; |
257 } |
277 } |
258 edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |
278 edge_map_readers.insert( |
279 make_pair(name, new SkipReader<Edge, Reader>(reader))); |
|
259 return *this; |
280 return *this; |
260 } |
281 } |
261 |
282 |
262 // Node rules |
283 // Node rules |
263 GraphReader& readNode(std::string name, Node& node) { |
284 GraphReader& addNode(std::string name, Node& node) { |
264 if (node_readers.find(name) != node_readers.end()) { |
285 if (node_readers.find(name) != node_readers.end()) { |
265 throw Exception() << "Multiple read rule for node"; |
286 throw Exception() << "Multiple read rule for node"; |
266 } |
287 } |
267 node_readers.insert(make_pair(name, &node)); |
288 node_readers.insert(make_pair(name, &node)); |
289 return *this; |
|
268 } |
290 } |
269 |
291 |
270 // Edge rules |
292 // Edge rules |
271 |
293 |
272 GraphReader& readEdge(std::string name, Edge& edge) { |
294 GraphReader& addEdge(std::string name, Edge& edge) { |
273 if (edge_readers.find(name) != edge_readers.end()) { |
295 if (edge_readers.find(name) != edge_readers.end()) { |
274 throw Exception() << "Multiple read rule for edge"; |
296 throw Exception() << "Multiple read rule for edge"; |
275 } |
297 } |
276 edge_readers.insert(make_pair(name, &edge)); |
298 edge_readers.insert(make_pair(name, &edge)); |
299 return *this; |
|
277 } |
300 } |
278 |
301 |
279 void read() { |
302 void read() { |
280 int line_num = 0; |
303 int line_num = 0; |
281 std::auto_ptr<InverterBase<Node> > nodeInverter; |
304 std::auto_ptr<InverterBase<Node> > nodeInverter; |
304 |
327 |
305 private: |
328 private: |
306 |
329 |
307 template <typename Item> class InverterBase; |
330 template <typename Item> class InverterBase; |
308 |
331 |
309 std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) { |
332 std::string readNodeSet(int& line_num, |
333 auto_ptr<InverterBase<Node> > & nodeInverter) { |
|
310 std::vector<ReaderBase<Node>* > index; |
334 std::vector<ReaderBase<Node>* > index; |
311 { |
335 { |
312 std::string line = readNotEmptyLine(is, line_num); |
336 std::string line = readNotEmptyLine(is, line_num); |
313 std::string id; |
337 std::string id; |
314 std::istringstream ls(line); |
338 std::istringstream ls(line); |
332 std::string line; |
356 std::string line; |
333 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
357 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
334 Node node = graph.addNode(); |
358 Node node = graph.addNode(); |
335 std::istringstream ls(line); |
359 std::istringstream ls(line); |
336 nodeInverter->read(ls, node); |
360 nodeInverter->read(ls, node); |
337 for (int i = 1; i < index.size(); ++i) { |
361 for (int i = 1; i < (int)index.size(); ++i) { |
338 index[i]->read(ls, node); |
362 index[i]->read(ls, node); |
339 } |
363 } |
340 } |
364 } |
341 return line; |
365 return line; |
342 } |
366 } |
343 |
367 |
344 std::string readEdgeSet(int& line_num, |
368 std::string readEdgeSet(int& line_num, |
345 auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) { |
369 auto_ptr<InverterBase<Edge> > & edgeInverter, |
370 auto_ptr<InverterBase<Node> > & nodeInverter) { |
|
346 std::vector<ReaderBase<Edge>*> index; |
371 std::vector<ReaderBase<Edge>*> index; |
347 { |
372 { |
348 std::string line = readNotEmptyLine(is, line_num); |
373 std::string line = readNotEmptyLine(is, line_num); |
349 std::string id; |
374 std::string id; |
350 std::istringstream ls(line); |
375 std::istringstream ls(line); |
370 std::istringstream ls(line); |
395 std::istringstream ls(line); |
371 Node source = nodeInverter->read(ls); |
396 Node source = nodeInverter->read(ls); |
372 Node target = nodeInverter->read(ls); |
397 Node target = nodeInverter->read(ls); |
373 Edge edge = graph.addEdge(source, target); |
398 Edge edge = graph.addEdge(source, target); |
374 edgeInverter->read(ls, edge); |
399 edgeInverter->read(ls, edge); |
375 for (int i = 1; i < index.size(); ++i) { |
400 for (int i = 1; i < (int)index.size(); ++i) { |
376 index[i]->read(ls, edge); |
401 index[i]->read(ls, edge); |
377 } |
402 } |
378 } |
403 } |
379 return line; |
404 return line; |
380 } |
405 } |
381 |
406 |
382 std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) { |
407 std::string readNodes(int& line_num, |
408 auto_ptr<InverterBase<Node> >& nodeInverter) { |
|
383 std::string line; |
409 std::string line; |
384 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
410 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
385 std::istringstream ls(line); |
411 std::istringstream ls(line); |
386 std::string name; |
412 std::string name; |
387 ls >> name; |
413 ls >> name; |
391 } |
417 } |
392 } |
418 } |
393 return line; |
419 return line; |
394 } |
420 } |
395 |
421 |
396 std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) { |
422 std::string readEdges(int& line_num, |
423 auto_ptr<InverterBase<Edge> >& edgeInverter) { |
|
397 std::string line; |
424 std::string line; |
398 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
425 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
399 std::istringstream ls(line); |
426 std::istringstream ls(line); |
400 std::string name; |
427 std::string name; |
401 ls >> name; |
428 ls >> name; |
409 |
436 |
410 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
437 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
411 std::string line; |
438 std::string line; |
412 while (++line_num, getline(is, line)) { |
439 while (++line_num, getline(is, line)) { |
413 int vi = line.find_first_not_of(" \t"); |
440 int vi = line.find_first_not_of(" \t"); |
414 if (vi != string::npos && line[vi] != '#') { |
441 if (vi != (int)string::npos && line[vi] != '#') { |
415 return line.substr(vi); |
442 return line.substr(vi); |
416 } |
443 } |
417 } |
444 } |
418 throw DataFormatException("End of stream"); |
445 throw DataFormatException("End of stream"); |
419 } |
446 } |
443 Inverse inverse; |
470 Inverse inverse; |
444 |
471 |
445 MapReaderInverter(Map& _map, const Reader& _reader) |
472 MapReaderInverter(Map& _map, const Reader& _reader) |
446 : map(_map), reader(_reader) {} |
473 : map(_map), reader(_reader) {} |
447 |
474 |
475 virtual ~MapReaderInverter() {} |
|
476 |
|
448 virtual void read(std::istream& is, const Item& item) { |
477 virtual void read(std::istream& is, const Item& item) { |
449 Value value; |
478 Value value; |
450 reader.read(is, value); |
479 reader.read(is, value); |
451 map.set(item, value); |
480 map.set(item, value); |
452 typename Inverse::iterator it = inverse.find(value); |
481 typename Inverse::iterator it = inverse.find(value); |
480 Reader reader; |
509 Reader reader; |
481 |
510 |
482 SkipReaderInverter(const Reader& _reader) |
511 SkipReaderInverter(const Reader& _reader) |
483 : reader(_reader) {} |
512 : reader(_reader) {} |
484 |
513 |
514 virtual ~SkipReaderInverter() {} |
|
515 |
|
485 virtual void read(std::istream& is, const Item& item) { |
516 virtual void read(std::istream& is, const Item& item) { |
486 Value value; |
517 Value value; |
487 reader.read(is, value); |
518 reader.read(is, value); |
488 typename Inverse::iterator it = inverse.find(value); |
519 typename Inverse::iterator it = inverse.find(value); |
489 if (it == inverse.end()) { |
520 if (it == inverse.end()) { |
511 |
542 |
512 template <typename _Item> |
543 template <typename _Item> |
513 class ReaderBase { |
544 class ReaderBase { |
514 public: |
545 public: |
515 typedef _Item Item; |
546 typedef _Item Item; |
547 |
|
548 // virtual ~ReaderBase() {} |
|
516 |
549 |
517 virtual void read(std::istream& is, const Item& item) = 0; |
550 virtual void read(std::istream& is, const Item& item) = 0; |
518 virtual InverterBase<_Item>* getInverter() = 0; |
551 virtual InverterBase<_Item>* getInverter() = 0; |
519 }; |
552 }; |
520 |
553 |
530 Reader reader; |
563 Reader reader; |
531 |
564 |
532 MapReader(Map& _map, const Reader& _reader) |
565 MapReader(Map& _map, const Reader& _reader) |
533 : map(_map), reader(_reader) {} |
566 : map(_map), reader(_reader) {} |
534 |
567 |
568 virtual ~MapReader() {} |
|
535 |
569 |
536 virtual void read(std::istream& is, const Item& item) { |
570 virtual void read(std::istream& is, const Item& item) { |
537 Value value; |
571 Value value; |
538 reader.read(is, value); |
572 reader.read(is, value); |
539 map.set(item, value); |
573 map.set(item, value); |
553 typedef _Item Item; |
587 typedef _Item Item; |
554 |
588 |
555 Reader reader; |
589 Reader reader; |
556 SkipReader(const Reader& _reader) : reader(_reader) {} |
590 SkipReader(const Reader& _reader) : reader(_reader) {} |
557 |
591 |
592 virtual ~SkipReader() {} |
|
593 |
|
558 virtual void read(std::istream& is, const Item& item) { |
594 virtual void read(std::istream& is, const Item& item) { |
559 Value value; |
595 Value value; |
560 reader.read(is, value); |
596 reader.read(is, value); |
561 } |
597 } |
562 |
598 |