32 #include <lemon/error.h> |
32 #include <lemon/error.h> |
33 |
33 |
34 |
34 |
35 namespace lemon { |
35 namespace lemon { |
36 |
36 |
|
37 /// \addtogroup io_group |
|
38 /// @{ |
37 |
39 |
38 /// \brief Standard ReaderTraits for the GraphReader class. |
40 /// \brief Standard ReaderTraits for the GraphReader class. |
39 /// |
41 /// |
40 /// Standard ReaderTraits for the GraphReader class. |
42 /// Standard ReaderTraits for the GraphReader class. |
41 /// It defines standard reading method for all type of value. |
43 /// It defines standard reading method for all type of value. |
|
44 /// \author Balazs Dezso |
42 struct DefaultReaderTraits { |
45 struct DefaultReaderTraits { |
43 |
46 |
44 /// \brief Template class for reading an value. |
47 /// \brief Template class for reading an value. |
45 /// |
48 /// |
46 /// Template class for reading an value. |
49 /// Template class for reading an value. |
|
50 /// \author Balazs Dezso |
47 template <typename _Value> |
51 template <typename _Value> |
48 struct Reader { |
52 struct Reader { |
49 /// The value type. |
53 /// The value type. |
50 typedef _Value Value; |
54 typedef _Value Value; |
51 /// \brief Reads a value from the given stream. |
55 /// \brief Reads a value from the given stream. |
55 if (!(is >> value)) |
59 if (!(is >> value)) |
56 throw DataFormatError("Default reader format exception"); |
60 throw DataFormatError("Default reader format exception"); |
57 } |
61 } |
58 }; |
62 }; |
59 |
63 |
|
64 /// \brief Returns wheter this name is an ID map name. |
|
65 /// |
|
66 /// Returns wheter this name is an ID map name. |
|
67 static bool idMapName(const std::string& name) { |
|
68 return name == "id"; |
|
69 } |
|
70 |
60 /// The reader class for the not needed maps. |
71 /// The reader class for the not needed maps. |
61 typedef Reader<std::string> DefaultReader; |
72 typedef Reader<std::string> DefaultReader; |
62 |
73 |
63 }; |
74 }; |
64 |
75 |
65 /// \brief Reader class for quoted strings. |
76 /// \brief Reader class for quoted strings. |
66 /// |
77 /// |
67 /// Reader class for quoted strings. It can process the escape |
78 /// Reader class for quoted strings. It can process the escape |
68 /// sequences in the string. |
79 /// sequences in the string. |
|
80 /// \author Balazs Dezso |
69 class QuotedStringReader { |
81 class QuotedStringReader { |
70 public: |
82 public: |
71 typedef std::string Value; |
83 typedef std::string Value; |
72 |
84 |
73 /// \brief Constructor for the reader. |
85 /// \brief Constructor for the reader. |
169 bool escaped; |
181 bool escaped; |
170 }; |
182 }; |
171 |
183 |
172 /// \brief The graph reader class. |
184 /// \brief The graph reader class. |
173 /// |
185 /// |
174 /// \ingroup io_group |
186 /// |
175 /// The reader class for the graph input. |
187 /// The given file format may contain several maps and labeled nodes or |
|
188 /// edges. |
|
189 /// |
|
190 /// If you read a graph you need not read all the maps and items just those |
|
191 /// that you need. The interface of the \c GraphReader is very similar to |
|
192 /// the GraphWriter but the reading method does not depend on the order the |
|
193 /// given commands. |
|
194 /// |
|
195 /// The reader object suppose that each not readed value does not contain |
|
196 /// whitespaces, therefore it has some extra possibilities to control how |
|
197 /// it should skip the values when the string representation contains spaces. |
|
198 /// |
|
199 /// \code |
|
200 /// GraphReader<ListGraph> reader(std::cin, graph); |
|
201 /// \endcode |
|
202 /// |
|
203 /// The \c addNodeMap() function reads a map from the \c \@nodeset section. |
|
204 /// If there is a map that you do not want to read from the file and there is |
|
205 /// whitespace in the string represenation of the values then you should |
|
206 /// call the \c skipNodeMap() template member function with proper |
|
207 /// parameters. |
|
208 /// |
|
209 /// \code |
|
210 /// reader.addNodeMap("x-coord", xCoordMap); |
|
211 /// reader.addNodeMap("y-coord", yCoordMap); |
|
212 /// |
|
213 /// reader.addNodeMap<QuotedStringReader>("label", labelMap); |
|
214 /// reader.skipNodeMap<QuotedStringReader>("description"); |
|
215 /// |
|
216 /// reader.addNodeMap("color", colorMap); |
|
217 /// \endcode |
|
218 /// |
|
219 /// With the \c addEdgeMap() member function you can give an edge map |
|
220 /// reading command similar to the NodeMaps. |
|
221 /// |
|
222 /// \code |
|
223 /// reader.addEdgeMap("weight", weightMap); |
|
224 /// reader.addEdgeMap("label", labelMap); |
|
225 /// \endcode |
|
226 /// |
|
227 /// With \c addNode() and \c addEdge() functions you can read labeled Nodes |
|
228 /// and Edges. |
|
229 /// |
|
230 /// \code |
|
231 /// reader.addNode("source", sourceNode); |
|
232 /// reader.addNode("target", targetNode); |
|
233 /// |
|
234 /// reader.addEdge("observed", edge); |
|
235 /// \endcode |
|
236 /// |
|
237 /// After you give all read commands you must call the \c run() member |
|
238 /// function, which execute all the commands. |
|
239 /// |
|
240 /// \code |
|
241 /// reader.run(); |
|
242 /// \endcode |
|
243 /// |
176 /// \see DefaultReaderTraits |
244 /// \see DefaultReaderTraits |
177 /// \see QuotedStringReader |
245 /// \see QuotedStringReader |
178 /// \see \ref GraphWriter |
246 /// \see \ref GraphWriter |
179 /// \see \ref graph-io-page |
247 /// \see \ref graph-io-page |
|
248 /// \author Balazs Dezso |
180 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
249 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
181 class GraphReader { |
250 class GraphReader { |
182 public: |
251 public: |
183 |
252 |
184 typedef _Graph Graph; |
253 typedef _Graph Graph; |
362 { |
430 { |
363 std::string line = readNotEmptyLine(is, line_num); |
431 std::string line = readNotEmptyLine(is, line_num); |
364 std::string id; |
432 std::string id; |
365 std::istringstream ls(line); |
433 std::istringstream ls(line); |
366 while (ls >> id) { |
434 while (ls >> id) { |
367 if (id[0] == '#') break; |
|
368 typename NodeMapReaders::iterator it = node_map_readers.find(id); |
435 typename NodeMapReaders::iterator it = node_map_readers.find(id); |
369 if (it != node_map_readers.end()) { |
436 if (it != node_map_readers.end()) { |
370 index.push_back(it->second); |
437 index.push_back(it->second); |
371 node_map_readers.erase(it); |
438 node_map_readers.erase(it); |
372 } else { |
439 } else { |
373 index.push_back(&nodeSkipper); |
440 index.push_back(&nodeSkipper); |
374 } |
441 } |
375 } |
442 if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) { |
376 } |
443 nodeInverter.reset(index.back()->getInverter()); |
377 |
444 index.back() = nodeInverter.get(); |
378 if (index.size() == 0) { |
445 } |
379 throw DataFormatError("Cannot find node id map"); |
446 } |
380 } |
447 } |
381 |
448 |
382 nodeInverter = |
449 // if (index.size() == 0) { |
383 std::auto_ptr<InverterBase<Node> >(index[0]->getInverter()); |
450 // throw DataFormatError("Cannot find node id map"); |
|
451 // } |
|
452 |
|
453 // nodeInverter = |
|
454 // std::auto_ptr<InverterBase<Node> >(index[0]->getInverter()); |
384 std::string line; |
455 std::string line; |
385 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
456 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
386 Node node = graph.addNode(); |
457 Node node = graph.addNode(); |
387 std::istringstream ls(line); |
458 std::istringstream ls(line); |
388 nodeInverter->read(ls, node); |
459 for (int i = 0; i < (int)index.size(); ++i) { |
389 for (int i = 1; i < (int)index.size(); ++i) { |
|
390 index[i]->read(ls, node); |
460 index[i]->read(ls, node); |
391 } |
461 } |
392 } |
462 } |
393 return line; |
463 return line; |
394 } |
464 } |
400 { |
470 { |
401 std::string line = readNotEmptyLine(is, line_num); |
471 std::string line = readNotEmptyLine(is, line_num); |
402 std::string id; |
472 std::string id; |
403 std::istringstream ls(line); |
473 std::istringstream ls(line); |
404 while (ls >> id) { |
474 while (ls >> id) { |
405 if (id[0] == '#') break; |
|
406 typename EdgeMapReaders::iterator it = edge_map_readers.find(id); |
475 typename EdgeMapReaders::iterator it = edge_map_readers.find(id); |
407 if (it != edge_map_readers.end()) { |
476 if (it != edge_map_readers.end()) { |
408 index.push_back(it->second); |
477 index.push_back(it->second); |
409 edge_map_readers.erase(it); |
478 edge_map_readers.erase(it); |
410 } else { |
479 } else { |
411 index.push_back(&edgeSkipper); |
480 index.push_back(&edgeSkipper); |
412 } |
481 } |
413 } |
482 if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) { |
414 } |
483 edgeInverter.reset(index.back()->getInverter()); |
415 |
484 index.back() = edgeInverter.get(); |
416 if (index.size() == 0) { |
485 } |
417 throw DataFormatError("Cannot find edge id map"); |
486 } |
418 } |
487 } |
419 |
488 |
420 edgeInverter = |
489 if (nodeInverter.get() == 0) { |
421 std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter()); |
490 throw DataFormatError("Cannot find node id map"); |
|
491 } |
|
492 // if (index.size() == 0) { |
|
493 // throw DataFormatError("Cannot find edge id map"); |
|
494 // } |
|
495 |
|
496 // edgeInverter = |
|
497 // std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter()); |
422 std::string line; |
498 std::string line; |
423 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
499 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
424 std::istringstream ls(line); |
500 std::istringstream ls(line); |
425 Node source = nodeInverter->read(ls); |
501 Node source = nodeInverter->read(ls); |
426 Node target = nodeInverter->read(ls); |
502 Node target = nodeInverter->read(ls); |
427 Edge edge = graph.addEdge(source, target); |
503 Edge edge = graph.addEdge(source, target); |
428 edgeInverter->read(ls, edge); |
504 for (int i = 0; i < (int)index.size(); ++i) { |
429 for (int i = 1; i < (int)index.size(); ++i) { |
|
430 index[i]->read(ls, edge); |
505 index[i]->read(ls, edge); |
431 } |
506 } |
432 } |
507 } |
433 return line; |
508 return line; |
434 } |
509 } |
435 |
510 |
436 std::string readNodes(int& line_num, |
511 std::string readNodes(int& line_num, |
437 std::auto_ptr<InverterBase<Node> >& nodeInverter) { |
512 std::auto_ptr<InverterBase<Node> >& nodeInverter) { |
438 std::string line; |
513 std::string line; |
|
514 if (nodeInverter.get() == 0) { |
|
515 throw DataFormatError("Cannot find node id map"); |
|
516 } |
439 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
517 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
440 std::istringstream ls(line); |
518 std::istringstream ls(line); |
441 std::string name; |
519 std::string name; |
442 ls >> name; |
520 ls >> name; |
443 typename NodeReaders::iterator it = node_readers.find(name); |
521 typename NodeReaders::iterator it = node_readers.find(name); |
464 } |
545 } |
465 |
546 |
466 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
547 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
467 std::string line; |
548 std::string line; |
468 while (++line_num, getline(is, line)) { |
549 while (++line_num, getline(is, line)) { |
469 int vi = line.find_first_not_of(" \t"); |
550 int vi = line.find('#'); |
470 if (vi != (int)std::string::npos && line[vi] != '#') { |
551 if (vi != (int)::std::string::npos) { |
|
552 line = line.substr(0, vi); |
|
553 } |
|
554 vi = line.find_first_not_of(" \t"); |
|
555 if (vi != (int)std::string::npos) { |
|
556 std::cerr << "Line: " << line.substr(vi) << std::endl; |
471 return line.substr(vi); |
557 return line.substr(vi); |
472 } |
558 } |
473 } |
559 } |
474 throw DataFormatError("End of stream error"); |
560 throw DataFormatError("End of stream error"); |
475 } |
561 } |
476 |
|
477 // Inverters store and give back the Item from the id, |
|
478 // and may put the ids into a map. |
|
479 |
562 |
480 template <typename _Item> |
563 template <typename _Item> |
481 class InverterBase { |
564 class ReaderBase; |
|
565 |
|
566 template <typename _Item> |
|
567 class InverterBase : public ReaderBase<_Item> { |
482 public: |
568 public: |
483 typedef _Item Item; |
569 typedef _Item Item; |
484 virtual void read(std::istream&, const Item&) = 0; |
570 virtual void read(std::istream&, const Item&) = 0; |
485 virtual Item read(std::istream&) = 0; |
571 virtual Item read(std::istream&) = 0; |
|
572 |
|
573 virtual InverterBase<_Item>* getInverter() { |
|
574 return this; |
|
575 } |
486 }; |
576 }; |
487 |
577 |
488 template <typename _Item, typename _Map, typename _Reader> |
578 template <typename _Item, typename _Map, typename _Reader> |
489 class MapReaderInverter : public InverterBase<_Item> { |
579 class MapReaderInverter : public InverterBase<_Item> { |
490 public: |
580 public: |
649 SkipReader<Node, DefaultReader> nodeSkipper; |
739 SkipReader<Node, DefaultReader> nodeSkipper; |
650 SkipReader<Edge, DefaultReader> edgeSkipper; |
740 SkipReader<Edge, DefaultReader> edgeSkipper; |
651 |
741 |
652 }; |
742 }; |
653 |
743 |
654 /// Ready to use reader function. |
744 /// \brief Read a graph from the input. |
|
745 /// |
|
746 /// Read a graph from the input. |
|
747 /// \param is The input stream. |
|
748 /// \param g The graph. |
|
749 /// \param capacity The capacity map. |
|
750 /// \param s The source node. |
|
751 /// \param t The target node. |
|
752 /// \param cost The cost map. |
655 template<typename Graph, typename CapacityMap, typename CostMap> |
753 template<typename Graph, typename CapacityMap, typename CostMap> |
656 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
754 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
657 typename Graph::Node &s, typename Graph::Node &t, |
755 typename Graph::Node &s, typename Graph::Node &t, |
658 CostMap& cost) { |
756 CostMap& cost) { |
659 GraphReader<Graph> reader(is, g); |
757 GraphReader<Graph> reader(is, g); |
662 reader.addNode("source", s); |
760 reader.addNode("source", s); |
663 reader.addNode("target", t); |
761 reader.addNode("target", t); |
664 reader.run(); |
762 reader.run(); |
665 } |
763 } |
666 |
764 |
|
765 /// \brief Read a graph from the input. |
|
766 /// |
|
767 /// Read a graph from the input. |
|
768 /// \param is The input stream. |
|
769 /// \param g The graph. |
|
770 /// \param capacity The capacity map. |
|
771 /// \param s The source node. |
|
772 /// \param t The target node. |
667 template<typename Graph, typename CapacityMap> |
773 template<typename Graph, typename CapacityMap> |
668 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
774 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
669 typename Graph::Node &s, typename Graph::Node &t) { |
775 typename Graph::Node &s, typename Graph::Node &t) { |
670 GraphReader<Graph> reader(is, g); |
776 GraphReader<Graph> reader(is, g); |
671 reader.addEdgeMap("capacity", capacity); |
777 reader.addEdgeMap("capacity", capacity); |
672 reader.addNode("source", s); |
778 reader.addNode("source", s); |
673 reader.addNode("target", t); |
779 reader.addNode("target", t); |
674 reader.run(); |
780 reader.run(); |
675 } |
781 } |
676 |
782 |
|
783 /// \brief Read a graph from the input. |
|
784 /// |
|
785 /// Read a graph from the input. |
|
786 /// \param is The input stream. |
|
787 /// \param g The graph. |
|
788 /// \param capacity The capacity map. |
|
789 /// \param s The source node. |
677 template<typename Graph, typename CapacityMap> |
790 template<typename Graph, typename CapacityMap> |
678 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
791 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, |
679 typename Graph::Node &s) { |
792 typename Graph::Node &s) { |
680 GraphReader<Graph> reader(is, g); |
793 GraphReader<Graph> reader(is, g); |
681 reader.addEdgeMap("capacity", capacity); |
794 reader.addEdgeMap("capacity", capacity); |
682 reader.addNode("source", s); |
795 reader.addNode("source", s); |
683 reader.run(); |
796 reader.run(); |
684 } |
797 } |
685 |
798 |
|
799 /// \brief Read a graph from the input. |
|
800 /// |
|
801 /// Read a graph from the input. |
|
802 /// \param is The input stream. |
|
803 /// \param g The graph. |
|
804 /// \param capacity The capacity map. |
686 template<typename Graph, typename CapacityMap> |
805 template<typename Graph, typename CapacityMap> |
687 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) { |
806 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) { |
688 GraphReader<Graph> reader(is, g); |
807 GraphReader<Graph> reader(is, g); |
689 reader.addEdgeMap("capacity", capacity); |
808 reader.addEdgeMap("capacity", capacity); |
690 reader.run(); |
809 reader.run(); |
691 } |
810 } |
692 |
811 |
|
812 /// \brief Read a graph from the input. |
|
813 /// |
|
814 /// Read a graph from the input. |
|
815 /// \param is The input stream. |
|
816 /// \param g The graph. |
693 template<typename Graph> |
817 template<typename Graph> |
694 void readGraph(std::istream& is, Graph &g) { |
818 void readGraph(std::istream& is, Graph &g) { |
695 GraphReader<Graph> reader(is, g); |
819 GraphReader<Graph> reader(is, g); |
696 reader.run(); |
820 reader.run(); |
697 } |
821 } |
698 |
822 |
|
823 /// @} |
699 } |
824 } |
700 |
825 |
701 #endif |
826 #endif |