gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Section readers moved to distinct class
0 1 0
default
1 file changed with 1386 insertions and 1336 deletions:
↑ Collapse diff ↑
Show white space 6 line context
... ...
@@ -419,9 +419,7 @@
419 419
  /// By default the reader uses the first section in the file of the
420 420
  /// proper type. If a section has an optional name, then it can be
421 421
  /// selected for reading by giving an optional name parameter to the
422
  /// \c nodes(), \c arcs() or \c attributes() functions. The readers
423
  /// also can load extra sections with the \c sectionLines() and
424
  /// sectionStream() functions.
422
  /// \c nodes(), \c arcs() or \c attributes() functions.
425 423
  ///
426 424
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
427 425
  /// that the nodes or arcs should not be constructed (added to the
... ...
@@ -473,9 +471,6 @@
473 471
      Attributes;
474 472
    Attributes _attributes;
475 473

	
476
    typedef std::map<std::string, _reader_bits::Section*> Sections;
477
    Sections _sections;
478

	
479 474
    bool _use_nodes;
480 475
    bool _use_arcs;
481 476

	
... ...
@@ -537,7 +532,6 @@
537 532
      _arcs_caption = other._arcs_caption;
538 533
      _attributes_caption = other._attributes_caption;
539 534

	
540
      _sections.swap(other._sections);
541 535
    }
542 536

	
543 537
    /// \brief Destructor
... ...
@@ -557,11 +551,6 @@
557 551
	delete it->second;
558 552
      }
559 553

	
560
      for (typename Sections::iterator it = _sections.begin(); 
561
	   it != _sections.end(); ++it) {
562
	delete it->second;
563
      }
564

	
565 554
      if (local_is) {
566 555
	delete _is;
567 556
      }
... ...
@@ -708,20 +697,1371 @@
708 697

	
709 698
    /// @}
710 699

	
700
    /// \name Using previously constructed node or arc set
701
    /// @{
702

	
703
    /// \brief Use previously constructed node set
704
    ///
705
    /// Use previously constructed node set, and specify the node
706
    /// label map.
707
    template <typename Map>
708
    DigraphReader& useNodes(const Map& map) {
709
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
710
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
711
      _use_nodes = true;
712
      _writer_bits::DefaultConverter<typename Map::Value> converter;
713
      for (NodeIt n(_digraph); n != INVALID; ++n) {
714
	_node_index.insert(std::make_pair(converter(map[n]), n));
715
      }
716
      return *this;
717
    }
718

	
719
    /// \brief Use previously constructed node set
720
    ///
721
    /// Use previously constructed node set, and specify the node
722
    /// label map and a functor which converts the label map values to
723
    /// std::string.
724
    template <typename Map, typename Converter>
725
    DigraphReader& useNodes(const Map& map, 
726
			    const Converter& converter = Converter()) {
727
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
728
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
729
      _use_nodes = true;
730
      for (NodeIt n(_digraph); n != INVALID; ++n) {
731
	_node_index.insert(std::make_pair(converter(map[n]), n));
732
      }
733
      return *this;
734
    }
735

	
736
    /// \brief Use previously constructed arc set
737
    ///
738
    /// Use previously constructed arc set, and specify the arc
739
    /// label map.
740
    template <typename Map>
741
    DigraphReader& useArcs(const Map& map) {
742
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
743
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
744
      _use_arcs = true;
745
      _writer_bits::DefaultConverter<typename Map::Value> converter;
746
      for (ArcIt a(_digraph); a != INVALID; ++a) {
747
	_arc_index.insert(std::make_pair(converter(map[a]), a));
748
      }
749
      return *this;
750
    }
751

	
752
    /// \brief Use previously constructed arc set
753
    ///
754
    /// Use previously constructed arc set, and specify the arc
755
    /// label map and a functor which converts the label map values to
756
    /// std::string.
757
    template <typename Map, typename Converter>
758
    DigraphReader& useArcs(const Map& map, 
759
			   const Converter& converter = Converter()) {
760
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
761
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
762
      _use_arcs = true;
763
      for (ArcIt a(_digraph); a != INVALID; ++a) {
764
	_arc_index.insert(std::make_pair(converter(map[a]), a));
765
      }
766
      return *this;
767
    }
768

	
769
    /// \brief Skips the reading of node section
770
    ///
771
    /// Omit the reading of the node section. This implies that each node
772
    /// map reading rule will be abanoned, and the nodes of the graph
773
    /// will not be constructed, which usually cause that the arc set
774
    /// could not be read due to lack of node name
775
    /// resolving. Therefore, the \c skipArcs() should be used too, or
776
    /// the useNodes() member function should be used to specify the
777
    /// label of the nodes.
778
    DigraphReader& skipNodes() {
779
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
780
      _skip_nodes = true;
781
      return *this;
782
    }
783

	
784
    /// \brief Skips the reading of arc section
785
    ///
786
    /// Omit the reading of the arc section. This implies that each arc
787
    /// map reading rule will be abanoned, and the arcs of the graph
788
    /// will not be constructed.
789
    DigraphReader& skipArcs() {
790
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 
791
      _skip_arcs = true;
792
      return *this;
793
    }
794

	
795
    /// @}
796

	
797
  private:
798

	
799
    bool readLine() {
800
      std::string str;
801
      while(++line_num, std::getline(*_is, str)) {
802
	line.clear(); line.str(str);
803
	char c;
804
	if (line >> std::ws >> c && c != '#') {
805
	  line.putback(c);
806
	  return true;
807
	}
808
      }
809
      return false;
810
    }
811

	
812
    bool readSuccess() {
813
      return static_cast<bool>(*_is);
814
    }
815
    
816
    void skipSection() {
817
      char c;
818
      while (readSuccess() && line >> c && c != '@') {
819
	readLine();
820
      }
821
      line.putback(c);
822
    }
823

	
824
    void readNodes() {
825

	
826
      std::vector<int> map_index(_node_maps.size());
827
      int map_num, label_index;
828

	
829
      char c;
830
      if (!readLine() || !(line >> c) || c == '@') {
831
	if (readSuccess() && line) line.putback(c);
832
	if (!_node_maps.empty()) 
833
	  throw DataFormatError("Cannot find map names");
834
	return;
835
      }
836
      line.putback(c);
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
	    label_index = jt->second;
868
	  } else {
869
	    label_index = -1;
870
	  }
871
	}
872
	map_num = maps.size();
873
      }
874

	
875
      while (readLine() && line >> c && c != '@') {
876
	line.putback(c);
877

	
878
	std::vector<std::string> tokens(map_num);
879
	for (int i = 0; i < map_num; ++i) {
880
	  if (!_reader_bits::readToken(line, tokens[i])) {
881
	    std::ostringstream msg;
882
	    msg << "Column not found (" << i + 1 << ")";
883
	    throw DataFormatError(msg.str().c_str());
884
	  }
885
	}
886
	if (line >> std::ws >> c)
887
	  throw DataFormatError("Extra character on the end of line");
888
	
889
	Node n;
890
	if (!_use_nodes) {
891
	  n = _digraph.addNode();
892
	  if (label_index != -1)
893
	    _node_index.insert(std::make_pair(tokens[label_index], n));
894
	} else {
895
	  if (label_index == -1) 
896
	    throw DataFormatError("Label map not found in file");
897
	  typename std::map<std::string, Node>::iterator it =
898
	    _node_index.find(tokens[label_index]);
899
	  if (it == _node_index.end()) {
900
	    std::ostringstream msg;
901
	    msg << "Node with label not found: " << tokens[label_index];
902
	    throw DataFormatError(msg.str().c_str());	    
903
	  }
904
	  n = it->second;
905
	}
906

	
907
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
908
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
909
	}
910

	
911
      }
912
      if (readSuccess()) {
913
	line.putback(c);
914
      }
915
    }
916

	
917
    void readArcs() {
918

	
919
      std::vector<int> map_index(_arc_maps.size());
920
      int map_num, label_index;
921

	
922
      char c;
923
      if (!readLine() || !(line >> c) || c == '@') {
924
	if (readSuccess() && line) line.putback(c);
925
	if (!_arc_maps.empty()) 
926
	  throw DataFormatError("Cannot find map names");
927
	return;
928
      }
929
      line.putback(c);
930
      
931
      {
932
	std::map<std::string, int> maps;
933
	
934
	std::string map;
935
	int index = 0;
936
	while (_reader_bits::readToken(line, map)) {
937
	  if (maps.find(map) != maps.end()) {
938
	    std::ostringstream msg;
939
	    msg << "Multiple occurence of arc map: " << map;
940
	    throw DataFormatError(msg.str().c_str());
941
	  }
942
	  maps.insert(std::make_pair(map, index));
943
	  ++index;
944
	}
945
	
946
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
947
	  std::map<std::string, int>::iterator jt = 
948
	    maps.find(_arc_maps[i].first);
949
	  if (jt == maps.end()) {
950
	    std::ostringstream msg;
951
	    msg << "Map not found in file: " << _arc_maps[i].first;
952
	    throw DataFormatError(msg.str().c_str());
953
	  }
954
	  map_index[i] = jt->second;
955
	}
956

	
957
	{
958
	  std::map<std::string, int>::iterator jt = maps.find("label");
959
	  if (jt != maps.end()) {
960
	    label_index = jt->second;
961
	  } else {
962
	    label_index = -1;
963
	  }
964
	}
965
	map_num = maps.size();
966
      }
967

	
968
      while (readLine() && line >> c && c != '@') {
969
	line.putback(c);
970

	
971
	std::string source_token;
972
	std::string target_token;
973

	
974
	if (!_reader_bits::readToken(line, source_token))
975
	  throw DataFormatError("Source not found");
976

	
977
	if (!_reader_bits::readToken(line, target_token))
978
	  throw DataFormatError("Target not found");
979
	
980
	std::vector<std::string> tokens(map_num);
981
	for (int i = 0; i < map_num; ++i) {
982
	  if (!_reader_bits::readToken(line, tokens[i])) {
983
	    std::ostringstream msg;
984
	    msg << "Column not found (" << i + 1 << ")";
985
	    throw DataFormatError(msg.str().c_str());
986
	  }
987
	}
988
	if (line >> std::ws >> c)
989
	  throw DataFormatError("Extra character on the end of line");
990
	
991
	Arc a;
992
	if (!_use_arcs) {
993

	
994
          typename NodeIndex::iterator it;
995
 
996
          it = _node_index.find(source_token);
997
          if (it == _node_index.end()) {
998
            std::ostringstream msg;
999
            msg << "Item not found: " << source_token;
1000
            throw DataFormatError(msg.str().c_str());
1001
          }
1002
          Node source = it->second;
1003

	
1004
          it = _node_index.find(target_token);
1005
          if (it == _node_index.end()) {       
1006
            std::ostringstream msg;            
1007
            msg << "Item not found: " << target_token;
1008
            throw DataFormatError(msg.str().c_str());
1009
          }                                          
1010
          Node target = it->second;                            
1011

	
1012
	  a = _digraph.addArc(source, target);
1013
	  if (label_index != -1) 
1014
	    _arc_index.insert(std::make_pair(tokens[label_index], a));
1015
	} else {
1016
	  if (label_index == -1) 
1017
	    throw DataFormatError("Label map not found in file");
1018
	  typename std::map<std::string, Arc>::iterator it =
1019
	    _arc_index.find(tokens[label_index]);
1020
	  if (it == _arc_index.end()) {
1021
	    std::ostringstream msg;
1022
	    msg << "Arc with label not found: " << tokens[label_index];
1023
	    throw DataFormatError(msg.str().c_str());	    
1024
	  }
1025
	  a = it->second;
1026
	}
1027

	
1028
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1029
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
1030
	}
