src/lemon/graph_reader.h
changeset 1410 dcfad73b3965
parent 1396 56f9a4ba9149
child 1421 7a21e1414c38
equal deleted inserted replaced
13:b292b0051a99 14:cab215f82eec
    20 
    20 
    21 #ifndef LEMON_GRAPH_READER_H
    21 #ifndef LEMON_GRAPH_READER_H
    22 #define LEMON_GRAPH_READER_H
    22 #define LEMON_GRAPH_READER_H
    23 
    23 
    24 #include <iostream>
    24 #include <iostream>
    25 #include <sstream>
       
    26 
       
    27 #include <map>
       
    28 #include <vector>
       
    29 
       
    30 #include <memory>
       
    31 
    25 
    32 #include <lemon/error.h>
    26 #include <lemon/error.h>
    33 
    27 #include <lemon/lemon_reader.h>
    34 
    28 
    35 namespace lemon {
    29 namespace lemon {
    36 
    30 
    37   /// \addtogroup io_group
    31   /// \addtogroup io_group
    38   /// @{
    32   /// @{
    39 
    33 
    40   /// \brief Standard ReaderTraits for the GraphReader class.
       
    41   ///
       
    42   /// Standard ReaderTraits for the GraphReader class.
       
    43   /// It defines standard reading method for all type of value. 
       
    44   /// \author Balazs Dezso
       
    45   struct DefaultReaderTraits {
       
    46 
       
    47     /// \brief Template class for reading an value.
       
    48     ///
       
    49     /// Template class for reading an value.
       
    50     /// \author Balazs Dezso
       
    51     template <typename _Value>
       
    52     struct Reader {
       
    53       /// The value type.
       
    54       typedef _Value Value;
       
    55       /// \brief Reads a value from the given stream.
       
    56       ///
       
    57       /// Reads a value from the given stream.
       
    58       void read(std::istream& is, Value& value) {
       
    59 	if (!(is >> value)) 
       
    60 	  throw DataFormatError("Default reader format exception");
       
    61       }
       
    62     };
       
    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 
       
    71     /// The reader class for the not needed maps.
       
    72     typedef Reader<std::string> DefaultReader;
       
    73 
       
    74   };
       
    75 
       
    76   /// \brief Reader class for quoted strings.
       
    77   ///
       
    78   /// Reader class for quoted strings. It can process the escape
       
    79   /// sequences in the string.
       
    80   /// \author Balazs Dezso
       
    81   class QuotedStringReader {
       
    82   public:
       
    83     typedef std::string Value;
       
    84     
       
    85     /// \brief Constructor for the reader.
       
    86     ///
       
    87     /// Constructor for the reader. If the given parameter is true
       
    88     /// the reader processes the escape sequences.
       
    89     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
       
    90     
       
    91     /// \brief Reads a quoted string from the given stream.
       
    92     ///
       
    93     /// Reads a quoted string from the given stream.
       
    94     void read(std::istream& is, std::string& value) {
       
    95       char c;
       
    96       value.clear();
       
    97       is >> std::ws;
       
    98       if (!is.get(c) || c != '\"') 
       
    99 	throw DataFormatError("Quoted string format error");
       
   100       while (is.get(c) && c != '\"') {
       
   101 	if (escaped && c == '\\') {
       
   102 	  value += readEscape(is);
       
   103 	} else {
       
   104 	  value += c;
       
   105 	}
       
   106       }
       
   107       if (!is) throw DataFormatError("Quoted string format error");
       
   108     }
       
   109 
       
   110   private:
       
   111     
       
   112     static char readEscape(std::istream& is) {
       
   113       char c;
       
   114       switch (is.get(c), c) {
       
   115       case '\\':
       
   116 	return '\\';
       
   117       case '\"':
       
   118 	return '\"';
       
   119       case '\'':
       
   120 	return '\'';
       
   121       case '\?':
       
   122 	return '\?';
       
   123       case 'a':
       
   124 	return '\a';
       
   125       case 'b':
       
   126 	return '\b';
       
   127       case 'f':
       
   128 	return '\f';
       
   129       case 'n':
       
   130 	return '\n';
       
   131       case 'r':
       
   132 	return '\r';
       
   133       case 't':
       
   134 	return '\t';
       
   135       case 'v':
       
   136 	return '\v';
       
   137       case 'x':
       
   138 	{
       
   139 	  int code;
       
   140 	  if (!is.get(c) || !isHex(c)) 
       
   141 	    throw DataFormatError("Escape format error");
       
   142 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
       
   143 	  else code = code * 16 + valueHex(c);
       
   144 	  return code;
       
   145 	}
       
   146       default:
       
   147 	{
       
   148 	  int code;
       
   149 	  if (!isOct(c)) 
       
   150 	    throw DataFormatError("Escape format error");
       
   151 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
       
   152 	    is.putback(c);
       
   153 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
       
   154 	    is.putback(c);
       
   155 	  else code = code * 8 + valueOct(c);
       
   156 	  return code;
       
   157 	}	      
       
   158       } 
       
   159     }
       
   160 
       
   161     static bool isOct(char c) {
       
   162       return '0' <= c && c <='7'; 
       
   163     }
       
   164     
       
   165     static int valueOct(char c) {
       
   166       return c - '0';
       
   167     }
       
   168 
       
   169    static bool isHex(char c) {
       
   170       return ('0' <= c && c <= '9') || 
       
   171 	('a' <= c && c <= 'z') || 
       
   172 	('A' <= c && c <= 'Z'); 
       
   173     }
       
   174     
       
   175     static int valueHex(char c) {
       
   176       if ('0' <= c && c <= '9') return c - '0';
       
   177       if ('a' <= c && c <= 'z') return c - 'a' + 10;
       
   178       return c - 'A' + 10;
       
   179     }
       
   180 
       
   181     bool escaped;
       
   182   };
       
   183 
       
   184   class GUIReader {
       
   185   public:
       
   186     virtual void read(std::istream& is) = 0;
       
   187   };
       
   188 
       
   189   /// \brief The graph reader class.
    34   /// \brief The graph reader class.
   190   ///
       
   191   ///
    35   ///
   192   /// The given file format may contain several maps and labeled nodes or 
    36   /// The given file format may contain several maps and labeled nodes or 
   193   /// edges.
    37   /// edges.
   194   ///
    38   ///
   195   /// If you read a graph you need not read all the maps and items just those
    39   /// If you read a graph you need not read all the maps and items just those
   227   /// \code
    71   /// \code
   228   /// reader.readEdgeMap("weight", weightMap);
    72   /// reader.readEdgeMap("weight", weightMap);
   229   /// reader.readEdgeMap("label", labelMap);
    73   /// reader.readEdgeMap("label", labelMap);
   230   /// \endcode
    74   /// \endcode
   231   ///
    75   ///
   232   /// With \c readNode() and \c readEdge() functions you can read labeled Nodes 
    76   /// With \c readNode() and \c readEdge() functions you can read 
   233   /// and Edges.
    77   /// labeled Nodes and Edges.
   234   ///
    78   ///
   235   /// \code
    79   /// \code
   236   /// reader.readNode("source", sourceNode);
    80   /// reader.readNode("source", sourceNode);
   237   /// reader.readNode("target", targetNode);
    81   /// reader.readNode("target", targetNode);
   238   ///
    82   ///
   239   /// reader.readEdge("observed", edge);
    83   /// reader.readEdge("observed", edge);
   240   /// \endcode
    84   /// \endcode
       
    85   ///
       
    86   /// With the \c readAttribute() functions you can read an attribute
       
    87   /// in a variable. You can specify the reader for the attribute as
       
    88   /// the nodemaps.
   241   ///
    89   ///
   242   /// After you give all read commands you must call the \c run() member
    90   /// After you give all read commands you must call the \c run() member
   243   /// function, which execute all the commands.
    91   /// function, which execute all the commands.
   244   ///
    92   ///
   245   /// \code
    93   /// \code
   258     typedef _Graph Graph;
   106     typedef _Graph Graph;
   259     typedef typename Graph::Node Node;
   107     typedef typename Graph::Node Node;
   260     typedef typename Graph::Edge Edge;
   108     typedef typename Graph::Edge Edge;
   261 
   109 
   262     typedef _ReaderTraits ReaderTraits;
   110     typedef _ReaderTraits ReaderTraits;
   263     typedef typename ReaderTraits::DefaultReader DefaultReader;
   111     typedef typename ReaderTraits::Skipper DefaultSkipper;
   264 
   112 
   265     /// \brief Construct a new GraphReader.
   113     /// \brief Construct a new GraphReader.
   266     ///
   114     ///
   267     /// Construct a new GraphReader. It reads into the given graph
   115     /// Construct a new GraphReader. It reads into the given graph
   268     /// and it use the given reader as the default skipper.
   116     /// and it use the given reader as the default skipper.
   269     GraphReader(std::istream& _is, Graph& _graph, 
   117     GraphReader(std::istream& _is, Graph& _graph, 
   270 		const DefaultReader& _reader = DefaultReader()) 
   118 		const DefaultSkipper& _skipper = DefaultSkipper()) 
   271       : gui_reader(0), is(_is), graph(_graph), 
   119       : reader(new LemonReader(_is)), own_reader(true), 
   272 	nodeSkipper(_reader), edgeSkipper(_reader) {}
   120 	graph(_graph), skipper(_skipper),
       
   121 	nodeset_reader(*reader, graph, std::string(), skipper),
       
   122 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
       
   123 	node_reader(*reader, nodeset_reader, std::string()),
       
   124 	edge_reader(*reader, edgeset_reader, std::string()),
       
   125 	attribute_reader(*reader, std::string()) {}
       
   126 
       
   127     /// \brief Construct a new GraphReader.
       
   128     ///
       
   129     /// Construct a new GraphReader. It reads into the given graph
       
   130     /// and it use the given reader as the default skipper.
       
   131     GraphReader(const std::string& _filename, Graph& _graph, 
       
   132 		const DefaultSkipper& _skipper = DefaultSkipper()) 
       
   133       : reader(new LemonReader(_filename)), own_reader(true), 
       
   134 	graph(_graph), skipper(_skipper),
       
   135 	nodeset_reader(*reader, graph, std::string(), skipper),
       
   136 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
       
   137 	node_reader(*reader, nodeset_reader, std::string()),
       
   138 	edge_reader(*reader, edgeset_reader, std::string()),
       
   139 	attribute_reader(*reader, std::string()) {}
       
   140 
       
   141     /// \brief Construct a new GraphReader.
       
   142     ///
       
   143     /// Construct a new GraphReader. It reads into the given graph
       
   144     /// and it use the given reader as the default skipper.
       
   145     GraphReader(LemonReader& _reader, Graph& _graph, 
       
   146 		const DefaultSkipper& _skipper = DefaultSkipper()) 
       
   147       : reader(_reader), own_reader(false), 
       
   148 	graph(_graph), skipper(_skipper),
       
   149 	nodeset_reader(*reader, graph, std::string(), skipper),
       
   150 	edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
       
   151 	node_reader(*reader, nodeset_reader, std::string()),
       
   152 	edge_reader(*reader, edgeset_reader, std::string()),
       
   153 	attribute_reader(*reader, std::string()) {}
   273 
   154 
   274     /// \brief Destruct the graph reader.
   155     /// \brief Destruct the graph reader.
   275     ///
   156     ///
   276     /// Destruct the graph reader.
   157     /// Destruct the graph reader.
   277     ~GraphReader() {
   158     ~GraphReader() {
   278       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
   159       if (own_reader) 
   279 	   it != node_map_readers.end(); ++it) {
   160 	delete reader;
   280 	delete it->second;
       
   281       }
       
   282 
       
   283       for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); 
       
   284 	   it != edge_map_readers.end(); ++it) {
       
   285 	delete it->second;
       
   286       }
       
   287 
       
   288     }
   161     }
   289 
   162 
   290     /// \brief Add a new node map reader command for the reader.
   163     /// \brief Add a new node map reader command for the reader.
   291     ///
   164     ///
   292     /// Add a new node map reader command for the reader.
   165     /// Add a new node map reader command for the reader.
   293     template <typename Map>
   166     template <typename Map>
   294     GraphReader& readNodeMap(std::string name, Map& map) {
   167     GraphReader& readNodeMap(std::string name, Map& map) {
   295       return readNodeMap<typename ReaderTraits::template 
   168       nodeset_reader.readMap(name, map);
   296 	Reader<typename Map::Value>, Map>(name, map);
   169       return *this;
   297     }
   170     }
   298 
   171 
   299     /// \brief Add a new node map reader command for the reader.
   172     /// \brief Add a new node map reader command for the reader.
   300     ///
   173     ///
   301     /// Add a new node map reader command for the reader.
   174     /// Add a new node map reader command for the reader.
   302     template <typename Reader, typename Map>
   175     template <typename Reader, typename Map>
   303     GraphReader& readNodeMap(std::string name, Map& map, 
   176     GraphReader& readNodeMap(std::string name, Map& map, 
   304 			     const Reader& reader = Reader()) {
   177 			     const Reader& reader = Reader()) {
   305       if (node_map_readers.find(name) != node_map_readers.end()) {
   178       nodeset_reader.readMap(name, map, reader);
   306 	ErrorMessage msg;
       
   307 	msg << "Multiple read rule for node map: " << name;
       
   308 	throw IOParameterError(msg.message());
       
   309       }
       
   310       node_map_readers.insert(
       
   311         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
       
   312       return *this;
   179       return *this;
   313     }
   180     }
   314 
   181 
   315     /// \brief Add a new node map skipper command for the reader.
   182     /// \brief Add a new node map skipper command for the reader.
   316     ///
   183     ///
   317     /// Add a new node map skipper command for the reader.
   184     /// Add a new node map skipper command for the reader.
   318     template <typename Reader>
   185     template <typename Reader>
   319     GraphReader& skipNodeMap(std::string name, 
   186     GraphReader& skipNodeMap(std::string name, 
   320 			     const Reader& reader = Reader()) {
   187 			     const Reader& reader = Reader()) {
   321       if (node_map_readers.find(name) != node_map_readers.end()) {
   188       nodeset_reader.skipMap(name, reader);
   322 	ErrorMessage msg;
       
   323 	msg << "Multiple read rule for node map: " << name;
       
   324 	throw IOParameterError(msg.message());
       
   325       }
       
   326       node_map_readers.insert(
       
   327         make_pair(name, new SkipReader<Node, Reader>(reader)));
       
   328       return *this;
   189       return *this;
   329     }
   190     }
   330 
   191 
   331     /// \brief Add a new edge map reader command for the reader.
   192     /// \brief Add a new edge map reader command for the reader.
   332     ///
   193     ///
   333     /// Add a new edge map reader command for the reader.
   194     /// Add a new edge map reader command for the reader.
   334     template <typename Map>
   195     template <typename Map>
   335     GraphReader& readEdgeMap(std::string name, Map& map) { 
   196     GraphReader& readEdgeMap(std::string name, Map& map) { 
   336       return readEdgeMap<typename ReaderTraits::template
   197       edgeset_reader.readMap(name, map);
   337 	Reader<typename Map::Value>, Map>(name, map);
   198       return *this;
   338     }
   199     }
   339 
   200 
   340 
   201 
   341     /// \brief Add a new edge map reader command for the reader.
   202     /// \brief Add a new edge map reader command for the reader.
   342     ///
   203     ///
   343     /// Add a new edge map reader command for the reader.
   204     /// Add a new edge map reader command for the reader.
   344     template <typename Reader, typename Map>
   205     template <typename Reader, typename Map>
   345     GraphReader& readEdgeMap(std::string name, Map& map,
   206     GraphReader& readEdgeMap(std::string name, Map& map,
   346 			     const Reader& reader = Reader()) {
   207 			     const Reader& reader = Reader()) {
   347       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   208       edgeset_reader.readMap(name, map, reader);
   348 	ErrorMessage msg;
       
   349 	msg << "Multiple read rule for edge map: " << name;
       
   350 	throw IOParameterError(msg.message());
       
   351       }
       
   352       edge_map_readers.insert(
       
   353         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
       
   354       return *this;
   209       return *this;
   355     }
   210     }
   356 
   211 
   357     /// \brief Add a new edge map skipper command for the reader.
   212     /// \brief Add a new edge map skipper command for the reader.
   358     ///
   213     ///
   359     /// Add a new edge map skipper command for the reader.
   214     /// Add a new edge map skipper command for the reader.
   360     template <typename Reader>
   215     template <typename Reader>
   361     GraphReader& skipEdgeMap(std::string name,
   216     GraphReader& skipEdgeMap(std::string name,
   362 			     const Reader& reader = Reader()) {
   217 			     const Reader& reader = Reader()) {
   363       if (edge_map_readers.find(name) != edge_map_readers.end()) {
   218 
   364 	ErrorMessage msg;
   219       edgeset_reader.skipMap(name, reader);
   365 	msg << "Multiple read rule for edge map: " << name;
       
   366 	throw IOParameterError(msg.message());
       
   367       }
       
   368       edge_map_readers.insert(
       
   369         make_pair(name, new SkipReader<Edge, Reader>(reader)));
       
   370       return *this;
   220       return *this;
   371     }
   221     }
   372 
   222 
   373     /// \brief Add a new labeled node reader for the reader.
   223     /// \brief Add a new labeled node reader for the reader.
   374     ///
   224     ///
   375     /// Add a new labeled node reader for the reader.
   225     /// Add a new labeled node reader for the reader.
   376     GraphReader& readNode(std::string name, Node& node) {
   226     GraphReader& readNode(std::string name, Node& node) {
   377       if (node_readers.find(name) != node_readers.end()) {
   227       node_reader.readNode(name, node);
   378 	ErrorMessage msg;
       
   379 	msg << "Multiple read rule for node: " << name;
       
   380 	throw IOParameterError(msg.message());
       
   381       }
       
   382       node_readers.insert(make_pair(name, &node));
       
   383       return *this;
   228       return *this;
   384     }
   229     }
   385 
   230 
   386     /// \brief Add a new labeled edge reader for the reader.
   231     /// \brief Add a new labeled edge reader for the reader.
   387     ///
   232     ///
   388     /// Add a new labeled edge reader for the reader.
   233     /// Add a new labeled edge reader for the reader.
   389     GraphReader& readEdge(std::string name, Edge& edge) {
   234     GraphReader& readEdge(std::string name, Edge& edge) {
   390       if (edge_readers.find(name) != edge_readers.end()) {
   235       edge_reader.readEdge(name, edge);
   391 	ErrorMessage msg;
   236     }
   392 	msg << "Multiple read rule for edge: " << name;
   237 
   393 	throw IOParameterError(msg.message());
   238     /// \brief Add a new attribute reader command.
   394       }
   239     ///
   395       edge_readers.insert(make_pair(name, &edge));
   240     ///  Add a new attribute reader command.
   396       return *this;
   241     template <typename Value>
       
   242     GraphReader& readAttribute(std::string name, Value& value) {
       
   243       attribute_reader.readAttribute(name, value);
       
   244       return *this;
       
   245     }
       
   246     
       
   247     /// \brief Add a new attribute reader command.
       
   248     ///
       
   249     ///  Add a new attribute reader command.
       
   250     template <typename Reader, typename Value>
       
   251     GraphReader& readAttribute(std::string name, Value& value, 
       
   252 			       const Reader& reader) {
       
   253       attribute_reader.readAttribute<Reader>(name, value, reader);
       
   254       return *this;
       
   255     }
       
   256 
       
   257     /// \brief Conversion operator to LemonReader.
       
   258     ///
       
   259     /// Conversion operator to LemonReader. It make possible
       
   260     /// to access the encapsulated \e LemonReader, this way
       
   261     /// you can attach to this reader new instances of 
       
   262     /// \e LemonReader::SectionReader.
       
   263     operator LemonReader&() {
       
   264       return *reader;
   397     }
   265     }
   398 
   266 
   399     /// \brief Executes the reader commands.
   267     /// \brief Executes the reader commands.
   400     ///
   268     ///
   401     /// Executes the reader commands.
   269     /// Executes the reader commands.
   402     void run() {
   270     void run() {
   403       int line_num = 0;
   271       reader->run();
   404       std::auto_ptr<InverterBase<Node> > nodeInverter;
       
   405       std::auto_ptr<InverterBase<Edge> > edgeInverter;
       
   406       try {
       
   407 	std::string line = readNotEmptyLine(is, line_num);
       
   408 	if (line.find("@nodeset") == 0) {
       
   409 	  line = readNodeSet(line_num, nodeInverter);
       
   410 	} 
       
   411 	if (line.find("@edgeset") == 0) {
       
   412 	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
       
   413 	}
       
   414 	if (line.find("@nodes") == 0) {
       
   415 	  line = readNodes(line_num, nodeInverter);
       
   416 	}
       
   417 	if (line.find("@edges") == 0) {
       
   418 	  line = readEdges(line_num, edgeInverter);
       
   419 	}
       
   420 	if (line.find("@gui") == 0) {
       
   421 	  line = readGUI(line_num);
       
   422 	}
       
   423 	if (line.find("@end") != 0) {
       
   424 	  throw DataFormatError("Invalid control sequence error");
       
   425 	}
       
   426       } catch (DataFormatError e) {
       
   427 	e.line(line_num);
       
   428 	throw e;
       
   429       }
       
   430     }
       
   431 
       
   432     GraphReader& readGUI(GUIReader& reader) {
       
   433       gui_reader = &reader;
       
   434       return *this;
       
   435     }
   272     }
   436 
   273 
   437   private:
   274   private:
   438 
   275 
   439     template <typename Item> class InverterBase;
   276     LemonReader* reader;
   440 
   277     bool own_reader;
   441     std::string readNodeSet(int& line_num, 
   278 
   442 			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
   279     Graph& graph;
   443       std::vector<ReaderBase<Node>* > index;
   280 
   444       {
   281     DefaultSkipper skipper;
   445 	std::string line = readNotEmptyLine(is, line_num);    
   282 
   446 	std::string id;
   283     NodeSetReader<Graph, ReaderTraits> nodeset_reader;
   447 	std::istringstream ls(line);	
   284     EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
   448 	while (ls >> id) {
   285 
   449 	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
   286     NodeReader<Graph> node_reader;
   450 	  if (it != node_map_readers.end()) {
   287     EdgeReader<Graph> edge_reader;
   451 	    index.push_back(it->second);
       
   452 	    node_map_readers.erase(it);
       
   453 	  } else {
       
   454 	    index.push_back(&nodeSkipper);
       
   455 	  }
       
   456 	  if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
       
   457 	    nodeInverter.reset(index.back()->getInverter());
       
   458 	    index.back() = nodeInverter.get();
       
   459 	  }
       
   460 	}
       
   461       }
       
   462 
       
   463 //       if (index.size() == 0) {
       
   464 // 	throw DataFormatError("Cannot find node id map");
       
   465 //       }
       
   466 
       
   467 //       nodeInverter = 
       
   468 // 	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
       
   469       std::string line;
       
   470       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
       
   471 	Node node = graph.addNode();
       
   472 	std::istringstream ls(line);
       
   473 	for (int i = 0; i < (int)index.size(); ++i) {
       
   474 	  index[i]->read(ls, node);
       
   475 	}
       
   476       }
       
   477       return line;
       
   478     }
       
   479 
       
   480     std::string readEdgeSet(int& line_num, 
       
   481 			    std::auto_ptr<InverterBase<Edge> >& edgeInverter, 
       
   482 			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
       
   483       std::vector<ReaderBase<Edge>*> index;
       
   484       {
       
   485 	std::string line = readNotEmptyLine(is, line_num);    
       
   486 	std::string id;
       
   487 	std::istringstream ls(line);	
       
   488 	while (ls >> id) {
       
   489 	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
       
   490 	  if (it != edge_map_readers.end()) {
       
   491 	    index.push_back(it->second);
       
   492 	    edge_map_readers.erase(it);
       
   493 	  } else {
       
   494 	    index.push_back(&edgeSkipper);
       
   495 	  }
       
   496 	  if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
       
   497 	    edgeInverter.reset(index.back()->getInverter());
       
   498 	    index.back() = edgeInverter.get();
       
   499 	  }
       
   500 	}
       
   501       }
       
   502       
       
   503       if (nodeInverter.get() == 0) {
       
   504  	throw DataFormatError("Cannot find node id map");
       
   505       }
       
   506 //       if (index.size() == 0) {
       
   507 // 	throw DataFormatError("Cannot find edge id map");
       
   508 //       }
       
   509 
       
   510 //       edgeInverter = 
       
   511 // 	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
       
   512       std::string line;
       
   513       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
       
   514 	std::istringstream ls(line);
       
   515 	Node source = nodeInverter->read(ls);
       
   516 	Node target = nodeInverter->read(ls);
       
   517 	Edge edge = graph.addEdge(source, target);
       
   518 	for (int i = 0; i < (int)index.size(); ++i) {
       
   519 	  index[i]->read(ls, edge);
       
   520 	}
       
   521       }      
       
   522       return line;
       
   523     }
       
   524 
       
   525     std::string readNodes(int& line_num, 
       
   526 			  std::auto_ptr<InverterBase<Node> >& nodeInverter) {
       
   527       std::string line;
       
   528       if (nodeInverter.get() == 0) {
       
   529  	throw DataFormatError("Cannot find node id map");
       
   530       }
       
   531       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
       
   532 	std::istringstream ls(line);
       
   533 	std::string name;
       
   534 	ls >> name;
       
   535 	typename NodeReaders::iterator it = node_readers.find(name);
       
   536 	if (it != node_readers.end()) {
       
   537 	  *(it -> second) = nodeInverter->read(ls);
       
   538 	} 
       
   539       }        
       
   540       return line;
       
   541     }
       
   542 
       
   543     std::string readEdges(int& line_num, 
       
   544 			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
       
   545       std::string line;
       
   546       if (edgeInverter.get() == 0) {
       
   547  	throw DataFormatError("Cannot find edge id map");
       
   548       }
       
   549       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
       
   550 	std::istringstream ls(line);
       
   551 	std::string name;
       
   552 	ls >> name;
       
   553 	typename EdgeReaders::iterator it = edge_readers.find(name);
       
   554 	if (it != edge_readers.end()) {
       
   555 	  *(it -> second) = edgeInverter->read(ls);
       
   556 	} 
       
   557       }        
       
   558       return line;    
       
   559     }
       
   560 
       
   561     std::string readGUI(int& line_num) {
       
   562       std::stringstream section;
       
   563       std::string line;
       
   564       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
       
   565 	section << line << std::endl;
       
   566       }
       
   567       if (gui_reader != 0) {
       
   568 	gui_reader->read(section);
       
   569       }
       
   570       return line;
       
   571     }
       
   572 
       
   573     std::string readNotEmptyLine(std::istream& is, int& line_num) {
       
   574       std::string line;
       
   575       while (++line_num, getline(is, line)) {	
       
   576 	int vi = line.find('#');
       
   577 	if (vi != (int)::std::string::npos) {
       
   578 	  line = line.substr(0, vi);
       
   579 	}
       
   580 	vi = line.find_first_not_of(" \t");
       
   581 	if (vi != (int)std::string::npos) { 
       
   582 	  return line.substr(vi);
       
   583 	}
       
   584       }
       
   585       throw DataFormatError("End of stream error");
       
   586     }
       
   587     
   288     
   588     template <typename _Item>
   289     AttributeReader<ReaderTraits> attribute_reader;
   589     class ReaderBase;
       
   590     
       
   591     template <typename _Item>
       
   592     class InverterBase : public ReaderBase<_Item> {
       
   593     public:
       
   594       typedef _Item Item;
       
   595       virtual void read(std::istream&, const Item&) = 0;
       
   596       virtual Item read(std::istream&) = 0;
       
   597 
       
   598       virtual InverterBase<_Item>* getInverter() {
       
   599 	return this;
       
   600       }
       
   601     };
       
   602 
       
   603     template <typename _Item, typename _Map, typename _Reader>
       
   604     class MapReaderInverter : public InverterBase<_Item> {
       
   605     public:
       
   606       typedef _Item Item;
       
   607       typedef _Reader Reader;
       
   608       typedef typename Reader::Value Value;
       
   609       typedef _Map Map;
       
   610       typedef std::map<Value, Item> Inverse;
       
   611 
       
   612       Map& map;
       
   613       Reader reader;
       
   614       Inverse inverse;
       
   615 
       
   616       MapReaderInverter(Map& _map, const Reader& _reader) 
       
   617 	: map(_map), reader(_reader) {}
       
   618 
       
   619       virtual ~MapReaderInverter() {}
       
   620 
       
   621       virtual void read(std::istream& is, const Item& item) {
       
   622 	Value value;
       
   623 	reader.read(is, value);
       
   624 	map.set(item, value);
       
   625 	typename Inverse::iterator it = inverse.find(value);
       
   626 	if (it == inverse.end()) {
       
   627 	  inverse.insert(std::make_pair(value, item));
       
   628 	} else {
       
   629 	  throw DataFormatError("Multiple ID occurence");
       
   630 	}
       
   631       }
       
   632 
       
   633       virtual Item read(std::istream& is) {
       
   634 	Value value;
       
   635 	reader.read(is, value);	
       
   636 	typename Inverse::const_iterator it = inverse.find(value);
       
   637 	if (it != inverse.end()) {
       
   638 	  return it->second;
       
   639 	} else {
       
   640 	  throw DataFormatError("Invalid ID error");
       
   641 	}
       
   642       }      
       
   643     };
       
   644 
       
   645     template <typename _Item, typename _Reader>
       
   646     class SkipReaderInverter : public InverterBase<_Item> {
       
   647     public:
       
   648       typedef _Item Item;
       
   649       typedef _Reader Reader;
       
   650       typedef typename Reader::Value Value;
       
   651       typedef std::map<Value, Item> Inverse;
       
   652 
       
   653       Reader reader;
       
   654 
       
   655       SkipReaderInverter(const Reader& _reader) 
       
   656 	: reader(_reader) {}
       
   657 
       
   658       virtual ~SkipReaderInverter() {}
       
   659 
       
   660       virtual void read(std::istream& is, const Item& item) {
       
   661 	Value value;
       
   662 	reader.read(is, value);
       
   663 	typename Inverse::iterator it = inverse.find(value);
       
   664 	if (it == inverse.end()) {
       
   665 	  inverse.insert(std::make_pair(value, item));
       
   666 	} else {
       
   667 	  throw DataFormatError("Multiple ID occurence error");
       
   668 	}
       
   669       }
       
   670 
       
   671       virtual Item read(std::istream& is) {
       
   672 	Value value;
       
   673 	reader.read(is, value);	
       
   674 	typename Inverse::const_iterator it = inverse.find(value);
       
   675 	if (it != inverse.end()) {
       
   676 	  return it->second;
       
   677 	} else {
       
   678 	  throw DataFormatError("Invalid ID error");
       
   679 	}
       
   680       }      
       
   681     private:
       
   682       Inverse inverse;
       
   683     };
       
   684 
       
   685     // Readers
       
   686 
       
   687     template <typename _Item>    
       
   688     class ReaderBase {
       
   689     public:
       
   690       typedef _Item Item;
       
   691 
       
   692       //      virtual ~ReaderBase() {}
       
   693 
       
   694       virtual void read(std::istream& is, const Item& item) = 0;
       
   695       virtual InverterBase<_Item>* getInverter() = 0;
       
   696     };
       
   697 
       
   698     template <typename _Item, typename _Map, typename _Reader>
       
   699     class MapReader : public ReaderBase<_Item> {
       
   700     public:
       
   701       typedef _Map Map;
       
   702       typedef _Reader Reader;
       
   703       typedef typename Reader::Value Value;
       
   704       typedef _Item Item;
       
   705       
       
   706       Map& map;
       
   707       Reader reader;
       
   708 
       
   709       MapReader(Map& _map, const Reader& _reader) 
       
   710 	: map(_map), reader(_reader) {}
       
   711 
       
   712       virtual ~MapReader() {}
       
   713 
       
   714       virtual void read(std::istream& is, const Item& item) {
       
   715 	Value value;
       
   716 	reader.read(is, value);
       
   717 	map.set(item, value);
       
   718       }
       
   719 
       
   720       virtual InverterBase<_Item>* getInverter() {
       
   721 	return new MapReaderInverter<Item, Map, Reader>(map, reader);
       
   722       }
       
   723     };
       
   724 
       
   725 
       
   726     template <typename _Item, typename _Reader>
       
   727     class SkipReader : public ReaderBase<_Item> {
       
   728     public:
       
   729       typedef _Reader Reader;
       
   730       typedef typename Reader::Value Value;
       
   731       typedef _Item Item;
       
   732 
       
   733       Reader reader;
       
   734       SkipReader(const Reader& _reader) : reader(_reader) {}
       
   735 
       
   736       virtual ~SkipReader() {}
       
   737 
       
   738       virtual void read(std::istream& is, const Item&) {
       
   739 	Value value;
       
   740 	reader.read(is, value);
       
   741       }      
       
   742 
       
   743       virtual InverterBase<Item>* getInverter() {
       
   744 	return new SkipReaderInverter<Item, Reader>(reader);
       
   745       }
       
   746     };
       
   747 
       
   748 
       
   749     typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
       
   750     NodeMapReaders node_map_readers;
       
   751 
       
   752     typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
       
   753     EdgeMapReaders edge_map_readers;
       
   754 
       
   755     typedef std::map<std::string, Node*> NodeReaders;
       
   756     NodeReaders node_readers;
       
   757 
       
   758     typedef std::map<std::string, Edge*> EdgeReaders;
       
   759     EdgeReaders edge_readers;
       
   760 
       
   761     GUIReader* gui_reader;
       
   762 
       
   763     std::istream& is;
       
   764     Graph& graph;
       
   765 
       
   766     SkipReader<Node, DefaultReader> nodeSkipper;
       
   767     SkipReader<Edge, DefaultReader> edgeSkipper;
       
   768 
       
   769   };
   290   };
   770 
   291 
   771   /// \brief Read a graph from the input.
   292   /// \brief Read a graph from the input.
   772   ///
   293   ///
   773   /// Read a graph from the input.
   294   /// Read a graph from the input.