src/lemon/graph_reader.h
changeset 1335 13a863ce81d9
parent 1311 b810a07248a0
child 1341 bda966891ea0
equal deleted inserted replaced
7:358e3ee5c5f1 8:e5912587656b
    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;
   198 
   267 
   199     /// \brief Destruct the graph reader.
   268     /// \brief Destruct the graph reader.
   200     ///
   269     ///
   201     /// Destruct the graph reader.
   270     /// Destruct the graph reader.
   202     ~GraphReader() {
   271     ~GraphReader() {
   203 
       
   204       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   272       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   205 	   it != node_map_readers.end(); ++it) {
   273 	   it != node_map_readers.end(); ++it) {
   206 	delete it->second;
   274 	delete it->second;
   207       }
   275       }
   208 
   276 
   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);
   449     }
   527     }
   450 
   528 
   451     std::string readEdges(int& line_num, 
   529     std::string readEdges(int& line_num, 
   452 			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
   530 			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
   453       std::string line;
   531       std::string line;
       
   532       if (edgeInverter.get() == 0) {
       
   533  	throw DataFormatError("Cannot find edge id map");
       
   534       }
   454       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   535       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   455 	std::istringstream ls(line);
   536 	std::istringstream ls(line);
   456 	std::string name;
   537 	std::string name;
   457 	ls >> name;
   538 	ls >> name;
   458 	typename EdgeReaders::iterator it = edge_readers.find(name);
   539 	typename EdgeReaders::iterator it = edge_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