1031

	
1032
      }
1033
      if (readSuccess()) {
1034
	line.putback(c);
1035
      }
1036
    }
1037

	
1038
    void readAttributes() {
1039

	
1040
      std::set<std::string> read_attr;
1041

	
1042
      char c;
1043
      while (readLine() && line >> c && c != '@') {
1044
	line.putback(c);
1045
	
1046
	std::string attr, token;
1047
	if (!_reader_bits::readToken(line, attr))
1048
	  throw DataFormatError("Attribute name not found");
1049
	if (!_reader_bits::readToken(line, token))
1050
	  throw DataFormatError("Attribute value not found");
1051
	if (line >> c)
1052
	  throw DataFormatError("Extra character on the end of line");	  
1053

	
1054
	{
1055
	  std::set<std::string>::iterator it = read_attr.find(attr);
1056
	  if (it != read_attr.end()) {
1057
	    std::ostringstream msg;
1058
	    msg << "Multiple occurence of attribute " << attr;
1059
	    throw DataFormatError(msg.str().c_str());
1060
	  }
1061
	  read_attr.insert(attr);
1062
	}
1063
	
1064
	{
1065
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1066
	  while (it != _attributes.end() && it->first == attr) {
1067
	    it->second->set(token);
1068
	    ++it;
1069
	  }
1070
	}
1071

	
1072
      }
1073
      if (readSuccess()) {
1074
	line.putback(c);
1075
      }
1076
      for (typename Attributes::iterator it = _attributes.begin();
1077
	   it != _attributes.end(); ++it) {
1078
	if (read_attr.find(it->first) == read_attr.end()) {
1079
	  std::ostringstream msg;
1080
	  msg << "Attribute not found in file: " << it->first;
1081
	  throw DataFormatError(msg.str().c_str());
1082
	}	
1083
      }
1084
    }
1085

	
1086
  public:
1087

	
1088
    /// \name Execution of the reader    
1089
    /// @{
1090

	
1091
    /// \brief Start the batch processing
1092
    ///
1093
    /// This function starts the batch processing
1094
    void run() {
1095
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1096
      if (!*_is) {
1097
	throw DataFormatError("Cannot find file");
1098
      }
1099
      
1100
      bool nodes_done = _skip_nodes;
1101
      bool arcs_done = _skip_arcs;
1102
      bool attributes_done = false;
1103

	
1104
      line_num = 0;      
1105
      readLine();
1106
      skipSection();
1107

	
1108
      while (readSuccess()) {
1109
	try {
1110
	  char c;
1111
	  std::string section, caption;
1112
	  line >> c;
1113
	  _reader_bits::readToken(line, section);
1114
	  _reader_bits::readToken(line, caption);
1115

	
1116
	  if (line >> c) 
1117
	    throw DataFormatError("Extra character on the end of line");
1118

	
1119
	  if (section == "nodes" && !nodes_done) {
1120
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1121
	      readNodes();
1122
	      nodes_done = true;
1123
	    }
1124
	  } else if ((section == "arcs" || section == "edges") && 
1125
		     !arcs_done) {
1126
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
1127
	      readArcs();
1128
	      arcs_done = true;
1129
	    }
1130
	  } else if (section == "attributes" && !attributes_done) {
1131
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1132
	      readAttributes();
1133
	      attributes_done = true;
1134
	    }
1135
	  } else {
1136
	    readLine();
1137
	    skipSection();
1138
	  }
1139
	} catch (DataFormatError& error) {
1140
	  error.line(line_num);
1141
	  throw;
1142
	}	
1143
      }
1144

	
1145
      if (!nodes_done) {
1146
	throw DataFormatError("Section @nodes not found");
1147
      }
1148

	
1149
      if (!arcs_done) {
1150
	throw DataFormatError("Section @arcs not found");
1151
      }
1152

	
1153
      if (!attributes_done && !_attributes.empty()) {
1154
	throw DataFormatError("Section @attributes not found");
1155
      }
1156

	
1157
    }
1158

	
1159
    /// @}
1160
    
1161
  };
1162

	
1163
  /// \relates DigraphReader
1164
  template <typename Digraph>
1165
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1166
    DigraphReader<Digraph> tmp(is, digraph);
1167
    return tmp;
1168
  }
1169

	
1170
  /// \relates DigraphReader
1171
  template <typename Digraph>
1172
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1173
				       Digraph& digraph) {
1174
    DigraphReader<Digraph> tmp(fn, digraph);
1175
    return tmp;
1176
  }
1177

	
1178
  /// \relates DigraphReader
1179
  template <typename Digraph>
1180
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1181
    DigraphReader<Digraph> tmp(fn, digraph);
1182
    return tmp;
1183
  }
1184

	
1185
  /// \ingroup lemon_io
1186
  ///  
1187
  /// \brief LGF reader for undirected graphs
1188
  ///
1189
  /// This utility reads an \ref lgf-format "LGF" file.
1190
  template <typename _Graph>
1191
  class GraphReader {
1192
  public:
1193

	
1194
    typedef _Graph Graph;
1195
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1196
    
1197
  private:
1198

	
1199
    std::istream* _is;
1200
    bool local_is;
1201

	
1202
    Graph& _graph;
1203

	
1204
    std::string _nodes_caption;
1205
    std::string _edges_caption;
1206
    std::string _attributes_caption;
1207

	
1208
    typedef std::map<std::string, Node> NodeIndex;
1209
    NodeIndex _node_index;
1210
    typedef std::map<std::string, Edge> EdgeIndex;
1211
    EdgeIndex _edge_index;
1212
    
1213
    typedef std::vector<std::pair<std::string, 
1214
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1215
    NodeMaps _node_maps; 
1216

	
1217
    typedef std::vector<std::pair<std::string,
1218
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1219
    EdgeMaps _edge_maps;
1220

	
1221
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1222
      Attributes;
1223
    Attributes _attributes;
1224

	
1225
    bool _use_nodes;
1226
    bool _use_edges;
1227

	
1228
    bool _skip_nodes;
1229
    bool _skip_edges;
1230

	
1231
    int line_num;
1232
    std::istringstream line;
1233

	
1234
  public:
1235

	
1236
    /// \brief Constructor
1237
    ///
1238
    /// Construct a undirected graph reader, which reads from the given
1239
    /// input stream.
1240
    GraphReader(std::istream& is, Graph& graph) 
1241
      : _is(&is), local_is(false), _graph(graph),
1242
	_use_nodes(false), _use_edges(false),
1243
	_skip_nodes(false), _skip_edges(false) {}
1244

	
1245
    /// \brief Constructor
1246
    ///
1247
    /// Construct a undirected graph reader, which reads from the given
1248
    /// file.
1249
    GraphReader(const std::string& fn, Graph& graph) 
1250
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1251
    	_use_nodes(false), _use_edges(false),
1252
	_skip_nodes(false), _skip_edges(false) {}
1253
    
1254
    /// \brief Constructor
1255
    ///
1256
    /// Construct a undirected graph reader, which reads from the given
1257
    /// file.
1258
    GraphReader(const char* fn, Graph& graph) 
1259
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1260
    	_use_nodes(false), _use_edges(false),
1261
	_skip_nodes(false), _skip_edges(false) {}
1262

	
1263
    /// \brief Copy constructor
1264
    ///
1265
    /// The copy constructor transfers all data from the other reader,
1266
    /// therefore the copied reader will not be usable more. 
1267
    GraphReader(GraphReader& other) 
1268
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1269
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1270
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1271

	
1272
      other._is = 0;
1273
      other.local_is = false;
1274
      
1275
      _node_index.swap(other._node_index);
1276
      _edge_index.swap(other._edge_index);
1277

	
1278
      _node_maps.swap(other._node_maps);
1279
      _edge_maps.swap(other._edge_maps);
1280
      _attributes.swap(other._attributes);
1281

	
1282
      _nodes_caption = other._nodes_caption;
1283
      _edges_caption = other._edges_caption;
1284
      _attributes_caption = other._attributes_caption;
1285

	
1286
    }
1287

	
1288
    /// \brief Destructor
1289
    ~GraphReader() {
1290
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1291
	   it != _node_maps.end(); ++it) {
1292
	delete it->second;
1293
      }
1294

	
1295
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1296
	   it != _edge_maps.end(); ++it) {
1297
	delete it->second;
1298
      }
1299

	
1300
      for (typename Attributes::iterator it = _attributes.begin(); 
1301
	   it != _attributes.end(); ++it) {
1302
	delete it->second;
1303
      }
1304

	
1305
      if (local_is) {
1306
	delete _is;
1307
      }
1308

	
1309
    }
1310

	
1311
  private:
1312
    
1313
    GraphReader& operator=(const GraphReader&);
1314

	
1315
  public:
1316

	
1317
    /// \name Reading rules
1318
    /// @{
1319
    
1320
    /// \brief Node map reading rule
1321
    ///
1322
    /// Add a node map reading rule to the reader.
1323
    template <typename Map>
1324
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1325
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1326
      _reader_bits::MapStorageBase<Node>* storage = 
1327
	new _reader_bits::MapStorage<Node, Map>(map);
1328
      _node_maps.push_back(std::make_pair(caption, storage));
1329
      return *this;
1330
    }
1331

	
1332
    /// \brief Node map reading rule
1333
    ///
1334
    /// Add a node map reading rule with specialized converter to the
1335
    /// reader.
1336
    template <typename Map, typename Converter>
1337
    GraphReader& nodeMap(const std::string& caption, Map& map, 
1338
			   const Converter& converter = Converter()) {
1339
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1340
      _reader_bits::MapStorageBase<Node>* storage = 
1341
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1342
      _node_maps.push_back(std::make_pair(caption, storage));
1343
      return *this;
1344
    }
1345

	
1346
    /// \brief Edge map reading rule
1347
    ///
1348
    /// Add an edge map reading rule to the reader.
1349
    template <typename Map>
1350
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1351
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1352
      _reader_bits::MapStorageBase<Edge>* storage = 
1353
	new _reader_bits::MapStorage<Edge, Map>(map);
1354
      _edge_maps.push_back(std::make_pair(caption, storage));
1355
      return *this;
1356
    }
1357

	
1358
    /// \brief Edge map reading rule
1359
    ///
1360
    /// Add an edge map reading rule with specialized converter to the
1361
    /// reader.
1362
    template <typename Map, typename Converter>
1363
    GraphReader& edgeMap(const std::string& caption, Map& map, 
1364
			  const Converter& converter = Converter()) {
1365
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1366
      _reader_bits::MapStorageBase<Edge>* storage = 
1367
	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1368
      _edge_maps.push_back(std::make_pair(caption, storage));
1369
      return *this;
1370
    }
1371

	
1372
    /// \brief Arc map reading rule
1373
    ///
1374
    /// Add an arc map reading rule to the reader.
1375
    template <typename Map>
1376
    GraphReader& arcMap(const std::string& caption, Map& map) {
1377
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1378
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1379
	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1380
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1381
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1382
	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1383
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1384
      return *this;
1385
    }
1386

	
1387
    /// \brief Arc map reading rule
1388
    ///
1389
    /// Add an arc map reading rule with specialized converter to the
1390
    /// reader.
1391
    template <typename Map, typename Converter>
1392
    GraphReader& arcMap(const std::string& caption, Map& map, 
1393
			  const Converter& converter = Converter()) {
1394
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1395
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1396
	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1397
	(_graph, map, converter);
1398
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1399
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1400
	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1401
	(_graph, map, converter);
1402
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1403
      return *this;
1404
    }
1405

	
1406
    /// \brief Attribute reading rule
1407
    ///
1408
    /// Add an attribute reading rule to the reader.
1409
    template <typename Value>
