33 |
33 |
34 namespace lemon { |
34 namespace lemon { |
35 |
35 |
36 // Exceptions |
36 // Exceptions |
37 |
37 |
38 class IOException { |
|
39 public: |
|
40 virtual ~IOException() {} |
|
41 virtual string what() const = 0; |
|
42 }; |
|
43 |
|
44 class DataFormatException : public IOException { |
|
45 std::string message; |
|
46 public: |
|
47 DataFormatException(const std::string& _message) |
|
48 : message(_message) {} |
|
49 std::string what() const { |
|
50 return "DataFormatException: " + message; |
|
51 } |
|
52 }; |
|
53 |
|
54 template <typename _Exception> |
|
55 class StreamException : public _Exception { |
|
56 public: |
|
57 typedef _Exception Exception; |
|
58 StreamException(int _line, Exception _exception) |
|
59 : Exception(_exception), line_num(_line) {} |
|
60 virtual int line() const { |
|
61 return line_num; |
|
62 } |
|
63 |
|
64 virtual ~StreamException() {} |
|
65 |
|
66 virtual std::string what() const { |
|
67 ostringstream os; |
|
68 os << Exception::what() << " in line " << line(); |
|
69 return os.str(); |
|
70 } |
|
71 private: |
|
72 int line_num; |
|
73 }; |
|
74 |
|
75 |
38 |
76 /// \brief Standard ReaderTraits for the GraphReader class. |
39 /// \brief Standard ReaderTraits for the GraphReader class. |
77 /// |
40 /// |
78 /// Standard ReaderTraits for the GraphReader class. |
41 /// Standard ReaderTraits for the GraphReader class. |
79 /// It defines standard reading method for all type of value. |
42 /// It defines standard reading method for all type of value. |
89 /// \brief Reads a value from the given stream. |
52 /// \brief Reads a value from the given stream. |
90 /// |
53 /// |
91 /// Reads a value from the given stream. |
54 /// Reads a value from the given stream. |
92 void read(std::istream& is, Value& value) { |
55 void read(std::istream& is, Value& value) { |
93 if (!(is >> value)) |
56 if (!(is >> value)) |
94 throw DataFormatException("Default Reader format exception"); |
57 throw DataFormatError("Default reader format exception"); |
95 } |
58 } |
96 }; |
59 }; |
97 |
60 |
98 /// The reader class for the not needed maps. |
61 /// The reader class for the not needed maps. |
99 typedef Reader<std::string> DefaultReader; |
62 typedef Reader<std::string> DefaultReader; |
120 void read(std::istream& is, std::string& value) { |
83 void read(std::istream& is, std::string& value) { |
121 char c; |
84 char c; |
122 value.clear(); |
85 value.clear(); |
123 is >> ws; |
86 is >> ws; |
124 if (!is.get(c) || c != '\"') |
87 if (!is.get(c) || c != '\"') |
125 throw DataFormatException("Quoted string format"); |
88 throw DataFormatError("Quoted string format error"); |
126 while (is.get(c) && c != '\"') { |
89 while (is.get(c) && c != '\"') { |
127 if (escaped && c == '\\') { |
90 if (escaped && c == '\\') { |
128 value += readEscape(is); |
91 value += readEscape(is); |
129 } else { |
92 } else { |
130 value += c; |
93 value += c; |
131 } |
94 } |
132 } |
95 } |
133 if (!is) throw DataFormatException("Quoted string format"); |
96 if (!is) throw DataFormatError("Quoted string format error"); |
134 } |
97 } |
135 |
98 |
136 private: |
99 private: |
137 |
100 |
138 static char readEscape(std::istream& is) { |
101 static char readEscape(std::istream& is) { |
162 return '\v'; |
125 return '\v'; |
163 case 'x': |
126 case 'x': |
164 { |
127 { |
165 int code; |
128 int code; |
166 if (!is.get(c) || !isHex(c)) |
129 if (!is.get(c) || !isHex(c)) |
167 throw DataFormatException("Escape format exception"); |
130 throw DataFormatError("Escape format error"); |
168 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); |
131 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); |
169 else code = code * 16 + valueHex(c); |
132 else code = code * 16 + valueHex(c); |
170 return code; |
133 return code; |
171 } |
134 } |
172 default: |
135 default: |
173 { |
136 { |
174 int code; |
137 int code; |
175 if (!isOct(c)) |
138 if (!isOct(c)) |
176 throw DataFormatException("Escape format exception"); |
139 throw DataFormatError("Escape format error"); |
177 else if (code = valueOct(c), !is.get(c) || !isOct(c)) |
140 else if (code = valueOct(c), !is.get(c) || !isOct(c)) |
178 is.putback(c); |
141 is.putback(c); |
179 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) |
142 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) |
180 is.putback(c); |
143 is.putback(c); |
181 else code = code * 8 + valueOct(c); |
144 else code = code * 8 + valueOct(c); |
223 typedef _ReaderTraits ReaderTraits; |
186 typedef _ReaderTraits ReaderTraits; |
224 typedef typename ReaderTraits::DefaultReader DefaultReader; |
187 typedef typename ReaderTraits::DefaultReader DefaultReader; |
225 |
188 |
226 /// \brief Construct a new GraphReader. |
189 /// \brief Construct a new GraphReader. |
227 /// |
190 /// |
228 /// Construct a new GraphReader. It reads from the given map, |
191 /// Construct a new GraphReader. It reads into the given graph |
229 /// it constructs the given map and it use the given reader as the |
192 /// and it use the given reader as the default skipper. |
230 /// default skipper. |
|
231 GraphReader(std::istream& _is, Graph& _graph, |
193 GraphReader(std::istream& _is, Graph& _graph, |
232 const DefaultReader& _reader = DefaultReader()) |
194 const DefaultReader& _reader = DefaultReader()) |
233 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
195 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
234 |
196 |
235 /// \brief Destruct the graph reader. |
197 /// \brief Destruct the graph reader. |
263 /// Add a new node map reader command for the reader. |
225 /// Add a new node map reader command for the reader. |
264 template <typename Reader, typename Map> |
226 template <typename Reader, typename Map> |
265 GraphReader& addNodeMap(std::string name, Map& map, |
227 GraphReader& addNodeMap(std::string name, Map& map, |
266 const Reader& reader = Reader()) { |
228 const Reader& reader = Reader()) { |
267 if (node_map_readers.find(name) != node_map_readers.end()) { |
229 if (node_map_readers.find(name) != node_map_readers.end()) { |
268 throw Exception() << "Multiple read rule for node map: " << name; |
230 ErrorMessage msg; |
|
231 msg << "Multiple read rule for node map: " << name; |
|
232 throw IOLogicError(msg.message()); |
269 } |
233 } |
270 node_map_readers.insert( |
234 node_map_readers.insert( |
271 make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
235 make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
272 return *this; |
236 return *this; |
273 } |
237 } |
277 /// Add a new node map skipper command for the reader. |
241 /// Add a new node map skipper command for the reader. |
278 template <typename Reader> |
242 template <typename Reader> |
279 GraphReader& skipNodeMap(std::string name, |
243 GraphReader& skipNodeMap(std::string name, |
280 const Reader& reader = Reader()) { |
244 const Reader& reader = Reader()) { |
281 if (node_map_readers.find(name) != node_map_readers.end()) { |
245 if (node_map_readers.find(name) != node_map_readers.end()) { |
282 throw Exception() << "Multiple read rule for node map: " << name; |
246 ErrorMessage msg; |
|
247 msg << "Multiple read rule for node map: " << name; |
|
248 throw IOLogicError(msg.message()); |
283 } |
249 } |
284 node_map_readers.insert( |
250 node_map_readers.insert( |
285 make_pair(name, new SkipReader<Node, Reader>(reader))); |
251 make_pair(name, new SkipReader<Node, Reader>(reader))); |
286 return *this; |
252 return *this; |
287 } |
253 } |
301 /// Add a new edge map reader command for the reader. |
267 /// Add a new edge map reader command for the reader. |
302 template <typename Reader, typename Map> |
268 template <typename Reader, typename Map> |
303 GraphReader& addEdgeMap(std::string name, Map& map, |
269 GraphReader& addEdgeMap(std::string name, Map& map, |
304 const Reader& reader = Reader()) { |
270 const Reader& reader = Reader()) { |
305 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
271 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
306 throw Exception() << "Multiple read rule for edge map: " << name; |
272 ErrorMessage msg; |
|
273 msg << "Multiple read rule for edge map: " << name; |
|
274 throw IOLogicError(msg.message()); |
307 } |
275 } |
308 edge_map_readers.insert( |
276 edge_map_readers.insert( |
309 make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
277 make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
310 return *this; |
278 return *this; |
311 } |
279 } |
315 /// Add a new edge map skipper command for the reader. |
283 /// Add a new edge map skipper command for the reader. |
316 template <typename Reader> |
284 template <typename Reader> |
317 GraphReader& skipEdgeMap(std::string name, |
285 GraphReader& skipEdgeMap(std::string name, |
318 const Reader& reader = Reader()) { |
286 const Reader& reader = Reader()) { |
319 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
287 if (edge_map_readers.find(name) != edge_map_readers.end()) { |
320 throw Exception() << "Multiple read rule for edge map: " << name; |
288 ErrorMessage msg; |
|
289 msg << "Multiple read rule for edge map: " << name; |
|
290 throw IOLogicError(msg.message()); |
321 } |
291 } |
322 edge_map_readers.insert( |
292 edge_map_readers.insert( |
323 make_pair(name, new SkipReader<Edge, Reader>(reader))); |
293 make_pair(name, new SkipReader<Edge, Reader>(reader))); |
324 return *this; |
294 return *this; |
325 } |
295 } |
327 /// \brief Add a new labeled node reader for the reader. |
297 /// \brief Add a new labeled node reader for the reader. |
328 /// |
298 /// |
329 /// Add a new labeled node reader for the reader. |
299 /// Add a new labeled node reader for the reader. |
330 GraphReader& addNode(std::string name, Node& node) { |
300 GraphReader& addNode(std::string name, Node& node) { |
331 if (node_readers.find(name) != node_readers.end()) { |
301 if (node_readers.find(name) != node_readers.end()) { |
332 throw Exception() << "Multiple read rule for node"; |
302 ErrorMessage msg; |
|
303 msg << "Multiple read rule for node: " << name; |
|
304 throw IOLogicError(msg.message()); |
333 } |
305 } |
334 node_readers.insert(make_pair(name, &node)); |
306 node_readers.insert(make_pair(name, &node)); |
335 return *this; |
307 return *this; |
336 } |
308 } |
337 |
309 |
338 /// \brief Add a new labeled edge reader for the reader. |
310 /// \brief Add a new labeled edge reader for the reader. |
339 /// |
311 /// |
340 /// Add a new labeled edge reader for the reader. |
312 /// Add a new labeled edge reader for the reader. |
341 GraphReader& addEdge(std::string name, Edge& edge) { |
313 GraphReader& addEdge(std::string name, Edge& edge) { |
342 if (edge_readers.find(name) != edge_readers.end()) { |
314 if (edge_readers.find(name) != edge_readers.end()) { |
343 throw Exception() << "Multiple read rule for edge"; |
315 ErrorMessage msg; |
|
316 msg << "Multiple read rule for edge: " << name; |
|
317 throw IOLogicError(msg.message()); |
344 } |
318 } |
345 edge_readers.insert(make_pair(name, &edge)); |
319 edge_readers.insert(make_pair(name, &edge)); |
346 return *this; |
320 return *this; |
347 } |
321 } |
348 |
322 |
366 } |
340 } |
367 if (line.find("@edges") == 0) { |
341 if (line.find("@edges") == 0) { |
368 line = readEdges(line_num, edgeInverter); |
342 line = readEdges(line_num, edgeInverter); |
369 } |
343 } |
370 if (line.find("@end") != 0) { |
344 if (line.find("@end") != 0) { |
371 throw DataFormatException("Invalid control sequence: " + line); |
345 throw DataFormatError("Invalid control sequence error"); |
372 } |
346 } |
373 } catch (DataFormatException e) { |
347 } catch (DataFormatError e) { |
374 throw StreamException<DataFormatException>(line_num, e); |
348 e.line(line_num); |
|
349 throw e; |
375 } |
350 } |
376 } |
351 } |
377 |
352 |
378 private: |
353 private: |
379 |
354 |
490 int vi = line.find_first_not_of(" \t"); |
465 int vi = line.find_first_not_of(" \t"); |
491 if (vi != (int)string::npos && line[vi] != '#') { |
466 if (vi != (int)string::npos && line[vi] != '#') { |
492 return line.substr(vi); |
467 return line.substr(vi); |
493 } |
468 } |
494 } |
469 } |
495 throw DataFormatException("End of stream"); |
470 throw DataFormatError("End of stream error"); |
496 } |
471 } |
497 |
472 |
498 // Inverters store and give back the Item from the id, |
473 // Inverters store and give back the Item from the id, |
499 // and may put the ids into a map. |
474 // and may put the ids into a map. |
500 |
475 |
530 map.set(item, value); |
505 map.set(item, value); |
531 typename Inverse::iterator it = inverse.find(value); |
506 typename Inverse::iterator it = inverse.find(value); |
532 if (it == inverse.end()) { |
507 if (it == inverse.end()) { |
533 inverse.insert(make_pair(value, item)); |
508 inverse.insert(make_pair(value, item)); |
534 } else { |
509 } else { |
535 throw DataFormatException("Multiple ID occurence"); |
510 throw DataFormatError("Multiple ID occurence"); |
536 } |
511 } |
537 } |
512 } |
538 |
513 |
539 virtual Item read(std::istream& is) { |
514 virtual Item read(std::istream& is) { |
540 Value value; |
515 Value value; |
541 reader.read(is, value); |
516 reader.read(is, value); |
542 typename Inverse::const_iterator it = inverse.find(value); |
517 typename Inverse::const_iterator it = inverse.find(value); |
543 if (it != inverse.end()) { |
518 if (it != inverse.end()) { |
544 return it->second; |
519 return it->second; |
545 } else { |
520 } else { |
546 throw DataFormatException("Invalid ID"); |
521 throw DataFormatError("Invalid ID error"); |
547 } |
522 } |
548 } |
523 } |
549 }; |
524 }; |
550 |
525 |
551 template <typename _Item, typename _Reader> |
526 template <typename _Item, typename _Reader> |
568 reader.read(is, value); |
543 reader.read(is, value); |
569 typename Inverse::iterator it = inverse.find(value); |
544 typename Inverse::iterator it = inverse.find(value); |
570 if (it == inverse.end()) { |
545 if (it == inverse.end()) { |
571 inverse.insert(make_pair(value, item)); |
546 inverse.insert(make_pair(value, item)); |
572 } else { |
547 } else { |
573 throw DataFormatException("Multiple ID occurence"); |
548 throw DataFormatError("Multiple ID occurence error"); |
574 } |
549 } |
575 } |
550 } |
576 |
551 |
577 virtual Item read(std::istream& is) { |
552 virtual Item read(std::istream& is) { |
578 Value value; |
553 Value value; |
579 reader.read(is, value); |
554 reader.read(is, value); |
580 typename Inverse::const_iterator it = inverse.find(value); |
555 typename Inverse::const_iterator it = inverse.find(value); |
581 if (it != inverse.end()) { |
556 if (it != inverse.end()) { |
582 return it->second; |
557 return it->second; |
583 } else { |
558 } else { |
584 throw DataFormatException("Invalid ID"); |
559 throw DataFormatError("Invalid ID error"); |
585 } |
560 } |
586 } |
561 } |
587 private: |
562 private: |
588 Inverse inverse; |
563 Inverse inverse; |
589 }; |
564 }; |
670 SkipReader<Node, DefaultReader> nodeSkipper; |
645 SkipReader<Node, DefaultReader> nodeSkipper; |
671 SkipReader<Edge, DefaultReader> edgeSkipper; |
646 SkipReader<Edge, DefaultReader> edgeSkipper; |
672 |
647 |
673 }; |
648 }; |
674 |
649 |
|
650 /// Ready to use reader function. |
|
651 template<typename Graph, typename CapacityMap, typename CostMap> |
|
652 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
|
653 typename Graph::Node &s, typename Graph::Node &t, |
|
654 CostMap& cost) { |
|
655 GraphReader<Graph> reader(is, g); |
|
656 reader.addEdgeMap("capacity", capacity); |
|
657 reader.addEdgeMap("cost", cost); |
|
658 reader.addNode("source", s); |
|
659 reader.addNode("target", t); |
|
660 reader.run(); |
|
661 } |
|
662 |
|
663 template<typename Graph, typename CapacityMap> |
|
664 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
|
665 typename Graph::Node &s, typename Graph::Node &t) { |
|
666 GraphReader<Graph> reader(is, g); |
|
667 reader.addEdgeMap("capacity", capacity); |
|
668 reader.addNode("source", s); |
|
669 reader.addNode("target", t); |
|
670 reader.run(); |
|
671 } |
|
672 |
|
673 template<typename Graph, typename CapacityMap> |
|
674 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
|
675 typename Graph::Node &s) { |
|
676 GraphReader<Graph> reader(is, g); |
|
677 reader.addEdgeMap("capacity", capacity); |
|
678 reader.addNode("source", s); |
|
679 reader.run(); |
|
680 } |
|
681 |
|
682 template<typename Graph, typename CapacityMap> |
|
683 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) { |
|
684 GraphReader<Graph> reader(is, g); |
|
685 reader.addEdgeMap("capacity", capacity); |
|
686 reader.run(); |
|
687 } |
|
688 |
|
689 template<typename Graph> |
|
690 void readGraph(std::istream& is, Graph &g) { |
|
691 GraphReader<Graph> reader(is, g); |
|
692 reader.run(); |
|
693 } |
|
694 |
675 } |
695 } |