src/lemon/graph_reader.h
changeset 1210 f02396423239
parent 1164 80bb73097736
child 1214 39993ada11c7
equal deleted inserted replaced
2:4c8869d50a9b 3:77f98de403ac
    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 
   397 	  }
   372 	  }
   398 	}
   373 	}
   399       }
   374       }
   400 
   375 
   401       if (index.size() == 0) {
   376       if (index.size() == 0) {
   402 	throw DataFormatException("No node map found");
   377 	throw DataFormatError("Cannot find node id map");
   403       }
   378       }
   404 
   379 
   405       nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter());
   380       nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter());
   406       std::string line;
   381       std::string line;
   407       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   382       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   434 	  }
   409 	  }
   435 	}
   410 	}
   436       }
   411       }
   437 
   412 
   438       if (index.size() == 0) {
   413       if (index.size() == 0) {
   439 	throw DataFormatException("No edge map found");
   414 	throw DataFormatError("Cannot find edge id map");
   440       }
   415       }
   441 
   416 
   442       edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
   417       edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
   443       std::string line;
   418       std::string line;
   444       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   419       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   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 }