1410
    GraphReader& attribute(const std::string& caption, Value& value) {
1411
      _reader_bits::ValueStorageBase* storage = 
1412
	new _reader_bits::ValueStorage<Value>(value);
1413
      _attributes.insert(std::make_pair(caption, storage));
1414
      return *this;
1415
    }
1416

	
1417
    /// \brief Attribute reading rule
1418
    ///
1419
    /// Add an attribute reading rule with specialized converter to the
1420
    /// reader.
1421
    template <typename Value, typename Converter>
1422
    GraphReader& attribute(const std::string& caption, Value& value, 
1423
			     const Converter& converter = Converter()) {
1424
      _reader_bits::ValueStorageBase* storage = 
1425
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1426
      _attributes.insert(std::make_pair(caption, storage));
1427
      return *this;
1428
    }
1429

	
1430
    /// \brief Node reading rule
1431
    ///
1432
    /// Add a node reading rule to reader.
1433
    GraphReader& node(const std::string& caption, Node& node) {
1434
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1435
      Converter converter(_node_index);
1436
      _reader_bits::ValueStorageBase* storage = 
1437
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1438
      _attributes.insert(std::make_pair(caption, storage));
1439
      return *this;
1440
    }
1441

	
1442
    /// \brief Edge reading rule
1443
    ///
1444
    /// Add an edge reading rule to reader.
1445
    GraphReader& edge(const std::string& caption, Edge& edge) {
1446
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1447
      Converter converter(_edge_index);
1448
      _reader_bits::ValueStorageBase* storage = 
1449
	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1450
      _attributes.insert(std::make_pair(caption, storage));
1451
      return *this;
1452
    }
1453

	
1454
    /// \brief Arc reading rule
1455
    ///
1456
    /// Add an arc reading rule to reader.
1457
    GraphReader& arc(const std::string& caption, Arc& arc) {
1458
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1459
      Converter converter(_graph, _edge_index);
1460
      _reader_bits::ValueStorageBase* storage = 
1461
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1462
      _attributes.insert(std::make_pair(caption, storage));
1463
      return *this;
1464
    }
1465

	
1466
    /// @}
1467

	
1468
    /// \name Select section by name
1469
    /// @{
1470

	
1471
    /// \brief Set \c \@nodes section to be read
1472
    ///
1473
    /// Set \c \@nodes section to be read
1474
    GraphReader& nodes(const std::string& caption) {
1475
      _nodes_caption = caption;
1476
      return *this;
1477
    }
1478

	
1479
    /// \brief Set \c \@edges section to be read
1480
    ///
1481
    /// Set \c \@edges section to be read
1482
    GraphReader& edges(const std::string& caption) {
1483
      _edges_caption = caption;
1484
      return *this;
1485
    }
1486

	
1487
    /// \brief Set \c \@attributes section to be read
1488
    ///
1489
    /// Set \c \@attributes section to be read
1490
    GraphReader& attributes(const std::string& caption) {
1491
      _attributes_caption = caption;
1492
      return *this;
1493
    }
1494

	
1495
    /// @}
1496

	
1497
    /// \name Using previously constructed node or edge set
1498
    /// @{
1499

	
1500
    /// \brief Use previously constructed node set
1501
    ///
1502
    /// Use previously constructed node set, and specify the node
1503
    /// label map.
1504
    template <typename Map>
1505
    GraphReader& useNodes(const Map& map) {
1506
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1507
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1508
      _use_nodes = true;
1509
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1510
      for (NodeIt n(_graph); n != INVALID; ++n) {
1511
	_node_index.insert(std::make_pair(converter(map[n]), n));
1512
      }
1513
      return *this;
1514
    }
1515

	
1516
    /// \brief Use previously constructed node set
1517
    ///
1518
    /// Use previously constructed node set, and specify the node
1519
    /// label map and a functor which converts the label map values to
1520
    /// std::string.
1521
    template <typename Map, typename Converter>
1522
    GraphReader& useNodes(const Map& map, 
1523
			    const Converter& converter = Converter()) {
1524
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1525
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1526
      _use_nodes = true;
1527
      for (NodeIt n(_graph); n != INVALID; ++n) {
1528
	_node_index.insert(std::make_pair(converter(map[n]), n));
1529
      }
1530
      return *this;
1531
    }
1532

	
1533
    /// \brief Use previously constructed edge set
1534
    ///
1535
    /// Use previously constructed edge set, and specify the edge
1536
    /// label map.
1537
    template <typename Map>
1538
    GraphReader& useEdges(const Map& map) {
1539
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1540
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1541
      _use_edges = true;
1542
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1543
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1544
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1545
      }
1546
      return *this;
1547
    }
1548

	
1549
    /// \brief Use previously constructed edge set
1550
    ///
1551
    /// Use previously constructed edge set, and specify the edge
1552
    /// label map and a functor which converts the label map values to
1553
    /// std::string.
1554
    template <typename Map, typename Converter>
1555
    GraphReader& useEdges(const Map& map, 
1556
			    const Converter& converter = Converter()) {
1557
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1558
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
1559
      _use_edges = true;
1560
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1561
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1562
      }
1563
      return *this;
1564
    }
1565

	
1566
    /// \brief Skips the reading of node section
1567
    ///
1568
    /// Omit the reading of the node section. This implies that each node
1569
    /// map reading rule will be abanoned, and the nodes of the graph
1570
    /// will not be constructed, which usually cause that the edge set
1571
    /// could not be read due to lack of node name
1572
    /// resolving. Therefore, the \c skipEdges() should be used too, or
1573
    /// the useNodes() member function should be used to specify the
1574
    /// label of the nodes.
1575
    GraphReader& skipNodes() {
1576
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
1577
      _skip_nodes = true;
1578
      return *this;
1579
    }
1580

	
1581
    /// \brief Skips the reading of edge section
1582
    ///
1583
    /// Omit the reading of the edge section. This implies that each edge
1584
    /// map reading rule will be abanoned, and the edges of the graph
1585
    /// will not be constructed.
1586
    GraphReader& skipEdges() {
1587
      LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 
1588
      _skip_edges = true;
1589
      return *this;
1590
    }
1591

	
1592
    /// @}
1593

	
1594
  private:
1595

	
1596
    bool readLine() {
1597
      std::string str;
1598
      while(++line_num, std::getline(*_is, str)) {
1599
	line.clear(); line.str(str);
1600
	char c;
1601
	if (line >> std::ws >> c && c != '#') {
1602
	  line.putback(c);
1603
	  return true;
1604
	}
1605
      }
1606
      return false;
1607
    }
1608

	
1609
    bool readSuccess() {
1610
      return static_cast<bool>(*_is);
1611
    }
1612
    
1613
    void skipSection() {
1614
      char c;
1615
      while (readSuccess() && line >> c && c != '@') {
1616
	readLine();
1617
      }
1618
      line.putback(c);
1619
    }
1620

	
1621
    void readNodes() {
1622

	
1623
      std::vector<int> map_index(_node_maps.size());
1624
      int map_num, label_index;
1625

	
1626
      char c;
1627
      if (!readLine() || !(line >> c) || c == '@') {
1628
	if (readSuccess() && line) line.putback(c);
1629
	if (!_node_maps.empty()) 
1630
	  throw DataFormatError("Cannot find map names");
1631
	return;
1632
      }
1633
      line.putback(c);
1634
      
1635
      {
1636
	std::map<std::string, int> maps;
1637
	
1638
	std::string map;
1639
	int index = 0;
1640
	while (_reader_bits::readToken(line, map)) {
1641
	  if (maps.find(map) != maps.end()) {
1642
	    std::ostringstream msg;
1643
	    msg << "Multiple occurence of node map: " << map;
1644
	    throw DataFormatError(msg.str().c_str());
1645
	  }
1646
	  maps.insert(std::make_pair(map, index));
1647
	  ++index;
1648
	}
1649
	
1650
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1651
	  std::map<std::string, int>::iterator jt = 
1652
	    maps.find(_node_maps[i].first);
1653
	  if (jt == maps.end()) {
1654
	    std::ostringstream msg;
1655
	    msg << "Map not found in file: " << _node_maps[i].first;
1656
	    throw DataFormatError(msg.str().c_str());
1657
	  }
1658
	  map_index[i] = jt->second;
1659
	}
1660

	
1661
	{
1662
	  std::map<std::string, int>::iterator jt = maps.find("label");
1663
	  if (jt != maps.end()) {
1664
	    label_index = jt->second;
1665
	  } else {
1666
	    label_index = -1;
1667
	  }
1668
	}
1669
	map_num = maps.size();
1670
      }
1671

	
1672
      while (readLine() && line >> c && c != '@') {
1673
	line.putback(c);
1674

	
1675
	std::vector<std::string> tokens(map_num);
1676
	for (int i = 0; i < map_num; ++i) {
1677
	  if (!_reader_bits::readToken(line, tokens[i])) {
1678
	    std::ostringstream msg;
1679
	    msg << "Column not found (" << i + 1 << ")";
1680
	    throw DataFormatError(msg.str().c_str());
1681
	  }
1682
	}
1683
	if (line >> std::ws >> c)
1684
	  throw DataFormatError("Extra character on the end of line");
1685
	
1686
	Node n;
1687
	if (!_use_nodes) {
1688
	  n = _graph.addNode();
1689
	  if (label_index != -1) 
1690
	    _node_index.insert(std::make_pair(tokens[label_index], n));
1691
	} else {
1692
	  if (label_index == -1) 
1693
	    throw DataFormatError("Label map not found in file");
1694
	  typename std::map<std::string, Node>::iterator it =
1695
	    _node_index.find(tokens[label_index]);
1696
	  if (it == _node_index.end()) {
1697
	    std::ostringstream msg;
1698
	    msg << "Node with label not found: " << tokens[label_index];
1699
	    throw DataFormatError(msg.str().c_str());	    
1700
	  }
1701
	  n = it->second;
1702
	}
1703

	
1704
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1705
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
1706
	}
1707

	
1708
      }
1709
      if (readSuccess()) {
1710
	line.putback(c);
1711
      }
1712
    }
1713

	
1714
    void readEdges() {
1715

	
1716
      std::vector<int> map_index(_edge_maps.size());
1717
      int map_num, label_index;
1718

	
1719
      char c;
1720
      if (!readLine() || !(line >> c) || c == '@') {
1721
	if (readSuccess() && line) line.putback(c);
1722
	if (!_edge_maps.empty()) 
1723
	  throw DataFormatError("Cannot find map names");
1724
	return;
1725
      }
1726
      line.putback(c);
1727
      
1728
      {
1729
	std::map<std::string, int> maps;
1730
	
1731
	std::string map;
1732
	int index = 0;
1733
	while (_reader_bits::readToken(line, map)) {
1734
	  if (maps.find(map) != maps.end()) {
1735
	    std::ostringstream msg;
1736
	    msg << "Multiple occurence of edge map: " << map;
1737
	    throw DataFormatError(msg.str().c_str());
1738
	  }
1739
	  maps.insert(std::make_pair(map, index));
1740
	  ++index;
1741
	}
1742
	
1743
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1744
	  std::map<std::string, int>::iterator jt = 
1745
	    maps.find(_edge_maps[i].first);
1746
	  if (jt == maps.end()) {
1747
	    std::ostringstream msg;
1748
	    msg << "Map not found in file: " << _edge_maps[i].first;
1749
	    throw DataFormatError(msg.str().c_str());
1750
	  }
1751
	  map_index[i] = jt->second;
1752
	}
1753

	
1754
	{
1755
	  std::map<std::string, int>::iterator jt = maps.find("label");
1756
	  if (jt != maps.end()) {
1757
	    label_index = jt->second;
1758
	  } else {
1759
	    label_index = -1;
1760
	  }
1761
	}
1762
	map_num = maps.size();
1763
      }
