lemon/lgf_reader.h
author Balazs Dezso <deba@inf.elte.hu>
Tue, 27 May 2008 16:01:20 +0200
changeset 162 33247f6fff16
parent 156 e561aa7675de
child 163 c82fd9568d75
permissions -rw-r--r--
Section reader for DigraphReader
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup lemon_io
    20 ///\file
    21 ///\brief Lemon Graph Format reader.
    22 
    23 
    24 #ifndef LEMON_LGF_READER_H
    25 #define LEMON_LGF_READER_H
    26 
    27 #include <iostream>
    28 #include <fstream>
    29 #include <sstream>
    30 
    31 #include <set>
    32 #include <map>
    33 
    34 #include <lemon/assert.h>
    35 #include <lemon/graph_utils.h>
    36 
    37 #include <lemon/lgf_writer.h>
    38 
    39 #include <lemon/concept_check.h>
    40 #include <lemon/concepts/maps.h>
    41 
    42 namespace lemon {
    43 
    44   namespace _reader_bits {
    45 
    46     template <typename Value>
    47     struct DefaultConverter {
    48       Value operator()(const std::string& str) {
    49 	std::istringstream is(str);
    50 	Value value;
    51 	is >> value;
    52 
    53 	char c;
    54 	if (is >> std::ws >> c) {
    55 	  throw DataFormatError("Remaining characters in token");
    56 	}
    57 	return value;
    58       }
    59     };
    60 
    61     template <>
    62     struct DefaultConverter<std::string> {
    63       std::string operator()(const std::string& str) {
    64 	return str;
    65       }
    66     };
    67 
    68     template <typename _Item>    
    69     class MapStorageBase {
    70     public:
    71       typedef _Item Item;
    72 
    73     public:
    74       MapStorageBase() {}
    75       virtual ~MapStorageBase() {}
    76 
    77       virtual void set(const Item& item, const std::string& value) = 0;
    78 
    79     };
    80 
    81     template <typename _Item, typename _Map, 
    82 	      typename _Converter = DefaultConverter<typename _Map::Value> >
    83     class MapStorage : public MapStorageBase<_Item> {
    84     public:
    85       typedef _Map Map;
    86       typedef _Converter Converter;
    87       typedef _Item Item;
    88       
    89     private:
    90       Map& _map;
    91       Converter _converter;
    92 
    93     public:
    94       MapStorage(Map& map, const Converter& converter = Converter()) 
    95 	: _map(map), _converter(converter) {}
    96       virtual ~MapStorage() {}
    97 
    98       virtual void set(const Item& item ,const std::string& value) {
    99 	_map.set(item, _converter(value));
   100       }
   101     };
   102 
   103     class ValueStorageBase {
   104     public:
   105       ValueStorageBase() {}
   106       virtual ~ValueStorageBase() {}
   107 
   108       virtual void set(const std::string&) = 0;
   109     };
   110 
   111     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
   112     class ValueStorage : public ValueStorageBase {
   113     public:
   114       typedef _Value Value;
   115       typedef _Converter Converter;
   116 
   117     private:
   118       Value& _value;
   119       Converter _converter;
   120 
   121     public:
   122       ValueStorage(Value& value, const Converter& converter = Converter())
   123  	: _value(value), _converter(converter) {}
   124 
   125       virtual void set(const std::string& value) {
   126 	_value = _converter(value);
   127       }
   128     };
   129 
   130     template <typename Value>
   131     struct MapLookUpConverter {
   132       const std::map<std::string, Value>& _map;
   133 
   134       MapLookUpConverter(const std::map<std::string, Value>& map)
   135         : _map(map) {}
   136 
   137       Value operator()(const std::string& str) {
   138         typename std::map<std::string, Value>::const_iterator it =
   139           _map.find(str);
   140         if (it == _map.end()) {
   141           std::ostringstream msg;
   142           msg << "Item not found: " << str;
   143           throw DataFormatError(msg.str().c_str());
   144         }
   145         return it->second;
   146       }
   147     };
   148 
   149     bool isWhiteSpace(char c) {
   150       return c == ' ' || c == '\t' || c == '\v' || 
   151         c == '\n' || c == '\r' || c == '\f'; 
   152     }
   153     
   154     bool isOct(char c) {
   155       return '0' <= c && c <='7'; 
   156     }
   157     
   158     int valueOct(char c) {
   159       LEMON_ASSERT(isOct(c), "The character is not octal.");
   160       return c - '0';
   161     }
   162 
   163     bool isHex(char c) {
   164       return ('0' <= c && c <= '9') || 
   165 	('a' <= c && c <= 'z') || 
   166 	('A' <= c && c <= 'Z'); 
   167     }
   168     
   169     int valueHex(char c) {
   170       LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
   171       if ('0' <= c && c <= '9') return c - '0';
   172       if ('a' <= c && c <= 'z') return c - 'a' + 10;
   173       return c - 'A' + 10;
   174     }
   175 
   176     bool isIdentifierFirstChar(char c) {
   177       return ('a' <= c && c <= 'z') ||
   178 	('A' <= c && c <= 'Z') || c == '_';
   179     }
   180 
   181     bool isIdentifierChar(char c) {
   182       return isIdentifierFirstChar(c) ||
   183 	('0' <= c && c <= '9');
   184     }
   185 
   186     char readEscape(std::istream& is) {
   187       char c;
   188       if (!is.get(c))
   189 	throw DataFormatError("Escape format error");
   190 
   191       switch (c) {
   192       case '\\':
   193 	return '\\';
   194       case '\"':
   195 	return '\"';
   196       case '\'':
   197 	return '\'';
   198       case '\?':
   199 	return '\?';
   200       case 'a':
   201 	return '\a';
   202       case 'b':
   203 	return '\b';
   204       case 'f':
   205 	return '\f';
   206       case 'n':
   207 	return '\n';
   208       case 'r':
   209 	return '\r';
   210       case 't':
   211 	return '\t';
   212       case 'v':
   213 	return '\v';
   214       case 'x':
   215 	{
   216 	  int code;
   217 	  if (!is.get(c) || !isHex(c)) 
   218 	    throw DataFormatError("Escape format error");
   219 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
   220 	  else code = code * 16 + valueHex(c);
   221 	  return code;
   222 	}
   223       default:
   224 	{
   225 	  int code;
   226 	  if (!isOct(c)) 
   227 	    throw DataFormatError("Escape format error");
   228 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
   229 	    is.putback(c);
   230 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
   231 	    is.putback(c);
   232 	  else code = code * 8 + valueOct(c);
   233 	  return code;
   234 	}	      
   235       } 
   236     }
   237     
   238     std::istream& readToken(std::istream& is, std::string& str) {
   239       std::ostringstream os;
   240 
   241       char c;
   242       is >> std::ws;
   243       
   244       if (!is.get(c)) 
   245 	return is;
   246 
   247       if (c == '\"') {
   248 	while (is.get(c) && c != '\"') {
   249 	  if (c == '\\') 
   250 	    c = readEscape(is);
   251 	  os << c;
   252 	}
   253 	if (!is) 
   254 	  throw DataFormatError("Quoted format error");
   255       } else {
   256 	is.putback(c);
   257 	while (is.get(c) && !isWhiteSpace(c)) {
   258 	  if (c == '\\') 
   259 	    c = readEscape(is);
   260 	  os << c;
   261 	}
   262 	if (!is) {
   263 	  is.clear();
   264 	} else {
   265 	  is.putback(c);
   266 	}
   267       }
   268       str = os.str();
   269       return is;
   270     }
   271 
   272     class Section {
   273     public:
   274       virtual ~Section() {}
   275       virtual void process(std::istream& is, int& line_num) = 0;
   276     };
   277 
   278     template <typename Functor>
   279     class LineSection : public Section {
   280     private:
   281 
   282       Functor _functor;
   283 
   284     public:
   285       
   286       LineSection(const Functor& functor) : _functor(functor) {}
   287       virtual ~LineSection() {}
   288 
   289       virtual void process(std::istream& is, int& line_num) {
   290 	char c;
   291 	std::string line;
   292 	while (is.get(c) && c != '@') {
   293 	  if (c == '\n') {
   294 	    ++line_num;
   295 	  } else if (c == '#') {
   296 	    getline(is, line);
   297 	    ++line_num;
   298 	  } else if (!isWhiteSpace(c)) {
   299 	    is.putback(c);
   300 	    getline(is, line);
   301 	    _functor(line);
   302 	    ++line_num;
   303 	  }
   304 	}
   305 	if (is) is.putback(c);
   306 	else if (is.eof()) is.clear();
   307       }
   308     };
   309 
   310     template <typename Functor>
   311     class StreamSection : public Section {
   312     private:
   313 
   314       Functor _functor;
   315 
   316     public:
   317       
   318       StreamSection(const Functor& functor) : _functor(functor) {}
   319       virtual ~StreamSection() {} 
   320 
   321       virtual void process(std::istream& is, int& line_num) {
   322 	_functor(is, line_num);
   323 	char c;
   324 	std::string line;
   325 	while (is.get(c) && c != '@') {
   326 	  if (c == '\n') {
   327 	    ++line_num;
   328 	  } else if (!isWhiteSpace(c)) {
   329 	    getline(is, line);
   330 	    ++line_num;
   331 	  }
   332 	}
   333 	if (is) is.putback(c);
   334 	else if (is.eof()) is.clear();	
   335       }
   336     };
   337     
   338   }
   339 
   340   /// \ingroup lemon_io
   341   ///  
   342   /// \brief LGF reader for directed graphs
   343   ///
   344   /// This utility reads an \ref lgf-format "LGF" file.
   345   ///
   346   /// The reading method does a batch processing. The user creates a
   347   /// reader object, then various reading rules can be added to the
   348   /// reader, and eventually the reading is executed with the \c run()
   349   /// member function. A map reading rule can be added to the reader
   350   /// with the \c nodeMap() or \c arcMap() members. An optional
   351   /// converter parameter can also be added as a standard functor
   352   /// converting from std::string to the value type of the map. If it
   353   /// is set, it will determine how the tokens in the file should be
   354   /// is converted to the map's value type. If the functor is not set,
   355   /// then a default conversion will be used. One map can be read into
   356   /// multiple map objects at the same time. The \c attribute(), \c
   357   /// node() and \c arc() functions are used to add attribute reading
   358   /// rules.
   359   ///
   360   ///\code
   361   ///     DigraphReader<Digraph>(std::cin, digraph).
   362   ///       nodeMap("coordinates", coord_map).
   363   ///       arcMap("capacity", cap_map).
   364   ///       node("source", src).
   365   ///       node("target", trg).
   366   ///       attribute("caption", caption).
   367   ///       run();
   368   ///\endcode
   369   ///
   370   /// By default the reader uses the first section in the file of the
   371   /// proper type. If a section has an optional name, then it can be
   372   /// selected for reading by giving an optional name parameter to the
   373   /// \c nodes(), \c arcs() or \c attributes() functions. The readers
   374   /// also can load extra sections with the \c sectionLines() and
   375   /// sectionStream() functions.
   376   ///
   377   /// The \c useNodes() and \c useArcs() functions are used to tell the reader
   378   /// that the nodes or arcs should not be constructed (added to the
   379   /// graph) during the reading, but instead the label map of the items
   380   /// are given as a parameter of these functions. An
   381   /// application of these function is multipass reading, which is
   382   /// important if two \e \@arcs sections must be read from the
   383   /// file. In this example the first phase would read the node set and one
   384   /// of the arc sets, while the second phase would read the second arc
   385   /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
   386   /// The previously read label node map should be passed to the \c
   387   /// useNodes() functions. Another application of multipass reading when
   388   /// paths are given as a node map or an arc map. It is impossible read this in
   389   /// a single pass, because the arcs are not constructed when the node
   390   /// maps are read.
   391   template <typename _Digraph>
   392   class DigraphReader {
   393   public:
   394 
   395     typedef _Digraph Digraph;
   396     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   397     
   398   private:
   399 
   400 
   401     std::istream* _is;
   402     bool local_is;
   403 
   404     Digraph& _digraph;
   405 
   406     std::string _nodes_caption;
   407     std::string _arcs_caption;
   408     std::string _attributes_caption;
   409 
   410     typedef std::map<std::string, Node> NodeIndex;
   411     NodeIndex _node_index;
   412     typedef std::map<std::string, Arc> ArcIndex;
   413     ArcIndex _arc_index;
   414     
   415     typedef std::vector<std::pair<std::string, 
   416       _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
   417     NodeMaps _node_maps; 
   418 
   419     typedef std::vector<std::pair<std::string,
   420       _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
   421     ArcMaps _arc_maps;
   422 
   423     typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
   424       Attributes;
   425     Attributes _attributes;
   426 
   427     typedef std::map<std::string, _reader_bits::Section*> Sections;
   428     Sections _sections;
   429 
   430     bool _use_nodes;
   431     bool _use_arcs;
   432 
   433     int line_num;
   434     std::istringstream line;
   435 
   436   public:
   437 
   438     /// \brief Constructor
   439     ///
   440     /// Construct a directed graph reader, which reads from the given
   441     /// input stream.
   442     DigraphReader(std::istream& is, Digraph& digraph) 
   443       : _is(&is), local_is(false), _digraph(digraph),
   444 	_use_nodes(false), _use_arcs(false) {}
   445 
   446     /// \brief Constructor
   447     ///
   448     /// Construct a directed graph reader, which reads from the given
   449     /// file.
   450     DigraphReader(const std::string& fn, Digraph& digraph) 
   451       : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   452     	_use_nodes(false), _use_arcs(false) {}
   453     
   454     /// \brief Constructor
   455     ///
   456     /// Construct a directed graph reader, which reads from the given
   457     /// file.
   458     DigraphReader(const char* fn, Digraph& digraph) 
   459       : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   460     	_use_nodes(false), _use_arcs(false) {}
   461 
   462     /// \brief Copy constructor
   463     ///
   464     /// The copy constructor transfers all data from the other reader,
   465     /// therefore the copied reader will not be usable more. 
   466     DigraphReader(DigraphReader& other) 
   467       : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   468 	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
   469 
   470       other.is = 0;
   471       other.local_is = false;
   472       
   473       _node_index.swap(other._node_index);
   474       _arc_index.swap(other._arc_index);
   475 
   476       _node_maps.swap(other._node_maps);
   477       _arc_maps.swap(other._arc_maps);
   478       _attributes.swap(other._attributes);
   479 
   480       _nodes_caption = other._nodes_caption;
   481       _arcs_caption = other._arcs_caption;
   482       _attributes_caption = other._attributes_caption;
   483 
   484       _sections.swap(other._sections);
   485     }
   486 
   487     /// \brief Destructor
   488     ~DigraphReader() {
   489       for (typename NodeMaps::iterator it = _node_maps.begin(); 
   490 	   it != _node_maps.end(); ++it) {
   491 	delete it->second;
   492       }
   493 
   494       for (typename ArcMaps::iterator it = _arc_maps.begin(); 
   495 	   it != _arc_maps.end(); ++it) {
   496 	delete it->second;
   497       }
   498 
   499       for (typename Attributes::iterator it = _attributes.begin(); 
   500 	   it != _attributes.end(); ++it) {
   501 	delete it->second;
   502       }
   503 
   504       for (typename Sections::iterator it = _sections.begin(); 
   505 	   it != _sections.end(); ++it) {
   506 	delete it->second;
   507       }
   508 
   509       if (local_is) {
   510 	delete _is;
   511       }
   512 
   513     }
   514 
   515   private:
   516     
   517     DigraphReader& operator=(const DigraphReader&);
   518 
   519   public:
   520 
   521     /// \name Reading rules
   522     /// @{
   523     
   524     /// \brief Node map reading rule
   525     ///
   526     /// Add a node map reading rule to the reader.
   527     template <typename Map>
   528     DigraphReader& nodeMap(const std::string& caption, Map& map) {
   529       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   530       _reader_bits::MapStorageBase<Node>* storage = 
   531 	new _reader_bits::MapStorage<Node, Map>(map);
   532       _node_maps.push_back(std::make_pair(caption, storage));
   533       return *this;
   534     }
   535 
   536     /// \brief Node map reading rule
   537     ///
   538     /// Add a node map reading rule with specialized converter to the
   539     /// reader.
   540     template <typename Map, typename Converter>
   541     DigraphReader& nodeMap(const std::string& caption, Map& map, 
   542 			   const Converter& converter = Converter()) {
   543       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   544       _reader_bits::MapStorageBase<Node>* storage = 
   545 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
   546       _node_maps.push_back(std::make_pair(caption, storage));
   547       return *this;
   548     }
   549 
   550     /// \brief Arc map reading rule
   551     ///
   552     /// Add an arc map reading rule to the reader.
   553     template <typename Map>
   554     DigraphReader& arcMap(const std::string& caption, Map& map) {
   555       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   556       _reader_bits::MapStorageBase<Arc>* storage = 
   557 	new _reader_bits::MapStorage<Arc, Map>(map);
   558       _arc_maps.push_back(std::make_pair(caption, storage));
   559       return *this;
   560     }
   561 
   562     /// \brief Arc map reading rule
   563     ///
   564     /// Add an arc map reading rule with specialized converter to the
   565     /// reader.
   566     template <typename Map, typename Converter>
   567     DigraphReader& arcMap(const std::string& caption, Map& map, 
   568 			  const Converter& converter = Converter()) {
   569       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   570       _reader_bits::MapStorageBase<Arc>* storage = 
   571 	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
   572       _arc_maps.push_back(std::make_pair(caption, storage));
   573       return *this;
   574     }
   575 
   576     /// \brief Attribute reading rule
   577     ///
   578     /// Add an attribute reading rule to the reader.
   579     template <typename Value>
   580     DigraphReader& attribute(const std::string& caption, Value& value) {
   581       _reader_bits::ValueStorageBase* storage = 
   582 	new _reader_bits::ValueStorage<Value>(value);
   583       _attributes.insert(std::make_pair(caption, storage));
   584       return *this;
   585     }
   586 
   587     /// \brief Attribute reading rule
   588     ///
   589     /// Add an attribute reading rule with specialized converter to the
   590     /// reader.
   591     template <typename Value, typename Converter>
   592     DigraphReader& attribute(const std::string& caption, Value& value, 
   593 			     const Converter& converter = Converter()) {
   594       _reader_bits::ValueStorageBase* storage = 
   595 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
   596       _attributes.insert(std::make_pair(caption, storage));
   597       return *this;
   598     }
   599 
   600     /// \brief Node reading rule
   601     ///
   602     /// Add a node reading rule to reader.
   603     DigraphReader& node(const std::string& caption, Node& node) {
   604       typedef _reader_bits::MapLookUpConverter<Node> Converter;
   605       Converter converter(_node_index);
   606       _reader_bits::ValueStorageBase* storage = 
   607 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
   608       _attributes.insert(std::make_pair(caption, storage));
   609       return *this;
   610     }
   611 
   612     /// \brief Arc reading rule
   613     ///
   614     /// Add an arc reading rule to reader.
   615     DigraphReader& arc(const std::string& caption, Arc& arc) {
   616       typedef _reader_bits::MapLookUpConverter<Arc> Converter;
   617       Converter converter(_arc_index);
   618       _reader_bits::ValueStorageBase* storage = 
   619 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
   620       _attributes.insert(std::make_pair(caption, storage));
   621       return *this;
   622     }
   623 
   624     /// @}
   625 
   626     /// \name Select section by name
   627     /// @{
   628 
   629     /// \brief Set \c \@nodes section to be read
   630     ///
   631     /// Set \c \@nodes section to be read
   632     DigraphReader& nodes(const std::string& caption) {
   633       _nodes_caption = caption;
   634       return *this;
   635     }
   636 
   637     /// \brief Set \c \@arcs section to be read
   638     ///
   639     /// Set \c \@arcs section to be read
   640     DigraphReader& arcs(const std::string& caption) {
   641       _arcs_caption = caption;
   642       return *this;
   643     }
   644 
   645     /// \brief Set \c \@attributes section to be read
   646     ///
   647     /// Set \c \@attributes section to be read
   648     DigraphReader& attributes(const std::string& caption) {
   649       _attributes_caption = caption;
   650       return *this;
   651     }
   652 
   653     /// @}
   654 
   655     /// \name Section readers
   656     /// @{
   657 
   658     /// \brief Add a section processor with line oriented reading
   659     ///
   660     /// In the \e LGF file extra sections can be placed, which contain
   661     /// any data in arbitrary format. These sections can be read with
   662     /// this function line by line. The first parameter is the type
   663     /// descriptor of the section, the second is a functor, which
   664     /// takes just one \c std::string parameter. At the reading
   665     /// process, each line of the section will be given to the functor
   666     /// object. However, the empty lines and the comment lines are
   667     /// filtered out, and the leading whitespaces are stipped from
   668     /// each processed string.
   669     ///
   670     /// For example let's see a section, which contain several
   671     /// integers, which should be inserted into a vector.
   672     ///\code
   673     ///  @numbers
   674     ///  12 45 23
   675     ///  4
   676     ///  23 6
   677     ///\endcode
   678     ///
   679     /// The functor is implemented as an struct:
   680     ///\code
   681     ///  struct NumberSection {
   682     ///    std::vector<int>& _data;
   683     ///    NumberSection(std::vector<int>& data) : _data(data) {}
   684     ///    void operator()(const std::string& line) {
   685     ///      std::istringstream ls(line);
   686     ///      int value;
   687     ///      while (ls >> value) _data.push_back(value);
   688     ///    }
   689     ///  };
   690     ///
   691     ///  // ...
   692     ///
   693     ///  reader.sectionLines("numbers", NumberSection(vec));  
   694     ///\endcode
   695     template <typename Functor>
   696     DigraphReader& sectionLines(const std::string& type, Functor functor) {
   697       LEMON_ASSERT(!type.empty(), "Type is not empty.");
   698       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
   699 		   "Multiple reading of section.");
   700       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
   701 		   type != "attributes", "Multiple reading of section.");
   702       _sections.insert(std::make_pair(type, 
   703         new _reader_bits::LineSection<Functor>(functor)));
   704       return *this;
   705     }
   706 
   707 
   708     /// \brief Add a section processor with stream oriented reading
   709     ///
   710     /// In the \e LGF file extra sections can be placed, which contain
   711     /// any data in arbitrary format. These sections can be read
   712     /// directly with this function. The first parameter is the type
   713     /// of the section, the second is a functor, which takes an \c
   714     /// std::istream& and an int& parameter, the latter regard to the
   715     /// line number of stream. The functor can read the input while
   716     /// the section go on, and the line number should be modified
   717     /// accordingly.
   718     template <typename Functor>
   719     DigraphReader& sectionStream(const std::string& type, Functor functor) {
   720       LEMON_ASSERT(!type.empty(), "Type is not empty.");
   721       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
   722 		   "Multiple reading of section.");
   723       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
   724 		   type != "attributes", "Multiple reading of section.");
   725       _sections.insert(std::make_pair(type, 
   726 	 new _reader_bits::StreamSection<Functor>(functor)));
   727       return *this;
   728     }    
   729     
   730     /// @}
   731 
   732     /// \name Using previously constructed node or arc set
   733     /// @{
   734 
   735     /// \brief Use previously constructed node set
   736     ///
   737     /// Use previously constructed node set, and specify the node
   738     /// label map.
   739     template <typename Map>
   740     DigraphReader& useNodes(const Map& map) {
   741       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   742       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   743       _use_nodes = true;
   744       _writer_bits::DefaultConverter<typename Map::Value> converter;
   745       for (NodeIt n(_digraph); n != INVALID; ++n) {
   746 	_node_index.insert(std::make_pair(converter(map[n]), n));
   747       }
   748       return *this;
   749     }
   750 
   751     /// \brief Use previously constructed node set
   752     ///
   753     /// Use previously constructed node set, and specify the node
   754     /// label map and a functor which converts the label map values to
   755     /// std::string.
   756     template <typename Map, typename Converter>
   757     DigraphReader& useNodes(const Map& map, 
   758 			    const Converter& converter = Converter()) {
   759       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   760       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
   761       _use_nodes = true;
   762       for (NodeIt n(_digraph); n != INVALID; ++n) {
   763 	_node_index.insert(std::make_pair(converter(map[n]), n));
   764       }
   765       return *this;
   766     }
   767 
   768     /// \brief Use previously constructed arc set
   769     ///
   770     /// Use previously constructed arc set, and specify the arc
   771     /// label map.
   772     template <typename Map>
   773     DigraphReader& useArcs(const Map& map) {
   774       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   775       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
   776       _use_arcs = true;
   777       _writer_bits::DefaultConverter<typename Map::Value> converter;
   778       for (ArcIt a(_digraph); a != INVALID; ++a) {
   779 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   780       }
   781       return *this;
   782     }
   783 
   784     /// \brief Use previously constructed arc set
   785     ///
   786     /// Use previously constructed arc set, and specify the arc
   787     /// label map and a functor which converts the label map values to
   788     /// std::string.
   789     template <typename Map, typename Converter>
   790     DigraphReader& useArcs(const Map& map, 
   791 			    const Converter& converter = Converter()) {
   792       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   793       LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
   794       _use_arcs = true;
   795       for (ArcIt a(_digraph); a != INVALID; ++a) {
   796 	_arc_index.insert(std::make_pair(converter(map[a]), a));
   797       }
   798       return *this;
   799     }
   800 
   801     /// @}
   802 
   803   private:
   804 
   805     bool readLine() {
   806       std::string str;
   807       while(++line_num, std::getline(*_is, str)) {
   808 	line.clear(); line.str(str);
   809 	char c;
   810 	if (line >> std::ws >> c && c != '#') {
   811 	  line.putback(c);
   812 	  return true;
   813 	}
   814       }
   815       return false;
   816     }
   817 
   818     bool readSuccess() {
   819       return static_cast<bool>(*_is);
   820     }
   821     
   822     void skipSection() {
   823       char c;
   824       while (readSuccess() && line >> c && c != '@') {
   825 	readLine();
   826       }
   827       line.putback(c);
   828     }
   829 
   830     void readNodes() {
   831 
   832       std::vector<int> map_index(_node_maps.size());
   833       int map_num, label_index;
   834 
   835       if (!readLine()) 
   836 	throw DataFormatError("Cannot find map captions");
   837       
   838       {
   839 	std::map<std::string, int> maps;
   840 	
   841 	std::string map;
   842 	int index = 0;
   843 	while (_reader_bits::readToken(line, map)) {
   844 	  if (maps.find(map) != maps.end()) {
   845 	    std::ostringstream msg;
   846 	    msg << "Multiple occurence of node map: " << map;
   847 	    throw DataFormatError(msg.str().c_str());
   848 	  }
   849 	  maps.insert(std::make_pair(map, index));
   850 	  ++index;
   851 	}
   852 	
   853 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   854 	  std::map<std::string, int>::iterator jt = 
   855 	    maps.find(_node_maps[i].first);
   856 	  if (jt == maps.end()) {
   857 	    std::ostringstream msg;
   858 	    msg << "Map not found in file: " << _node_maps[i].first;
   859 	    throw DataFormatError(msg.str().c_str());
   860 	  }
   861 	  map_index[i] = jt->second;
   862 	}
   863 
   864 	{
   865 	  std::map<std::string, int>::iterator jt = maps.find("label");
   866 	  if (jt == maps.end())
   867 	    throw DataFormatError("Label map not found in file");
   868 	  label_index = jt->second;
   869 	}
   870 	map_num = maps.size();
   871       }
   872 
   873       char c;
   874       while (readLine() && line >> c && c != '@') {
   875 	line.putback(c);
   876 
   877 	std::vector<std::string> tokens(map_num);
   878 	for (int i = 0; i < map_num; ++i) {
   879 	  if (!_reader_bits::readToken(line, tokens[i])) {
   880 	    std::ostringstream msg;
   881 	    msg << "Column not found (" << i + 1 << ")";
   882 	    throw DataFormatError(msg.str().c_str());
   883 	  }
   884 	}
   885 	if (line >> std::ws >> c)
   886 	  throw DataFormatError("Extra character on the end of line");
   887 	
   888 	Node n;
   889 	if (!_use_nodes) {
   890 	  n = _digraph.addNode();
   891 	  _node_index.insert(std::make_pair(tokens[label_index], n));
   892 	} else {
   893 	  typename std::map<std::string, Node>::iterator it =
   894 	    _node_index.find(tokens[label_index]);
   895 	  if (it == _node_index.end()) {
   896 	    std::ostringstream msg;
   897 	    msg << "Node with label not found: " << tokens[label_index];
   898 	    throw DataFormatError(msg.str().c_str());	    
   899 	  }
   900 	  n = it->second;
   901 	}
   902 
   903 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
   904 	  _node_maps[i].second->set(n, tokens[map_index[i]]);
   905 	}
   906 
   907       }
   908       if (readSuccess()) {
   909 	line.putback(c);
   910       }
   911     }
   912 
   913     void readArcs() {
   914 
   915       std::vector<int> map_index(_arc_maps.size());
   916       int map_num, label_index;
   917 
   918       if (!readLine()) 
   919 	throw DataFormatError("Cannot find map captions");
   920       
   921       {
   922 	std::map<std::string, int> maps;
   923 	
   924 	std::string map;
   925 	int index = 0;
   926 	while (_reader_bits::readToken(line, map)) {
   927 	  if (maps.find(map) != maps.end()) {
   928 	    std::ostringstream msg;
   929 	    msg << "Multiple occurence of arc map: " << map;
   930 	    throw DataFormatError(msg.str().c_str());
   931 	  }
   932 	  maps.insert(std::make_pair(map, index));
   933 	  ++index;
   934 	}
   935 	
   936 	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
   937 	  std::map<std::string, int>::iterator jt = 
   938 	    maps.find(_arc_maps[i].first);
   939 	  if (jt == maps.end()) {
   940 	    std::ostringstream msg;
   941 	    msg << "Map not found in file: " << _arc_maps[i].first;
   942 	    throw DataFormatError(msg.str().c_str());
   943 	  }
   944 	  map_index[i] = jt->second;
   945 	}
   946 
   947 	{
   948 	  std::map<std::string, int>::iterator jt = maps.find("label");
   949 	  if (jt == maps.end())
   950 	    throw DataFormatError("Label map not found in file");
   951 	  label_index = jt->second;
   952 	}
   953 	map_num = maps.size();
   954       }
   955 
   956       char c;
   957       while (readLine() && line >> c && c != '@') {
   958 	line.putback(c);
   959 
   960 	std::string source_token;
   961 	std::string target_token;
   962 
   963 	if (!_reader_bits::readToken(line, source_token))
   964 	  throw DataFormatError("Source not found");
   965 
   966 	if (!_reader_bits::readToken(line, target_token))
   967 	  throw DataFormatError("Source not found");
   968 	
   969 	std::vector<std::string> tokens(map_num);
   970 	for (int i = 0; i < map_num; ++i) {
   971 	  if (!_reader_bits::readToken(line, tokens[i])) {
   972 	    std::ostringstream msg;
   973 	    msg << "Column not found (" << i + 1 << ")";
   974 	    throw DataFormatError(msg.str().c_str());
   975 	  }
   976 	}
   977 	if (line >> std::ws >> c)
   978 	  throw DataFormatError("Extra character on the end of line");
   979 	
   980 	Arc a;
   981 	if (!_use_arcs) {
   982 
   983           typename NodeIndex::iterator it;
   984  
   985           it = _node_index.find(source_token);
   986           if (it == _node_index.end()) {
   987             std::ostringstream msg;
   988             msg << "Item not found: " << source_token;
   989             throw DataFormatError(msg.str().c_str());
   990           }
   991           Node source = it->second;
   992 
   993           it = _node_index.find(target_token);
   994           if (it == _node_index.end()) {       
   995             std::ostringstream msg;            
   996             msg << "Item not found: " << target_token;
   997             throw DataFormatError(msg.str().c_str());
   998           }                                          
   999           Node target = it->second;                            
  1000 
  1001 	  a = _digraph.addArc(source, target);
  1002 	  _arc_index.insert(std::make_pair(tokens[label_index], a));
  1003 	} else {
  1004 	  typename std::map<std::string, Arc>::iterator it =
  1005 	    _arc_index.find(tokens[label_index]);
  1006 	  if (it == _arc_index.end()) {
  1007 	    std::ostringstream msg;
  1008 	    msg << "Arc with label not found: " << tokens[label_index];
  1009 	    throw DataFormatError(msg.str().c_str());	    
  1010 	  }
  1011 	  a = it->second;
  1012 	}
  1013 
  1014 	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
  1015 	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
  1016 	}
  1017 
  1018       }
  1019       if (readSuccess()) {
  1020 	line.putback(c);
  1021       }
  1022     }
  1023 
  1024     void readAttributes() {
  1025 
  1026       std::set<std::string> read_attr;
  1027 
  1028       char c;
  1029       while (readLine() && line >> c && c != '@') {
  1030 	line.putback(c);
  1031 	
  1032 	std::string attr, token;
  1033 	if (!_reader_bits::readToken(line, attr))
  1034 	  throw DataFormatError("Attribute name not found");
  1035 	if (!_reader_bits::readToken(line, token))
  1036 	  throw DataFormatError("Attribute value not found");
  1037 	if (line >> c)
  1038 	  throw DataFormatError("Extra character on the end of line");	  
  1039 
  1040 	{
  1041 	  std::set<std::string>::iterator it = read_attr.find(attr);
  1042 	  if (it != read_attr.end()) {
  1043 	    std::ostringstream msg;
  1044 	    msg << "Multiple occurence of attribute " << attr;
  1045 	    throw DataFormatError(msg.str().c_str());
  1046 	  }
  1047 	  read_attr.insert(attr);
  1048 	}
  1049 	
  1050 	{
  1051 	  typename Attributes::iterator it = _attributes.lower_bound(attr);
  1052 	  while (it != _attributes.end() && it->first == attr) {
  1053 	    it->second->set(token);
  1054 	    ++it;
  1055 	  }
  1056 	}
  1057 
  1058       }
  1059       if (readSuccess()) {
  1060 	line.putback(c);
  1061       }
  1062       for (typename Attributes::iterator it = _attributes.begin();
  1063 	   it != _attributes.end(); ++it) {
  1064 	if (read_attr.find(it->first) == read_attr.end()) {
  1065 	  std::ostringstream msg;
  1066 	  msg << "Attribute not found in file: " << it->first;
  1067 	  throw DataFormatError(msg.str().c_str());
  1068 	}	
  1069       }
  1070     }
  1071 
  1072   public:
  1073 
  1074     /// \name Execution of the reader    
  1075     /// @{
  1076 
  1077     /// \brief Start the batch processing
  1078     ///
  1079     /// This function starts the batch processing
  1080     void run() {
  1081       
  1082       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
  1083       
  1084       bool nodes_done = false;
  1085       bool arcs_done = false;
  1086       bool attributes_done = false;
  1087       std::set<std::string> extra_sections;
  1088 
  1089       line_num = 0;      
  1090       readLine();
  1091 
  1092       while (readSuccess()) {
  1093 	skipSection();
  1094 	try {
  1095 	  char c;
  1096 	  std::string section, caption;
  1097 	  line >> c;
  1098 	  _reader_bits::readToken(line, section);
  1099 	  _reader_bits::readToken(line, caption);
  1100 
  1101 	  if (line >> c) 
  1102 	    throw DataFormatError("Extra character on the end of line");
  1103 
  1104 	  if (section == "nodes" && !nodes_done) {
  1105 	    if (_nodes_caption.empty() || _nodes_caption == caption) {
  1106 	      readNodes();
  1107 	      nodes_done = true;
  1108 	    }
  1109 	  } else if ((section == "arcs" || section == "edges") && 
  1110 		     !arcs_done) {
  1111 	    if (_arcs_caption.empty() || _arcs_caption == caption) {
  1112 	      readArcs();
  1113 	      arcs_done = true;
  1114 	    }
  1115 	  } else if (section == "attributes" && !attributes_done) {
  1116 	    if (_attributes_caption.empty() || _attributes_caption == caption) {
  1117 	      readAttributes();
  1118 	      attributes_done = true;
  1119 	    }
  1120 	  } else {
  1121 	    if (extra_sections.find(section) != extra_sections.end()) {
  1122 	      std::ostringstream msg;
  1123 	      msg << "Multiple occurence of section " << section;
  1124 	      throw DataFormatError(msg.str().c_str());
  1125 	    }
  1126 	    Sections::iterator it = _sections.find(section);
  1127 	    if (it != _sections.end()) {
  1128 	      extra_sections.insert(section);
  1129 	      it->second->process(*_is, line_num);
  1130 	      readLine();
  1131 	    } else {
  1132 	      readLine();
  1133 	      skipSection();
  1134 	    }
  1135 	  }
  1136 	} catch (DataFormatError& error) {
  1137 	  error.line(line_num);
  1138 	  throw;
  1139 	}	
  1140       }
  1141 
  1142       if (!nodes_done) {
  1143 	throw DataFormatError("Section @nodes not found");
  1144       }
  1145 
  1146       if (!arcs_done) {
  1147 	throw DataFormatError("Section @arcs not found");
  1148       }
  1149 
  1150       if (!attributes_done && !_attributes.empty()) {
  1151 	throw DataFormatError("Section @attributes not found");
  1152       }
  1153 
  1154     }
  1155 
  1156     /// @}
  1157     
  1158   };
  1159 
  1160   /// \relates DigraphReader
  1161   template <typename Digraph>
  1162   DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
  1163     return DigraphReader<Digraph>(is, digraph);
  1164   }
  1165 
  1166   /// \relates DigraphReader
  1167   template <typename Digraph>
  1168   DigraphReader<Digraph> digraphReader(const std::string& fn, 
  1169 				       Digraph& digraph) {
  1170     return DigraphReader<Digraph>(fn, digraph);
  1171   }
  1172 
  1173   /// \relates DigraphReader
  1174   template <typename Digraph>
  1175   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
  1176     return DigraphReader<Digraph>(fn, digraph);
  1177   }
  1178 }
  1179 
  1180 #endif