1764

	
1765
      while (readLine() && line >> c && c != '@') {
1766
	line.putback(c);
1767

	
1768
	std::string source_token;
1769
	std::string target_token;
1770

	
1771
	if (!_reader_bits::readToken(line, source_token))
1772
	  throw DataFormatError("Node u not found");
1773

	
1774
	if (!_reader_bits::readToken(line, target_token))
1775
	  throw DataFormatError("Node v not found");
1776
	
1777
	std::vector<std::string> tokens(map_num);
1778
	for (int i = 0; i < map_num; ++i) {
1779
	  if (!_reader_bits::readToken(line, tokens[i])) {
1780
	    std::ostringstream msg;
1781
	    msg << "Column not found (" << i + 1 << ")";
1782
	    throw DataFormatError(msg.str().c_str());
1783
	  }
1784
	}
1785
	if (line >> std::ws >> c)
1786
	  throw DataFormatError("Extra character on the end of line");
1787
	
1788
	Edge e;
1789
	if (!_use_edges) {
1790

	
1791
          typename NodeIndex::iterator it;
1792
 
1793
          it = _node_index.find(source_token);
1794
          if (it == _node_index.end()) {
1795
            std::ostringstream msg;
1796
            msg << "Item not found: " << source_token;
1797
            throw DataFormatError(msg.str().c_str());
1798
          }
1799
          Node source = it->second;
1800

	
1801
          it = _node_index.find(target_token);
1802
          if (it == _node_index.end()) {       
1803
            std::ostringstream msg;            
1804
            msg << "Item not found: " << target_token;
1805
            throw DataFormatError(msg.str().c_str());
1806
          }                                          
1807
          Node target = it->second;                            
1808

	
1809
	  e = _graph.addEdge(source, target);
1810
	  if (label_index != -1) 
1811
	    _edge_index.insert(std::make_pair(tokens[label_index], e));
1812
	} else {
1813
	  if (label_index == -1) 
1814
	    throw DataFormatError("Label map not found in file");
1815
	  typename std::map<std::string, Edge>::iterator it =
1816
	    _edge_index.find(tokens[label_index]);
1817
	  if (it == _edge_index.end()) {
1818
	    std::ostringstream msg;
1819
	    msg << "Edge with label not found: " << tokens[label_index];
1820
	    throw DataFormatError(msg.str().c_str());	    
1821
	  }
1822
	  e = it->second;
1823
	}
1824

	
1825
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1826
	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
1827
	}
1828

	
1829
      }
1830
      if (readSuccess()) {
1831
	line.putback(c);
1832
      }
1833
    }
1834

	
1835
    void readAttributes() {
1836

	
1837
      std::set<std::string> read_attr;
1838

	
1839
      char c;
1840
      while (readLine() && line >> c && c != '@') {
1841
	line.putback(c);
1842
	
1843
	std::string attr, token;
1844
	if (!_reader_bits::readToken(line, attr))
1845
	  throw DataFormatError("Attribute name not found");
1846
	if (!_reader_bits::readToken(line, token))
1847
	  throw DataFormatError("Attribute value not found");
1848
	if (line >> c)
1849
	  throw DataFormatError("Extra character on the end of line");	  
1850

	
1851
	{
1852
	  std::set<std::string>::iterator it = read_attr.find(attr);
1853
	  if (it != read_attr.end()) {
1854
	    std::ostringstream msg;
1855
	    msg << "Multiple occurence of attribute " << attr;
1856
	    throw DataFormatError(msg.str().c_str());
1857
	  }
1858
	  read_attr.insert(attr);
1859
	}
1860
	
1861
	{
1862
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1863
	  while (it != _attributes.end() && it->first == attr) {
1864
	    it->second->set(token);
1865
	    ++it;
1866
	  }
1867
	}
1868

	
1869
      }
1870
      if (readSuccess()) {
1871
	line.putback(c);
1872
      }
1873
      for (typename Attributes::iterator it = _attributes.begin();
1874
	   it != _attributes.end(); ++it) {
1875
	if (read_attr.find(it->first) == read_attr.end()) {
1876
	  std::ostringstream msg;
1877
	  msg << "Attribute not found in file: " << it->first;
1878
	  throw DataFormatError(msg.str().c_str());
1879
	}	
1880
      }
1881
    }
1882

	
1883
  public:
1884

	
1885
    /// \name Execution of the reader    
1886
    /// @{
1887

	
1888
    /// \brief Start the batch processing
1889
    ///
1890
    /// This function starts the batch processing
1891
    void run() {
1892
      
1893
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1894
      
1895
      bool nodes_done = _skip_nodes;
1896
      bool edges_done = _skip_edges;
1897
      bool attributes_done = false;
1898

	
1899
      line_num = 0;      
1900
      readLine();
1901
      skipSection();
1902

	
1903
      while (readSuccess()) {
1904
	try {
1905
	  char c;
1906
	  std::string section, caption;
1907
	  line >> c;
1908
	  _reader_bits::readToken(line, section);
1909
	  _reader_bits::readToken(line, caption);
1910

	
1911
	  if (line >> c) 
1912
	    throw DataFormatError("Extra character on the end of line");
1913

	
1914
	  if (section == "nodes" && !nodes_done) {
1915
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1916
	      readNodes();
1917
	      nodes_done = true;
1918
	    }
1919
	  } else if ((section == "edges" || section == "arcs") && 
1920
		     !edges_done) {
1921
	    if (_edges_caption.empty() || _edges_caption == caption) {
1922
	      readEdges();
1923
	      edges_done = true;
1924
	    }
1925
	  } else if (section == "attributes" && !attributes_done) {
1926
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1927
	      readAttributes();
1928
	      attributes_done = true;
1929
	    }
1930
	  } else {
1931
	    readLine();
1932
	    skipSection();
1933
	  }
1934
	} catch (DataFormatError& error) {
1935
	  error.line(line_num);
1936
	  throw;
1937
	}	
1938
      }
1939

	
1940
      if (!nodes_done) {
1941
	throw DataFormatError("Section @nodes not found");
1942
      }
1943

	
1944
      if (!edges_done) {
1945
	throw DataFormatError("Section @edges not found");
1946
      }
1947

	
1948
      if (!attributes_done && !_attributes.empty()) {
1949
	throw DataFormatError("Section @attributes not found");
1950
      }
1951

	
1952
    }
1953

	
1954
    /// @}
1955
    
1956
  };
1957

	
1958
  /// \relates GraphReader
1959
  template <typename Graph>
1960
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
1961
    GraphReader<Graph> tmp(is, graph);
1962
    return tmp;
1963
  }
1964

	
1965
  /// \relates GraphReader
1966
  template <typename Graph>
1967
  GraphReader<Graph> graphReader(const std::string& fn, 
1968
				       Graph& graph) {
1969
    GraphReader<Graph> tmp(fn, graph);
1970
    return tmp;
1971
  }
1972

	
1973
  /// \relates GraphReader
1974
  template <typename Graph>
1975
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
1976
    GraphReader<Graph> tmp(fn, graph);
1977
    return tmp;
1978
  }
1979

	
1980
  /// \brief Section reader class
1981
  ///
1982
  /// In the \e LGF file extra sections can be placed, which contain
1983
  /// any data in arbitrary format. Such sections can be read with
1984
  /// this class. A reading rule can be added with two different
1985
  /// functions, with the \c sectionLines() function a functor can
1986
  /// process the section line-by-line. While with the \c
1987
  /// sectionStream() member the section can be read from an input
1988
  /// stream.
1989
  class SectionReader {
1990
  private:
1991
    
1992
    std::istream* _is;
1993
    bool local_is;
1994

	
1995
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1996
    Sections _sections;
1997

	
1998
    int line_num;
1999
    std::istringstream line;
2000

	
2001
  public:
2002

	
2003
    /// \brief Constructor
2004
    ///
2005
    /// Construct a section reader, which reads from the given input
2006
    /// stream.
2007
    SectionReader(std::istream& is) 
2008
      : _is(&is), local_is(false) {}
2009

	
2010
    /// \brief Constructor
2011
    ///
2012
    /// Construct a section reader, which reads from the given file.
2013
    SectionReader(const std::string& fn) 
2014
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2015
    
2016
    /// \brief Constructor
2017
    ///
2018
    /// Construct a section reader, which reads from the given file.
2019
    SectionReader(const char* fn) 
2020
      : _is(new std::ifstream(fn)), local_is(true) {}
2021

	
2022
    /// \brief Copy constructor
2023
    ///
2024
    /// The copy constructor transfers all data from the other reader,
2025
    /// therefore the copied reader will not be usable more. 
2026
    SectionReader(SectionReader& other) 
2027
      : _is(other._is), local_is(other.local_is) {
2028

	
2029
      other._is = 0;
2030
      other.local_is = false;
2031
      
2032
      _sections.swap(other._sections);
2033
    }
2034

	
2035
    /// \brief Destructor
2036
    ~SectionReader() {
2037
      for (Sections::iterator it = _sections.begin(); 
2038
	   it != _sections.end(); ++it) {
2039
	delete it->second;
2040
      }
2041

	
2042
      if (local_is) {
2043
	delete _is;
2044
      }
2045

	
2046
    }
2047

	
2048
  private:
2049
    
2050
    SectionReader& operator=(const SectionReader&);
2051

	
2052
  public:
2053

	
711 2054
    /// \name Section readers
712 2055
    /// @{
713 2056

	
714 2057
    /// \brief Add a section processor with line oriented reading
715 2058
    ///
716
    /// In the \e LGF file extra sections can be placed, which contain
717
    /// any data in arbitrary format. These sections can be read with
718
    /// this function line by line. The first parameter is the type
719
    /// descriptor of the section, the second is a functor, which
720
    /// takes just one \c std::string parameter. At the reading
721
    /// process, each line of the section will be given to the functor
722
    /// object. However, the empty lines and the comment lines are
723
    /// filtered out, and the leading whitespaces are stipped from
724
    /// each processed string.
2059
    /// The first parameter is the type descriptor of the section, the
2060
    /// second is a functor, which takes just one \c std::string
2061
    /// parameter. At the reading process, each line of the section
2062
    /// will be given to the functor object. However, the empty lines
2063
    /// and the comment lines are filtered out, and the leading
2064
    /// whitespaces are trimmed from each processed string.
725 2065
    ///
726 2066
    /// For example let's see a section, which contain several
727 2067
    /// integers, which should be inserted into a vector.
... ...
@@ -749,12 +2089,10 @@
749 2089
    ///  reader.sectionLines("numbers", NumberSection(vec));  
750 2090
    ///\endcode
751 2091
    template <typename Functor>
752
    DigraphReader& sectionLines(const std::string& type, Functor functor) {
2092
    SectionReader& sectionLines(const std::string& type, Functor functor) {
753 2093
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
754 2094
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
755 2095
		   "Multiple reading of section.");
756
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
757
		   type != "attributes", "Multiple reading of section.");
758 2096
      _sections.insert(std::make_pair(type, 
759 2097
        new _reader_bits::LineSection<Functor>(functor)));
760 2098
      return *this;
... ...
@@ -763,21 +2101,16 @@
763 2101

	
764 2102
    /// \brief Add a section processor with stream oriented reading
765 2103
    ///
766
    /// In the \e LGF file extra sections can be placed, which contain
767
    /// any data in arbitrary format. These sections can be read
768
    /// directly with this function. The first parameter is the type
769
    /// of the section, the second is a functor, which takes an \c
770
    /// std::istream& and an int& parameter, the latter regard to the
771
    /// line number of stream. The functor can read the input while
772
    /// the section go on, and the line number should be modified
773
    /// accordingly.
2104
    /// The first parameter is the type of the section, the second is
2105
    /// a functor, which takes an \c std::istream& and an int&
2106
    /// parameter, the latter regard to the line number of stream. The
2107
    /// functor can read the input while the section go on, and the
2108
    /// line number should be modified accordingly.
774 2109
    template <typename Functor>
775
    DigraphReader& sectionStream(const std::string& type, Functor functor) {
2110
    SectionReader& sectionStream(const std::string& type, Functor functor) {
776 2111
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
777 2112
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
778 2113
		   "Multiple reading of section.");
779
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
780
		   type != "attributes", "Multiple reading of section.");
781 2114
      _sections.insert(std::make_pair(type, 
782 2115
	 new _reader_bits::StreamSection<Functor>(functor)));
783 2116
      return *this;
... ...
@@ -785,103 +2118,6 @@
785 2118
    
786 2119
    /// @}
787 2120

	
788
    /// \name Using previously constructed node or arc set
789
    /// @{
790

	
791
    /// \brief Use previously constructed node set
792
    ///
793
    /// Use previously constructed node set, and specify the node
794
    /// label map.
795
    template <typename Map>
796
    DigraphReader& useNodes(const Map& map) {
797
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
798
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
799
      _use_nodes = true;
800
      _writer_bits::DefaultConverter<typename Map::Value> converter;
801
      for (NodeIt n(_digraph); n != INVALID; ++n) {
802
	_node_index.insert(std::make_pair(converter(map[n]), n));
803
      }
804
      return *this;
805
    }
806

	
807
    /// \brief Use previously constructed node set
808
    ///
809
    /// Use previously constructed node set, and specify the node
810
    /// label map and a functor which converts the label map values to
811
    /// std::string.
812
    template <typename Map, typename Converter>
813
    DigraphReader& useNodes(const Map& map, 
814
			    const Converter& converter = Converter()) {
815
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
816
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
817
      _use_nodes = true;
818
      for (NodeIt n(_digraph); n != INVALID; ++n) {
819
	_node_index.insert(std::make_pair(converter(map[n]), n));
820
      }
821
      return *this;
822
    }
823

	
824
    /// \brief Use previously constructed arc set
825
    ///
826
    /// Use previously constructed arc set, and specify the arc
827
    /// label map.
828
    template <typename Map>
829
    DigraphReader& useArcs(const Map& map) {
830
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
831
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
832
      _use_arcs = true;
833
      _writer_bits::DefaultConverter<typename Map::Value> converter;
834
      for (ArcIt a(_digraph); a != INVALID; ++a) {
835
	_arc_index.insert(std::make_pair(converter(map[a]), a));
836
      }
837
      return *this;
838
    }
839

	
840
    /// \brief Use previously constructed arc set
841
    ///
842
    /// Use previously constructed arc set, and specify the arc
843
    /// label map and a functor which converts the label map values to
844
    /// std::string.
845
    template <typename Map, typename Converter>
846
    DigraphReader& useArcs(const Map& map, 
847
			   const Converter& converter = Converter()) {
848
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
849
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
850
      _use_arcs = true;
851
      for (ArcIt a(_digraph); a != INVALID; ++a) {
852
	_arc_index.insert(std::make_pair(converter(map[a]), a));
853
      }
854
      return *this;
855
    }
856

	
857
    /// \brief Skips the reading of node section
858
    ///
859
    /// Omit the reading of the node section. This implies that each node
860
    /// map reading rule will be abanoned, and the nodes of the graph
861
    /// will not be constructed, which usually cause that the arc set
862
    /// could not be read due to lack of node name
863
    /// resolving. Therefore, the \c skipArcs() should be used too, or
864
    /// the useNodes() member function should be used to specify the
865
    /// label of the nodes.
866
    DigraphReader& skipNodes() {
867
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
868
      _skip_nodes = true;
869
      return *this;
870
    }
871

	
872
    /// \brief Skips the reading of arc section
873
    ///
874
    /// Omit the reading of the arc section. This implies that each arc
875
    /// map reading rule will be abanoned, and the arcs of the graph
876
    /// will not be constructed.
877
    DigraphReader& skipArcs() {
878
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 
879
      _skip_arcs = true;
880
      return *this;
881
    }
882

	
883
    /// @}
884

	
885 2121
  private:
886 2122

	
887 2123
    bool readLine() {
... ...
@@ -909,270 +2145,9 @@
909 2145
      line.putback(c);
910 2146
    }
911 2147

	
912
    void readNodes() {
913

	
914
      std::vector<int> map_index(_node_maps.size());
915
      int map_num, label_index;
916

	
917
      char c;
918
      if (!readLine() || !(line >> c) || c == '@') {
919
	if (readSuccess() && line) line.putback(c);
920
	if (!_node_maps.empty()) 
921
	  throw DataFormatError("Cannot find map names");
922
	return;
923
      }
924
      line.putback(c);
925

	
926
      {
927
	std::map<std::string, int> maps;
928
	
929
	std::string map;
930
	int index = 0;
931
	while (_reader_bits::readToken(line, map)) {
932
	  if (maps.find(map) != maps.end()) {
933
	    std::ostringstream msg;
934
	    msg << "Multiple occurence of node map: " << map;
935
	    throw DataFormatError(msg.str().c_str());
936
	  }
937
	  maps.insert(std::make_pair(map, index));
938
	  ++index;
939
	}
940
	
941
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
942
	  std::map<std::string, int>::iterator jt = 
943
	    maps.find(_node_maps[i].first);
944
	  if (jt == maps.end()) {
945
	    std::ostringstream msg;
946
	    msg << "Map not found in file: " << _node_maps[i].first;
947
	    throw DataFormatError(msg.str().c_str());
948
	  }
949
	  map_index[i] = jt->second;
950
	}
951

	
952
	{
953
	  std::map<std::string, int>::iterator jt = maps.find("label");
954
	  if (jt != maps.end()) {
955
	    label_index = jt->second;
956
	  } else {
957
	    label_index = -1;
958
	  }
959
	}
960
	map_num = maps.size();
961
      }
962

	
963
      while (readLine() && line >> c && c != '@') {
964
	line.putback(c);
965

	
966
	std::vector<std::string> tokens(map_num);
967
	for (int i = 0; i < map_num; ++i) {
968
	  if (!_reader_bits::readToken(line, tokens[i])) {
969
	    std::ostringstream msg;
970
	    msg << "Column not found (" << i + 1 << ")";
971
	    throw DataFormatError(msg.str().c_str());
972
	  }
973
	}
974
	if (line >> std::ws >> c)
975
	  throw DataFormatError("Extra character on the end of line");
976
	
977
	Node n;
978
	if (!_use_nodes) {
979
	  n = _digraph.addNode();
980
	  if (label_index != -1)
981
	    _node_index.insert(std::make_pair(tokens[label_index], n));
982
	} else {
983
	  if (label_index == -1) 
984
	    throw DataFormatError("Label map not found in file");
985
	  typename std::map<std::string, Node>::iterator it =
986
	    _node_index.find(tokens[label_index]);
987
	  if (it == _node_index.end()) {
988
	    std::ostringstream msg;
989
	    msg << "Node with label not found: " << tokens[label_index];
990
	    throw DataFormatError(msg.str().c_str());	    
991
	  }
992
	  n = it->second;
993
	}
994

	
995
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
996
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
997
	}
998

	
999
      }
1000
      if (readSuccess()) {
1001
	line.putback(c);
1002
      }
1003
    }
1004

	
1005
    void readArcs() {
1006

	
1007
      std::vector<int> map_index(_arc_maps.size());
1008
      int map_num, label_index;
1009

	
1010
      char c;
1011
      if (!readLine() || !(line >> c) || c == '@') {
1012
	if (readSuccess() && line) line.putback(c);
1013
	if (!_arc_maps.empty()) 
1014
	  throw DataFormatError("Cannot find map names");
1015
	return;
1016
      }
1017
      line.putback(c);
1018
      
1019
      {
1020
	std::map<std::string, int> maps;
1021
	
1022
	std::string map;
1023
	int index = 0;
1024
	while (_reader_bits::readToken(line, map)) {
1025
	  if (maps.find(map) != maps.end()) {
1026
	    std::ostringstream msg;
1027
	    msg << "Multiple occurence of arc map: " << map;
1028
	    throw DataFormatError(msg.str().c_str());
1029
	  }
1030
	  maps.insert(std::make_pair(map, index));
1031
	  ++index;
1032
	}
1033
	
1034
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1035
	  std::map<std::string, int>::iterator jt = 
1036
	    maps.find(_arc_maps[i].first);
1037
	  if (jt == maps.end()) {
1038
	    std::ostringstream msg;
1039
	    msg << "Map not found in file: " << _arc_maps[i].first;
1040
	    throw DataFormatError(msg.str().c_str());
1041
	  }
1042
	  map_index[i] = jt->second;
1043
	}
1044

	
1045
	{
1046
	  std::map<std::string, int>::iterator jt = maps.find("label");
1047
	  if (jt != maps.end()) {
1048
	    label_index = jt->second;
1049
	  } else {
1050
	    label_index = -1;
1051
	  }
1052
	}
1053
	map_num = maps.size();
1054
      }
1055

	
1056
      while (readLine() && line >> c && c != '@') {
1057
	line.putback(c);
1058

	
1059
	std::string source_token;
1060
	std::string target_token;
1061

	
1062
	if (!_reader_bits::readToken(line, source_token))
1063
	  throw DataFormatError("Source not found");
1064

	
1065
	if (!_reader_bits::readToken(line, target_token))
1066
	  throw DataFormatError("Target not found");
1067
	
1068
	std::vector<std::string> tokens(map_num);
1069
	for (int i = 0; i < map_num; ++i) {
1070
	  if (!_reader_bits::readToken(line, tokens[i])) {
1071
	    std::ostringstream msg;
1072
	    msg << "Column not found (" << i + 1 << ")";
1073
	    throw DataFormatError(msg.str().c_str());
1074
	  }
1075
	}
1076
	if (line >> std::ws >> c)
1077
	  throw DataFormatError("Extra character on the end of line");
1078
	
1079
	Arc a;
1080
	if (!_use_arcs) {
1081

	
1082
          typename NodeIndex::iterator it;
1083
 
1084
          it = _node_index.find(source_token);
1085
          if (it == _node_index.end()) {
1086
            std::ostringstream msg;
1087
            msg << "Item not found: " << source_token;
1088
            throw DataFormatError(msg.str().c_str());
1089
          }
1090
          Node source = it->second;
1091

	
1092
          it = _node_index.find(target_token);
1093
          if (it == _node_index.end()) {       
1094
            std::ostringstream msg;            
1095
            msg << "Item not found: " << target_token;
1096
            throw DataFormatError(msg.str().c_str());
1097
          }                                          
1098
          Node target = it->second;                            
1099

	
1100
	  a = _digraph.addArc(source, target);
1101
	  if (label_index != -1) 
1102
	    _arc_index.insert(std::make_pair(tokens[label_index], a));
1103
	} else {
1104
	  if (label_index == -1) 
1105
	    throw DataFormatError("Label map not found in file");
1106
	  typename std::map<std::string, Arc>::iterator it =
1107
	    _arc_index.find(tokens[label_index]);
1108
	  if (it == _arc_index.end()) {
1109
	    std::ostringstream msg;
1110
	    msg << "Arc with label not found: " << tokens[label_index];
1111
	    throw DataFormatError(msg.str().c_str());	    
1112
	  }
1113
	  a = it->second;
1114
	}
1115

	
1116
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1117
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
1118
	}
1119

	
1120
      }
1121
      if (readSuccess()) {
1122
	line.putback(c);
1123
      }
1124
    }
1125

	
1126
    void readAttributes() {
1127

	
1128
      std::set<std::string> read_attr;
1129

	
1130
      char c;
1131
      while (readLine() && line >> c && c != '@') {
1132
	line.putback(c);
1133
	
1134
	std::string attr, token;
1135
	if (!_reader_bits::readToken(line, attr))
1136
	  throw DataFormatError("Attribute name not found");
1137
	if (!_reader_bits::readToken(line, token))
1138
	  throw DataFormatError("Attribute value not found");
1139
	if (line >> c)
1140
	  throw DataFormatError("Extra character on the end of line");	  
1141

	
1142
	{
1143
	  std::set<std::string>::iterator it = read_attr.find(attr);
1144
	  if (it != read_attr.end()) {
1145
	    std::ostringstream msg;
1146
	    msg << "Multiple occurence of attribute " << attr;
1147
	    throw DataFormatError(msg.str().c_str());
1148
	  }
1149
	  read_attr.insert(attr);
1150
	}
1151
	
1152
	{
1153
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1154
	  while (it != _attributes.end() && it->first == attr) {
1155
	    it->second->set(token);
1156
	    ++it;
1157
	  }
1158
	}
1159

	
1160
      }
1161
      if (readSuccess()) {
1162
	line.putback(c);
1163
      }
1164
      for (typename Attributes::iterator it = _attributes.begin();
1165
	   it != _attributes.end(); ++it) {
1166
	if (read_attr.find(it->first) == read_attr.end()) {
1167
	  std::ostringstream msg;
1168
	  msg << "Attribute not found in file: " << it->first;
1169
	  throw DataFormatError(msg.str().c_str());
1170
	}	
1171
      }
1172
    }
1173

	
1174 2148
  public:
1175 2149

	
2150

	
1176 2151
    /// \name Execution of the reader    
1177 2152
    /// @{
1178 2153

	
... ...
@@ -1180,14 +2155,9 @@
1180 2155
    ///
1181 2156
    /// This function starts the batch processing
1182 2157
    void run() {
2158
      
1183 2159
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1184
      if (!*_is) {
1185
	throw DataFormatError("Cannot find file");
1186
      }
1187
      
1188
      bool nodes_done = _skip_nodes;
1189
      bool arcs_done = _skip_arcs;
1190
      bool attributes_done = false;
2160
      
1191 2161
      std::set<std::string> extra_sections;
1192 2162

	
1193 2163
      line_num = 0;      
... ...
@@ -1205,23 +2175,6 @@
1205 2175
	  if (line >> c) 
1206 2176
	    throw DataFormatError("Extra character on the end of line");
1207 2177

	
1208
	  if (section == "nodes" && !nodes_done) {
1209
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1210
	      readNodes();
1211
	      nodes_done = true;
1212
	    }
1213
	  } else if ((section == "arcs" || section == "edges") && 
1214
		     !arcs_done) {
1215
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
1216
	      readArcs();
1217
	      arcs_done = true;
1218
	    }
1219
	  } else if (section == "attributes" && !attributes_done) {
1220
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1221
	      readAttributes();
1222
	      attributes_done = true;
1223
	    }
1224
	  } else {
1225 2178
	    if (extra_sections.find(section) != extra_sections.end()) {
1226 2179
	      std::ostringstream msg;
1227 2180
	      msg << "Multiple occurence of section " << section;
... ...
@@ -1234,943 +2187,40 @@
1234 2187
	    }
1235 2188
	    readLine();
1236 2189
	    skipSection();
1237
	  }
1238 2190
	} catch (DataFormatError& error) {
1239 2191
	  error.line(line_num);
1240 2192
	  throw;
1241 2193
	}	
1242 2194
      }
1243

	
1244
      if (!nodes_done) {
1245
	throw DataFormatError("Section @nodes not found");
2195
      for (Sections::iterator it = _sections.begin();
2196
	   it != _sections.end(); ++it) {
2197
	if (extra_sections.find(it->first) == extra_sections.end()) {
2198
	  std::ostringstream os;
2199
	  os << "Cannot find section: " << it->first;
2200
	  throw DataFormatError(os.str().c_str());
1246 2201
      }
1247

	
1248
      if (!arcs_done) {
1249
	throw DataFormatError("Section @arcs not found");
1250 2202
      }
1251

	
1252
      if (!attributes_done && !_attributes.empty()) {
1253
	throw DataFormatError("Section @attributes not found");
1254 2203
      }
1255 2204

	
1256
    }
1257

	
1258 2205
    /// @}
1259 2206
    
1260 2207
  };
1261 2208

	
1262
  /// \relates DigraphReader
1263
  template <typename Digraph>
1264
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1265
    DigraphReader<Digraph> tmp(is, digraph);
2209
  /// \relates SectionReader
2210
  inline SectionReader sectionReader(std::istream& is) {
2211
    SectionReader tmp(is);
1266 2212
    return tmp;
1267 2213
  }
1268 2214

	
1269
  /// \relates DigraphReader
1270
  template <typename Digraph>
1271
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1272
				       Digraph& digraph) {
1273
    DigraphReader<Digraph> tmp(fn, digraph);
2215
  /// \relates SectionReader
2216
  inline SectionReader sectionReader(const std::string& fn) {
2217
    SectionReader tmp(fn);
1274 2218
    return tmp;
1275 2219
  }
1276 2220

	
1277
  /// \relates DigraphReader
1278
  template <typename Digraph>
1279
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1280
    DigraphReader<Digraph> tmp(fn, digraph);
1281
    return tmp;
1282
  }
1283

	
1284
  /// \ingroup lemon_io
1285
  ///  
1286
  /// \brief LGF reader for undirected graphs
1287
  ///
1288
  /// This utility reads an \ref lgf-format "LGF" file.
1289
  template <typename _Graph>
1290
  class GraphReader {
1291
  public:
1292

	
1293
    typedef _Graph Graph;
1294
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1295
    
1296
  private:
1297

	
1298

	
1299
    std::istream* _is;
1300
    bool local_is;
1301

	
1302
    Graph& _graph;
1303

	
1304
    std::string _nodes_caption;
1305
    std::string _edges_caption;
1306
    std::string _attributes_caption;
1307

	
1308
    typedef std::map<std::string, Node> NodeIndex;
1309
    NodeIndex _node_index;
1310
    typedef std::map<std::string, Edge> EdgeIndex;
1311
    EdgeIndex _edge_index;
1312
    
1313
    typedef std::vector<std::pair<std::string, 
1314
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1315
    NodeMaps _node_maps; 
1316

	
1317
    typedef std::vector<std::pair<std::string,
1318
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1319
    EdgeMaps _edge_maps;
1320

	
1321
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1322
      Attributes;
1323
    Attributes _attributes;
1324

	
1325
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1326
    Sections _sections;
1327

	
1328
    bool _use_nodes;
1329
    bool _use_edges;
1330

	
1331
    bool _skip_nodes;
1332
    bool _skip_edges;
1333

	
1334
    int line_num;
1335
    std::istringstream line;
1336

	
1337
  public:
1338

	
1339
    /// \brief Constructor
1340
    ///
1341
    /// Construct a undirected graph reader, which reads from the given
1342
    /// input stream.
1343
    GraphReader(std::istream& is, Graph& graph) 
1344
      : _is(&is), local_is(false), _graph(graph),
1345
	_use_nodes(false), _use_edges(false),
1346
	_skip_nodes(false), _skip_edges(false) {}
1347

	
1348
    /// \brief Constructor
1349
    ///
1350
    /// Construct a undirected graph reader, which reads from the given
1351
    /// file.
1352
    GraphReader(const std::string& fn, Graph& graph) 
1353
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1354
    	_use_nodes(false), _use_edges(false),
1355
	_skip_nodes(false), _skip_edges(false) {}
1356
    
1357
    /// \brief Constructor
1358
    ///
1359
    /// Construct a undirected graph reader, which reads from the given
1360
    /// file.
1361
    GraphReader(const char* fn, Graph& graph) 
1362
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1363
    	_use_nodes(false), _use_edges(false),
1364
	_skip_nodes(false), _skip_edges(false) {}
1365

	
1366
    /// \brief Copy constructor
1367
    ///
1368
    /// The copy constructor transfers all data from the other reader,
1369
    /// therefore the copied reader will not be usable more. 
1370
    GraphReader(GraphReader& other) 
1371
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1372
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1373
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1374

	
1375
      other._is = 0;
1376
      other.local_is = false;
1377
      
1378
      _node_index.swap(other._node_index);
1379
      _edge_index.swap(other._edge_index);
1380

	
1381
      _node_maps.swap(other._node_maps);
1382
      _edge_maps.swap(other._edge_maps);
1383
      _attributes.swap(other._attributes);
1384

	
1385
      _nodes_caption = other._nodes_caption;
1386
      _edges_caption = other._edges_caption;
1387
      _attributes_caption = other._attributes_caption;
1388

	
1389
      _sections.swap(other._sections);
1390
    }
1391

	
1392
    /// \brief Destructor
1393
    ~GraphReader() {
1394
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1395
	   it != _node_maps.end(); ++it) {
1396
	delete it->second;
1397
      }
1398

	
1399
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1400
	   it != _edge_maps.end(); ++it) {
1401
	delete it->second;
1402
      }
1403

	
1404
      for (typename Attributes::iterator it = _attributes.begin(); 
1405
	   it != _attributes.end(); ++it) {
1406
	delete it->second;
1407
      }
1408

	
1409
      for (typename Sections::iterator it = _sections.begin(); 
1410
	   it != _sections.end(); ++it) {
1411
	delete it->second;
1412
      }
1413

	
1414
      if (local_is) {
1415
	delete _is;
1416
      }
1417

	
1418
    }
1419

	
1420
  private:
1421
    
1422
    GraphReader& operator=(const GraphReader&);
1423

	
1424
  public:
1425

	
1426
    /// \name Reading rules
1427
    /// @{
1428
    
1429
    /// \brief Node map reading rule
1430
    ///
1431
    /// Add a node map reading rule to the reader.
1432
    template <typename Map>
1433
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1434
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1435
      _reader_bits::MapStorageBase<Node>* storage = 
1436
	new _reader_bits::MapStorage<Node, Map>(map);
1437
      _node_maps.push_back(std::make_pair(caption, storage));
1438
      return *this;
1439
    }
1440

	
1441
    /// \brief Node map reading rule
1442
    ///
1443
    /// Add a node map reading rule with specialized converter to the
1444
    /// reader.
1445
    template <typename Map, typename Converter>
1446
    GraphReader& nodeMap(const std::string& caption, Map& map, 
1447
			   const Converter& converter = Converter()) {
1448
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1449
      _reader_bits::MapStorageBase<Node>* storage = 
1450
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1451
      _node_maps.push_back(std::make_pair(caption, storage));
1452
      return *this;
1453
    }
1454

	
1455
    /// \brief Edge map reading rule
1456
    ///
1457
    /// Add an edge map reading rule to the reader.
1458
    template <typename Map>
1459
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1460
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1461
      _reader_bits::MapStorageBase<Edge>* storage = 
1462
	new _reader_bits::MapStorage<Edge, Map>(map);
1463
      _edge_maps.push_back(std::make_pair(caption, storage));
1464
      return *this;
1465
    }
1466

	
1467
    /// \brief Edge map reading rule
1468
    ///
1469
    /// Add an edge map reading rule with specialized converter to the
1470
    /// reader.
1471
    template <typename Map, typename Converter>
1472
    GraphReader& edgeMap(const std::string& caption, Map& map, 
1473
			  const Converter& converter = Converter()) {
1474
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1475
      _reader_bits::MapStorageBase<Edge>* storage = 
1476
	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1477
      _edge_maps.push_back(std::make_pair(caption, storage));
1478
      return *this;
1479
    }
1480

	
1481
    /// \brief Arc map reading rule
1482
    ///
1483
    /// Add an arc map reading rule to the reader.
1484
    template <typename Map>
1485
    GraphReader& arcMap(const std::string& caption, Map& map) {
1486
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1487
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1488
	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1489
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1490
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1491
	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1492
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1493
      return *this;
1494
    }
1495

	
1496
    /// \brief Arc map reading rule
1497
    ///
1498
    /// Add an arc map reading rule with specialized converter to the
1499
    /// reader.
1500
    template <typename Map, typename Converter>
1501
    GraphReader& arcMap(const std::string& caption, Map& map, 
1502
			  const Converter& converter = Converter()) {
1503
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1504
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1505
	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1506
	(_graph, map, converter);
1507
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1508
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1509
	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1510
	(_graph, map, converter);
1511
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1512
      return *this;
1513
    }
1514

	
1515
    /// \brief Attribute reading rule
1516
    ///
1517
    /// Add an attribute reading rule to the reader.
1518
    template <typename Value>
1519
    GraphReader& attribute(const std::string& caption, Value& value) {
1520
      _reader_bits::ValueStorageBase* storage = 
1521
	new _reader_bits::ValueStorage<Value>(value);
1522
      _attributes.insert(std::make_pair(caption, storage));
1523
      return *this;
1524
    }
1525

	
1526
    /// \brief Attribute reading rule
1527
    ///
1528
    /// Add an attribute reading rule with specialized converter to the
1529
    /// reader.
1530
    template <typename Value, typename Converter>
1531
    GraphReader& attribute(const std::string& caption, Value& value, 
1532
			     const Converter& converter = Converter()) {
1533
      _reader_bits::ValueStorageBase* storage = 
1534
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1535
      _attributes.insert(std::make_pair(caption, storage));
1536
      return *this;
1537
    }
1538

	
1539
    /// \brief Node reading rule
1540
    ///
1541
    /// Add a node reading rule to reader.
1542
    GraphReader& node(const std::string& caption, Node& node) {
1543
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1544
      Converter converter(_node_index);
1545
      _reader_bits::ValueStorageBase* storage = 
1546
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1547
      _attributes.insert(std::make_pair(caption, storage));
1548
      return *this;
1549
    }
1550

	
1551
    /// \brief Edge reading rule
1552
    ///
1553
    /// Add an edge reading rule to reader.
1554
    GraphReader& edge(const std::string& caption, Edge& edge) {
1555
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1556
      Converter converter(_edge_index);
1557
      _reader_bits::ValueStorageBase* storage = 
1558
	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1559
      _attributes.insert(std::make_pair(caption, storage));
1560
      return *this;
1561
    }
1562

	
1563
    /// \brief Arc reading rule
1564
    ///
1565
    /// Add an arc reading rule to reader.
1566
    GraphReader& arc(const std::string& caption, Arc& arc) {
1567
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1568
      Converter converter(_graph, _edge_index);
1569
      _reader_bits::ValueStorageBase* storage = 
1570
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1571
      _attributes.insert(std::make_pair(caption, storage));
1572
      return *this;
1573
    }
1574

	
1575
    /// @}
1576

	
1577
    /// \name Select section by name
1578
    /// @{
1579

	
1580
    /// \brief Set \c \@nodes section to be read
1581
    ///
1582
    /// Set \c \@nodes section to be read
1583
    GraphReader& nodes(const std::string& caption) {
1584
      _nodes_caption = caption;
1585
      return *this;
1586
    }
1587

	
1588
    /// \brief Set \c \@edges section to be read
1589
    ///
1590
    /// Set \c \@edges section to be read
1591
    GraphReader& edges(const std::string& caption) {
1592
      _edges_caption = caption;
1593
      return *this;
1594
    }
1595

	
1596
    /// \brief Set \c \@attributes section to be read
1597
    ///
1598
    /// Set \c \@attributes section to be read
1599
    GraphReader& attributes(const std::string& caption) {
1600
      _attributes_caption = caption;
1601
      return *this;
1602
    }
1603

	
1604
    /// @}
1605

	
1606
    /// \name Section readers
1607
    /// @{
1608

	
1609
    /// \brief Add a section processor with line oriented reading
1610
    ///
1611
    /// In the \e LGF file extra sections can be placed, which contain
1612
    /// any data in arbitrary format. These sections can be read with
1613
    /// this function line by line. The first parameter is the type
1614
    /// descriptor of the section, the second is a functor, which
1615
    /// takes just one \c std::string parameter. At the reading
1616
    /// process, each line of the section will be given to the functor
1617
    /// object. However, the empty lines and the comment lines are
1618
    /// filtered out, and the leading whitespaces are stipped from
1619
    /// each processed string.
1620
    ///
1621
    /// For example let's see a section, which contain several
1622
    /// integers, which should be inserted into a vector.
1623
    ///\code
1624
    ///  @numbers
1625
    ///  12 45 23
1626
    ///  4
1627
    ///  23 6
1628
    ///\endcode
1629
    ///
1630
    /// The functor is implemented as an struct:
1631
    ///\code
1632
    ///  struct NumberSection {
1633
    ///    std::vector<int>& _data;
1634
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
1635
    ///    void operator()(const std::string& line) {
1636
    ///      std::istringstream ls(line);
1637
    ///      int value;
1638
    ///      while (ls >> value) _data.push_back(value);
1639
    ///    }
1640
    ///  };
1641
    ///
1642
    ///  // ...
1643
    ///
1644
    ///  reader.sectionLines("numbers", NumberSection(vec));  
1645
    ///\endcode
1646
    template <typename Functor>
1647
    GraphReader& sectionLines(const std::string& type, Functor functor) {
1648
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1649
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1650
		   "Multiple reading of section.");
1651
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1652
		   type != "attributes", "Multiple reading of section.");
1653
      _sections.insert(std::make_pair(type, 
1654
        new _reader_bits::LineSection<Functor>(functor)));
1655
      return *this;
1656
    }
1657

	
1658

	
1659
    /// \brief Add a section processor with stream oriented reading
1660
    ///
1661
    /// In the \e LGF file extra sections can be placed, which contain
1662
    /// any data in arbitrary format. These sections can be read
1663
    /// directly with this function. The first parameter is the type
1664
    /// of the section, the second is a functor, which takes an \c
1665
    /// std::istream& and an int& parameter, the latter regard to the
1666
    /// line number of stream. The functor can read the input while
1667
    /// the section go on, and the line number should be modified
1668
    /// accordingly.
1669
    template <typename Functor>
1670
    GraphReader& sectionStream(const std::string& type, Functor functor) {
1671
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1672
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1673
		   "Multiple reading of section.");
1674
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1675
		   type != "attributes", "Multiple reading of section.");
1676
      _sections.insert(std::make_pair(type, 
1677
	 new _reader_bits::StreamSection<Functor>(functor)));
1678
      return *this;
1679
    }    
1680
    
1681
    /// @}
1682

	
1683
    /// \name Using previously constructed node or edge set
1684
    /// @{
1685

	
1686
    /// \brief Use previously constructed node set
1687
    ///
1688
    /// Use previously constructed node set, and specify the node
1689
    /// label map.
1690
    template <typename Map>
1691
    GraphReader& useNodes(const Map& map) {
1692
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1693
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1694
      _use_nodes = true;
1695
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1696
      for (NodeIt n(_graph); n != INVALID; ++n) {
1697
	_node_index.insert(std::make_pair(converter(map[n]), n));
1698
      }
1699
      return *this;
1700
    }
1701

	
1702
    /// \brief Use previously constructed node set
1703
    ///
1704
    /// Use previously constructed node set, and specify the node
1705
    /// label map and a functor which converts the label map values to
1706
    /// std::string.
1707
    template <typename Map, typename Converter>
1708
    GraphReader& useNodes(const Map& map, 
1709
			    const Converter& converter = Converter()) {
1710
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1711
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1712
      _use_nodes = true;
1713
      for (NodeIt n(_graph); n != INVALID; ++n) {
1714
	_node_index.insert(std::make_pair(converter(map[n]), n));
1715
      }
1716
      return *this;
1717
    }
1718

	
1719
    /// \brief Use previously constructed edge set
1720
    ///
1721
    /// Use previously constructed edge set, and specify the edge
1722
    /// label map.
1723
    template <typename Map>
1724
    GraphReader& useEdges(const Map& map) {
1725
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1726
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1727
      _use_edges = true;
1728
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1729
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1730
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1731
      }
1732
      return *this;
1733
    }
1734

	
1735
    /// \brief Use previously constructed edge set
1736
    ///
1737
    /// Use previously constructed edge set, and specify the edge
1738
    /// label map and a functor which converts the label map values to
1739
    /// std::string.
1740
    template <typename Map, typename Converter>
1741
    GraphReader& useEdges(const Map& map, 
1742
			    const Converter& converter = Converter()) {
1743
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1744
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
1745
      _use_edges = true;
1746
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1747
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1748
      }
1749
      return *this;
1750
    }
1751

	
1752
    /// \brief Skips the reading of node section
1753
    ///
1754
    /// Omit the reading of the node section. This implies that each node
1755
    /// map reading rule will be abanoned, and the nodes of the graph
1756
    /// will not be constructed, which usually cause that the edge set
1757
    /// could not be read due to lack of node name
1758
    /// resolving. Therefore, the \c skipEdges() should be used too, or
1759
    /// the useNodes() member function should be used to specify the
1760
    /// label of the nodes.
1761
    GraphReader& skipNodes() {
1762
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 
1763
      _skip_nodes = true;
1764
      return *this;
1765
    }
1766

	
1767
    /// \brief Skips the reading of edge section
1768
    ///
1769
    /// Omit the reading of the edge section. This implies that each edge
1770
    /// map reading rule will be abanoned, and the edges of the graph
1771
    /// will not be constructed.
1772
    GraphReader& skipEdges() {
1773
      LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 
1774
      _skip_edges = true;
1775
      return *this;
1776
    }
1777

	
1778
    /// @}
1779

	
1780
  private:
1781

	
1782
    bool readLine() {
1783
      std::string str;
1784
      while(++line_num, std::getline(*_is, str)) {
1785
	line.clear(); line.str(str);
1786
	char c;
1787
	if (line >> std::ws >> c && c != '#') {
1788
	  line.putback(c);
1789
	  return true;
1790
	}
1791
      }
1792
      return false;
1793
    }
1794

	
1795
    bool readSuccess() {
1796
      return static_cast<bool>(*_is);
1797
    }
1798
    
1799
    void skipSection() {
1800
      char c;
1801
      while (readSuccess() && line >> c && c != '@') {
1802
	readLine();
1803
      }
1804
      line.putback(c);
1805
    }
1806

	
1807
    void readNodes() {
1808

	
1809
      std::vector<int> map_index(_node_maps.size());
1810
      int map_num, label_index;
1811

	
1812
      char c;
1813
      if (!readLine() || !(line >> c) || c == '@') {
1814
	if (readSuccess() && line) line.putback(c);
1815
	if (!_node_maps.empty()) 
1816
	  throw DataFormatError("Cannot find map names");
1817
	return;
1818
      }
1819
      line.putback(c);
1820
      
1821
      {
1822
	std::map<std::string, int> maps;
1823
	
1824
	std::string map;
1825
	int index = 0;
1826
	while (_reader_bits::readToken(line, map)) {
1827
	  if (maps.find(map) != maps.end()) {
1828
	    std::ostringstream msg;
1829
	    msg << "Multiple occurence of node map: " << map;
1830
	    throw DataFormatError(msg.str().c_str());
1831
	  }
1832
	  maps.insert(std::make_pair(map, index));
1833
	  ++index;
1834
	}
1835
	
1836
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1837
	  std::map<std::string, int>::iterator jt = 
1838
	    maps.find(_node_maps[i].first);
1839
	  if (jt == maps.end()) {
1840
	    std::ostringstream msg;
1841
	    msg << "Map not found in file: " << _node_maps[i].first;
1842
	    throw DataFormatError(msg.str().c_str());
1843
	  }
1844
	  map_index[i] = jt->second;
1845
	}
1846

	
1847
	{
1848
	  std::map<std::string, int>::iterator jt = maps.find("label");
1849
	  if (jt != maps.end()) {
1850
	    label_index = jt->second;
1851
	  } else {
1852
	    label_index = -1;
1853
	  }
1854
	}
1855
	map_num = maps.size();
1856
      }
1857

	
1858
      while (readLine() && line >> c && c != '@') {
1859
	line.putback(c);
1860

	
1861
	std::vector<std::string> tokens(map_num);
1862
	for (int i = 0; i < map_num; ++i) {
1863
	  if (!_reader_bits::readToken(line, tokens[i])) {
1864
	    std::ostringstream msg;
1865
	    msg << "Column not found (" << i + 1 << ")";
1866
	    throw DataFormatError(msg.str().c_str());
1867
	  }
1868
	}
1869
	if (line >> std::ws >> c)
1870
	  throw DataFormatError("Extra character on the end of line");
1871
	
1872
	Node n;
1873
	if (!_use_nodes) {
1874
	  n = _graph.addNode();
1875
	  if (label_index != -1) 
1876
	    _node_index.insert(std::make_pair(tokens[label_index], n));
1877
	} else {
1878
	  if (label_index == -1) 
1879
	    throw DataFormatError("Label map not found in file");
1880
	  typename std::map<std::string, Node>::iterator it =
1881
	    _node_index.find(tokens[label_index]);
1882
	  if (it == _node_index.end()) {
1883
	    std::ostringstream msg;
1884
	    msg << "Node with label not found: " << tokens[label_index];
1885
	    throw DataFormatError(msg.str().c_str());	    
1886
	  }
1887
	  n = it->second;
1888
	}
1889

	
1890
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1891
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
1892
	}
1893

	
1894
      }
1895
      if (readSuccess()) {
1896
	line.putback(c);
1897
      }
1898
    }
1899

	
1900
    void readEdges() {
1901

	
1902
      std::vector<int> map_index(_edge_maps.size());
1903
      int map_num, label_index;
1904

	
1905
      char c;
1906
      if (!readLine() || !(line >> c) || c == '@') {
1907
	if (readSuccess() && line) line.putback(c);
1908
	if (!_edge_maps.empty()) 
1909
	  throw DataFormatError("Cannot find map names");
1910
	return;
1911
      }
1912
      line.putback(c);
1913
      
1914
      {
1915
	std::map<std::string, int> maps;
1916
	
1917
	std::string map;
1918
	int index = 0;
1919
	while (_reader_bits::readToken(line, map)) {
1920
	  if (maps.find(map) != maps.end()) {
1921
	    std::ostringstream msg;
1922
	    msg << "Multiple occurence of edge map: " << map;
1923
	    throw DataFormatError(msg.str().c_str());
1924
	  }
1925
	  maps.insert(std::make_pair(map, index));
1926
	  ++index;
1927
	}
1928
	
1929
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1930
	  std::map<std::string, int>::iterator jt = 
1931
	    maps.find(_edge_maps[i].first);
1932
	  if (jt == maps.end()) {
1933
	    std::ostringstream msg;
1934
	    msg << "Map not found in file: " << _edge_maps[i].first;
1935
	    throw DataFormatError(msg.str().c_str());
1936
	  }
1937
	  map_index[i] = jt->second;
1938
	}
1939

	
1940
	{
1941
	  std::map<std::string, int>::iterator jt = maps.find("label");
1942
	  if (jt != maps.end()) {
1943
	    label_index = jt->second;
1944
	  } else {
1945
	    label_index = -1;
1946
	  }
1947
	}
1948
	map_num = maps.size();
1949
      }
1950

	
1951
      while (readLine() && line >> c && c != '@') {
1952
	line.putback(c);
1953

	
1954
	std::string source_token;
1955
	std::string target_token;
1956

	
1957
	if (!_reader_bits::readToken(line, source_token))
1958
	  throw DataFormatError("Node u not found");
1959

	
1960
	if (!_reader_bits::readToken(line, target_token))
1961
	  throw DataFormatError("Node v not found");
1962
	
1963
	std::vector<std::string> tokens(map_num);
1964
	for (int i = 0; i < map_num; ++i) {
1965
	  if (!_reader_bits::readToken(line, tokens[i])) {
1966
	    std::ostringstream msg;
1967
	    msg << "Column not found (" << i + 1 << ")";
1968
	    throw DataFormatError(msg.str().c_str());
1969
	  }
1970
	}
1971
	if (line >> std::ws >> c)
1972
	  throw DataFormatError("Extra character on the end of line");
1973
	
1974
	Edge e;
1975
	if (!_use_edges) {
1976

	
1977
          typename NodeIndex::iterator it;
1978
 
1979
          it = _node_index.find(source_token);
1980
          if (it == _node_index.end()) {
1981
            std::ostringstream msg;
1982
            msg << "Item not found: " << source_token;
1983
            throw DataFormatError(msg.str().c_str());
1984
          }
1985
          Node source = it->second;
1986

	
1987
          it = _node_index.find(target_token);
1988
          if (it == _node_index.end()) {       
1989
            std::ostringstream msg;            
1990
            msg << "Item not found: " << target_token;
1991
            throw DataFormatError(msg.str().c_str());
1992
          }                                          
1993
          Node target = it->second;                            
1994

	
1995
	  e = _graph.addEdge(source, target);
1996
	  if (label_index != -1) 
1997
	    _edge_index.insert(std::make_pair(tokens[label_index], e));
1998
	} else {
1999
	  if (label_index == -1) 
2000
	    throw DataFormatError("Label map not found in file");
2001
	  typename std::map<std::string, Edge>::iterator it =
2002
	    _edge_index.find(tokens[label_index]);
2003
	  if (it == _edge_index.end()) {
2004
	    std::ostringstream msg;
2005
	    msg << "Edge with label not found: " << tokens[label_index];
2006
	    throw DataFormatError(msg.str().c_str());	    
2007
	  }
2008
	  e = it->second;
2009
	}
2010

	
2011
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
2012
	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
2013
	}
2014

	
2015
      }
2016
      if (readSuccess()) {
2017
	line.putback(c);
2018
      }
2019
    }
2020

	
2021
    void readAttributes() {
2022

	
2023
      std::set<std::string> read_attr;
2024

	
2025
      char c;
2026
      while (readLine() && line >> c && c != '@') {
2027
	line.putback(c);
2028
	
2029
	std::string attr, token;
2030
	if (!_reader_bits::readToken(line, attr))
2031
	  throw DataFormatError("Attribute name not found");
2032
	if (!_reader_bits::readToken(line, token))
2033
	  throw DataFormatError("Attribute value not found");
2034
	if (line >> c)
2035
	  throw DataFormatError("Extra character on the end of line");	  
2036

	
2037
	{
2038
	  std::set<std::string>::iterator it = read_attr.find(attr);
2039
	  if (it != read_attr.end()) {
2040
	    std::ostringstream msg;
2041
	    msg << "Multiple occurence of attribute " << attr;
2042
	    throw DataFormatError(msg.str().c_str());
2043
	  }
2044
	  read_attr.insert(attr);
2045
	}
2046
	
2047
	{
2048
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
2049
	  while (it != _attributes.end() && it->first == attr) {
2050
	    it->second->set(token);
2051
	    ++it;
2052
	  }
2053
	}
2054

	
2055
      }
2056
      if (readSuccess()) {
2057
	line.putback(c);
2058
      }
2059
      for (typename Attributes::iterator it = _attributes.begin();
2060
	   it != _attributes.end(); ++it) {
2061
	if (read_attr.find(it->first) == read_attr.end()) {
2062
	  std::ostringstream msg;
2063
	  msg << "Attribute not found in file: " << it->first;
2064
	  throw DataFormatError(msg.str().c_str());
2065
	}	
2066
      }
2067
    }
2068

	
2069
  public:
2070

	
2071
    /// \name Execution of the reader    
2072
    /// @{
2073

	
2074
    /// \brief Start the batch processing
2075
    ///
2076
    /// This function starts the batch processing
2077
    void run() {
2078
      
2079
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2080
      
2081
      bool nodes_done = _skip_nodes;
2082
      bool edges_done = _skip_edges;
2083
      bool attributes_done = false;
2084
      std::set<std::string> extra_sections;
2085

	
2086
      line_num = 0;      
2087
      readLine();
2088
      skipSection();
2089

	
2090
      while (readSuccess()) {
2091
	try {
2092
	  char c;
2093
	  std::string section, caption;
2094
	  line >> c;
2095
	  _reader_bits::readToken(line, section);
2096
	  _reader_bits::readToken(line, caption);
2097

	
2098
	  if (line >> c) 
2099
	    throw DataFormatError("Extra character on the end of line");
2100

	
2101
	  if (section == "nodes" && !nodes_done) {
2102
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
2103
	      readNodes();
2104
	      nodes_done = true;
2105
	    }
2106
	  } else if ((section == "edges" || section == "arcs") && 
2107
		     !edges_done) {
2108
	    if (_edges_caption.empty() || _edges_caption == caption) {
2109
	      readEdges();
2110
	      edges_done = true;
2111
	    }
2112
	  } else if (section == "attributes" && !attributes_done) {
2113
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
2114
	      readAttributes();
2115
	      attributes_done = true;
2116
	    }
2117
	  } else {
2118
	    if (extra_sections.find(section) != extra_sections.end()) {
2119
	      std::ostringstream msg;
2120
	      msg << "Multiple occurence of section " << section;
2121
	      throw DataFormatError(msg.str().c_str());
2122
	    }
2123
	    Sections::iterator it = _sections.find(section);
2124
	    if (it != _sections.end()) {
2125
	      extra_sections.insert(section);
2126
	      it->second->process(*_is, line_num);
2127
	    }
2128
	    readLine();
2129
	    skipSection();
2130
	  }
2131
	} catch (DataFormatError& error) {
2132
	  error.line(line_num);
2133
	  throw;
2134
	}	
2135
      }
2136

	
2137
      if (!nodes_done) {
2138
	throw DataFormatError("Section @nodes not found");
2139
      }
2140

	
2141
      if (!edges_done) {
2142
	throw DataFormatError("Section @edges not found");
2143
      }
2144

	
2145
      if (!attributes_done && !_attributes.empty()) {
2146
	throw DataFormatError("Section @attributes not found");
2147
      }
2148

	
2149
    }
2150

	
2151
    /// @}
2152
    
2153
  };
2154

	
2155
  /// \relates GraphReader
2156
  template <typename Graph>
2157
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2158
    GraphReader<Graph> tmp(is, graph);
2159
    return tmp;
2160
  }
2161

	
2162
  /// \relates GraphReader
2163
  template <typename Graph>
2164
  GraphReader<Graph> graphReader(const std::string& fn, 
2165
				       Graph& graph) {
2166
    GraphReader<Graph> tmp(fn, graph);
2167
    return tmp;
2168
  }
2169

	
2170
  /// \relates GraphReader
2171
  template <typename Graph>
2172
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2173
    GraphReader<Graph> tmp(fn, graph);
2221
  /// \relates SectionReader
2222
  inline SectionReader sectionReader(const char* fn) {
2223
    SectionReader tmp(fn);
2174 2224
    return tmp;
2175 2225
  }
2176 2226

	
0 comments (0 inline)