gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 1 0
merge default
1 file changed with 4 insertions and 8 deletions:
↑ Collapse diff ↑
Show white space 384 line context
... ...
@@ -950,429 +950,427 @@
950 950
	}
951 951

	
952 952
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
953 953
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
954 954
	}
955 955

	
956 956
      }
957 957
      if (readSuccess()) {
958 958
	line.putback(c);
959 959
      }
960 960
    }
961 961

	
962 962
    void readArcs() {
963 963

	
964 964
      std::vector<int> map_index(_arc_maps.size());
965 965
      int map_num, label_index;
966 966

	
967 967
      if (!readLine()) 
968 968
	throw DataFormatError("Cannot find map captions");
969 969
      
970 970
      {
971 971
	std::map<std::string, int> maps;
972 972
	
973 973
	std::string map;
974 974
	int index = 0;
975 975
	while (_reader_bits::readToken(line, map)) {
976 976
	  if (maps.find(map) != maps.end()) {
977 977
	    std::ostringstream msg;
978 978
	    msg << "Multiple occurence of arc map: " << map;
979 979
	    throw DataFormatError(msg.str().c_str());
980 980
	  }
981 981
	  maps.insert(std::make_pair(map, index));
982 982
	  ++index;
983 983
	}
984 984
	
985 985
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
986 986
	  std::map<std::string, int>::iterator jt = 
987 987
	    maps.find(_arc_maps[i].first);
988 988
	  if (jt == maps.end()) {
989 989
	    std::ostringstream msg;
990 990
	    msg << "Map not found in file: " << _arc_maps[i].first;
991 991
	    throw DataFormatError(msg.str().c_str());
992 992
	  }
993 993
	  map_index[i] = jt->second;
994 994
	}
995 995

	
996 996
	{
997 997
	  std::map<std::string, int>::iterator jt = maps.find("label");
998 998
	  if (jt == maps.end())
999 999
	    throw DataFormatError("Label map not found in file");
1000 1000
	  label_index = jt->second;
1001 1001
	}
1002 1002
	map_num = maps.size();
1003 1003
      }
1004 1004

	
1005 1005
      char c;
1006 1006
      while (readLine() && line >> c && c != '@') {
1007 1007
	line.putback(c);
1008 1008

	
1009 1009
	std::string source_token;
1010 1010
	std::string target_token;
1011 1011

	
1012 1012
	if (!_reader_bits::readToken(line, source_token))
1013 1013
	  throw DataFormatError("Source not found");
1014 1014

	
1015 1015
	if (!_reader_bits::readToken(line, target_token))
1016 1016
	  throw DataFormatError("Source not found");
1017 1017
	
1018 1018
	std::vector<std::string> tokens(map_num);
1019 1019
	for (int i = 0; i < map_num; ++i) {
1020 1020
	  if (!_reader_bits::readToken(line, tokens[i])) {
1021 1021
	    std::ostringstream msg;
1022 1022
	    msg << "Column not found (" << i + 1 << ")";
1023 1023
	    throw DataFormatError(msg.str().c_str());
1024 1024
	  }
1025 1025
	}
1026 1026
	if (line >> std::ws >> c)
1027 1027
	  throw DataFormatError("Extra character on the end of line");
1028 1028
	
1029 1029
	Arc a;
1030 1030
	if (!_use_arcs) {
1031 1031

	
1032 1032
          typename NodeIndex::iterator it;
1033 1033
 
1034 1034
          it = _node_index.find(source_token);
1035 1035
          if (it == _node_index.end()) {
1036 1036
            std::ostringstream msg;
1037 1037
            msg << "Item not found: " << source_token;
1038 1038
            throw DataFormatError(msg.str().c_str());
1039 1039
          }
1040 1040
          Node source = it->second;
1041 1041

	
1042 1042
          it = _node_index.find(target_token);
1043 1043
          if (it == _node_index.end()) {       
1044 1044
            std::ostringstream msg;            
1045 1045
            msg << "Item not found: " << target_token;
1046 1046
            throw DataFormatError(msg.str().c_str());
1047 1047
          }                                          
1048 1048
          Node target = it->second;                            
1049 1049

	
1050 1050
	  a = _digraph.addArc(source, target);
1051 1051
	  _arc_index.insert(std::make_pair(tokens[label_index], a));
1052 1052
	} else {
1053 1053
	  typename std::map<std::string, Arc>::iterator it =
1054 1054
	    _arc_index.find(tokens[label_index]);
1055 1055
	  if (it == _arc_index.end()) {
1056 1056
	    std::ostringstream msg;
1057 1057
	    msg << "Arc with label not found: " << tokens[label_index];
1058 1058
	    throw DataFormatError(msg.str().c_str());	    
1059 1059
	  }
1060 1060
	  a = it->second;
1061 1061
	}
1062 1062

	
1063 1063
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1064 1064
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
1065 1065
	}
1066 1066

	
1067 1067
      }
1068 1068
      if (readSuccess()) {
1069 1069
	line.putback(c);
1070 1070
      }
1071 1071
    }
1072 1072

	
1073 1073
    void readAttributes() {
1074 1074

	
1075 1075
      std::set<std::string> read_attr;
1076 1076

	
1077 1077
      char c;
1078 1078
      while (readLine() && line >> c && c != '@') {
1079 1079
	line.putback(c);
1080 1080
	
1081 1081
	std::string attr, token;
1082 1082
	if (!_reader_bits::readToken(line, attr))
1083 1083
	  throw DataFormatError("Attribute name not found");
1084 1084
	if (!_reader_bits::readToken(line, token))
1085 1085
	  throw DataFormatError("Attribute value not found");
1086 1086
	if (line >> c)
1087 1087
	  throw DataFormatError("Extra character on the end of line");	  
1088 1088

	
1089 1089
	{
1090 1090
	  std::set<std::string>::iterator it = read_attr.find(attr);
1091 1091
	  if (it != read_attr.end()) {
1092 1092
	    std::ostringstream msg;
1093 1093
	    msg << "Multiple occurence of attribute " << attr;
1094 1094
	    throw DataFormatError(msg.str().c_str());
1095 1095
	  }
1096 1096
	  read_attr.insert(attr);
1097 1097
	}
1098 1098
	
1099 1099
	{
1100 1100
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1101 1101
	  while (it != _attributes.end() && it->first == attr) {
1102 1102
	    it->second->set(token);
1103 1103
	    ++it;
1104 1104
	  }
1105 1105
	}
1106 1106

	
1107 1107
      }
1108 1108
      if (readSuccess()) {
1109 1109
	line.putback(c);
1110 1110
      }
1111 1111
      for (typename Attributes::iterator it = _attributes.begin();
1112 1112
	   it != _attributes.end(); ++it) {
1113 1113
	if (read_attr.find(it->first) == read_attr.end()) {
1114 1114
	  std::ostringstream msg;
1115 1115
	  msg << "Attribute not found in file: " << it->first;
1116 1116
	  throw DataFormatError(msg.str().c_str());
1117 1117
	}	
1118 1118
      }
1119 1119
    }
1120 1120

	
1121 1121
  public:
1122 1122

	
1123 1123
    /// \name Execution of the reader    
1124 1124
    /// @{
1125 1125

	
1126 1126
    /// \brief Start the batch processing
1127 1127
    ///
1128 1128
    /// This function starts the batch processing
1129 1129
    void run() {
1130 1130
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1131 1131
      if (!*_is) {
1132 1132
	throw DataFormatError("Cannot find file");
1133 1133
      }
1134 1134
      
1135 1135
      bool nodes_done = false;
1136 1136
      bool arcs_done = false;
1137 1137
      bool attributes_done = false;
1138 1138
      std::set<std::string> extra_sections;
1139 1139

	
1140 1140
      line_num = 0;      
1141 1141
      readLine();
1142
      skipSection();
1142 1143

	
1143 1144
      while (readSuccess()) {
1144
	skipSection();
1145 1145
	try {
1146 1146
	  char c;
1147 1147
	  std::string section, caption;
1148 1148
	  line >> c;
1149 1149
	  _reader_bits::readToken(line, section);
1150 1150
	  _reader_bits::readToken(line, caption);
1151 1151

	
1152 1152
	  if (line >> c) 
1153 1153
	    throw DataFormatError("Extra character on the end of line");
1154 1154

	
1155 1155
	  if (section == "nodes" && !nodes_done) {
1156 1156
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1157 1157
	      readNodes();
1158 1158
	      nodes_done = true;
1159 1159
	    }
1160 1160
	  } else if ((section == "arcs" || section == "edges") && 
1161 1161
		     !arcs_done) {
1162 1162
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
1163 1163
	      readArcs();
1164 1164
	      arcs_done = true;
1165 1165
	    }
1166 1166
	  } else if (section == "attributes" && !attributes_done) {
1167 1167
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1168 1168
	      readAttributes();
1169 1169
	      attributes_done = true;
1170 1170
	    }
1171 1171
	  } else {
1172 1172
	    if (extra_sections.find(section) != extra_sections.end()) {
1173 1173
	      std::ostringstream msg;
1174 1174
	      msg << "Multiple occurence of section " << section;
1175 1175
	      throw DataFormatError(msg.str().c_str());
1176 1176
	    }
1177 1177
	    Sections::iterator it = _sections.find(section);
1178 1178
	    if (it != _sections.end()) {
1179 1179
	      extra_sections.insert(section);
1180 1180
	      it->second->process(*_is, line_num);
1181
	      readLine();
1182
	    } else {
1181
	    }
1183 1182
	      readLine();
1184 1183
	      skipSection();
1185 1184
	    }
1186
	  }
1187 1185
	} catch (DataFormatError& error) {
1188 1186
	  error.line(line_num);
1189 1187
	  throw;
1190 1188
	}	
1191 1189
      }
1192 1190

	
1193 1191
      if (!nodes_done) {
1194 1192
	throw DataFormatError("Section @nodes not found");
1195 1193
      }
1196 1194

	
1197 1195
      if (!arcs_done) {
1198 1196
	throw DataFormatError("Section @arcs not found");
1199 1197
      }
1200 1198

	
1201 1199
      if (!attributes_done && !_attributes.empty()) {
1202 1200
	throw DataFormatError("Section @attributes not found");
1203 1201
      }
1204 1202

	
1205 1203
    }
1206 1204

	
1207 1205
    /// @}
1208 1206
    
1209 1207
  };
1210 1208

	
1211 1209
  /// \relates DigraphReader
1212 1210
  template <typename Digraph>
1213 1211
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1214 1212
    DigraphReader<Digraph> tmp(is, digraph);
1215 1213
    return tmp;
1216 1214
  }
1217 1215

	
1218 1216
  /// \relates DigraphReader
1219 1217
  template <typename Digraph>
1220 1218
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1221 1219
				       Digraph& digraph) {
1222 1220
    DigraphReader<Digraph> tmp(fn, digraph);
1223 1221
    return tmp;
1224 1222
  }
1225 1223

	
1226 1224
  /// \relates DigraphReader
1227 1225
  template <typename Digraph>
1228 1226
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1229 1227
    DigraphReader<Digraph> tmp(fn, digraph);
1230 1228
    return tmp;
1231 1229
  }
1232 1230

	
1233 1231
  /// \ingroup lemon_io
1234 1232
  ///  
1235 1233
  /// \brief LGF reader for undirected graphs
1236 1234
  ///
1237 1235
  /// This utility reads an \ref lgf-format "LGF" file.
1238 1236
  template <typename _Graph>
1239 1237
  class GraphReader {
1240 1238
  public:
1241 1239

	
1242 1240
    typedef _Graph Graph;
1243 1241
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1244 1242
    
1245 1243
  private:
1246 1244

	
1247 1245

	
1248 1246
    std::istream* _is;
1249 1247
    bool local_is;
1250 1248

	
1251 1249
    Graph& _graph;
1252 1250

	
1253 1251
    std::string _nodes_caption;
1254 1252
    std::string _edges_caption;
1255 1253
    std::string _attributes_caption;
1256 1254

	
1257 1255
    typedef std::map<std::string, Node> NodeIndex;
1258 1256
    NodeIndex _node_index;
1259 1257
    typedef std::map<std::string, Edge> EdgeIndex;
1260 1258
    EdgeIndex _edge_index;
1261 1259
    
1262 1260
    typedef std::vector<std::pair<std::string, 
1263 1261
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1264 1262
    NodeMaps _node_maps; 
1265 1263

	
1266 1264
    typedef std::vector<std::pair<std::string,
1267 1265
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1268 1266
    EdgeMaps _edge_maps;
1269 1267

	
1270 1268
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1271 1269
      Attributes;
1272 1270
    Attributes _attributes;
1273 1271

	
1274 1272
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1275 1273
    Sections _sections;
1276 1274

	
1277 1275
    bool _use_nodes;
1278 1276
    bool _use_edges;
1279 1277

	
1280 1278
    int line_num;
1281 1279
    std::istringstream line;
1282 1280

	
1283 1281
  public:
1284 1282

	
1285 1283
    /// \brief Constructor
1286 1284
    ///
1287 1285
    /// Construct a undirected graph reader, which reads from the given
1288 1286
    /// input stream.
1289 1287
    GraphReader(std::istream& is, Graph& graph) 
1290 1288
      : _is(&is), local_is(false), _graph(graph),
1291 1289
	_use_nodes(false), _use_edges(false) {}
1292 1290

	
1293 1291
    /// \brief Constructor
1294 1292
    ///
1295 1293
    /// Construct a undirected graph reader, which reads from the given
1296 1294
    /// file.
1297 1295
    GraphReader(const std::string& fn, Graph& graph) 
1298 1296
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1299 1297
    	_use_nodes(false), _use_edges(false) {}
1300 1298
    
1301 1299
    /// \brief Constructor
1302 1300
    ///
1303 1301
    /// Construct a undirected graph reader, which reads from the given
1304 1302
    /// file.
1305 1303
    GraphReader(const char* fn, Graph& graph) 
1306 1304
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1307 1305
    	_use_nodes(false), _use_edges(false) {}
1308 1306

	
1309 1307
    /// \brief Copy constructor
1310 1308
    ///
1311 1309
    /// The copy constructor transfers all data from the other reader,
1312 1310
    /// therefore the copied reader will not be usable more. 
1313 1311
    GraphReader(GraphReader& other) 
1314 1312
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1315 1313
	_use_nodes(other._use_nodes), _use_edges(other._use_edges) {
1316 1314

	
1317 1315
      other._is = 0;
1318 1316
      other.local_is = false;
1319 1317
      
1320 1318
      _node_index.swap(other._node_index);
1321 1319
      _edge_index.swap(other._edge_index);
1322 1320

	
1323 1321
      _node_maps.swap(other._node_maps);
1324 1322
      _edge_maps.swap(other._edge_maps);
1325 1323
      _attributes.swap(other._attributes);
1326 1324

	
1327 1325
      _nodes_caption = other._nodes_caption;
1328 1326
      _edges_caption = other._edges_caption;
1329 1327
      _attributes_caption = other._attributes_caption;
1330 1328

	
1331 1329
      _sections.swap(other._sections);
1332 1330
    }
1333 1331

	
1334 1332
    /// \brief Destructor
1335 1333
    ~GraphReader() {
1336 1334
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1337 1335
	   it != _node_maps.end(); ++it) {
1338 1336
	delete it->second;
1339 1337
      }
1340 1338

	
1341 1339
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1342 1340
	   it != _edge_maps.end(); ++it) {
1343 1341
	delete it->second;
1344 1342
      }
1345 1343

	
1346 1344
      for (typename Attributes::iterator it = _attributes.begin(); 
1347 1345
	   it != _attributes.end(); ++it) {
1348 1346
	delete it->second;
1349 1347
      }
1350 1348

	
1351 1349
      for (typename Sections::iterator it = _sections.begin(); 
1352 1350
	   it != _sections.end(); ++it) {
1353 1351
	delete it->second;
1354 1352
      }
1355 1353

	
1356 1354
      if (local_is) {
1357 1355
	delete _is;
1358 1356
      }
1359 1357

	
1360 1358
    }
1361 1359

	
1362 1360
  private:
1363 1361
    
1364 1362
    GraphReader& operator=(const GraphReader&);
1365 1363

	
1366 1364
  public:
1367 1365

	
1368 1366
    /// \name Reading rules
1369 1367
    /// @{
1370 1368
    
1371 1369
    /// \brief Node map reading rule
1372 1370
    ///
1373 1371
    /// Add a node map reading rule to the reader.
1374 1372
    template <typename Map>
1375 1373
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1376 1374
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1377 1375
      _reader_bits::MapStorageBase<Node>* storage = 
1378 1376
	new _reader_bits::MapStorage<Node, Map>(map);
... ...
@@ -1792,429 +1790,427 @@
1792 1790
	  }
1793 1791
	  n = it->second;
1794 1792
	}
1795 1793

	
1796 1794
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1797 1795
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
1798 1796
	}
1799 1797

	
1800 1798
      }
1801 1799
      if (readSuccess()) {
1802 1800
	line.putback(c);
1803 1801
      }
1804 1802
    }
1805 1803

	
1806 1804
    void readEdges() {
1807 1805

	
1808 1806
      std::vector<int> map_index(_edge_maps.size());
1809 1807
      int map_num, label_index;
1810 1808

	
1811 1809
      if (!readLine()) 
1812 1810
	throw DataFormatError("Cannot find map captions");
1813 1811
      
1814 1812
      {
1815 1813
	std::map<std::string, int> maps;
1816 1814
	
1817 1815
	std::string map;
1818 1816
	int index = 0;
1819 1817
	while (_reader_bits::readToken(line, map)) {
1820 1818
	  if (maps.find(map) != maps.end()) {
1821 1819
	    std::ostringstream msg;
1822 1820
	    msg << "Multiple occurence of edge map: " << map;
1823 1821
	    throw DataFormatError(msg.str().c_str());
1824 1822
	  }
1825 1823
	  maps.insert(std::make_pair(map, index));
1826 1824
	  ++index;
1827 1825
	}
1828 1826
	
1829 1827
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1830 1828
	  std::map<std::string, int>::iterator jt = 
1831 1829
	    maps.find(_edge_maps[i].first);
1832 1830
	  if (jt == maps.end()) {
1833 1831
	    std::ostringstream msg;
1834 1832
	    msg << "Map not found in file: " << _edge_maps[i].first;
1835 1833
	    throw DataFormatError(msg.str().c_str());
1836 1834
	  }
1837 1835
	  map_index[i] = jt->second;
1838 1836
	}
1839 1837

	
1840 1838
	{
1841 1839
	  std::map<std::string, int>::iterator jt = maps.find("label");
1842 1840
	  if (jt == maps.end())
1843 1841
	    throw DataFormatError("Label map not found in file");
1844 1842
	  label_index = jt->second;
1845 1843
	}
1846 1844
	map_num = maps.size();
1847 1845
      }
1848 1846

	
1849 1847
      char c;
1850 1848
      while (readLine() && line >> c && c != '@') {
1851 1849
	line.putback(c);
1852 1850

	
1853 1851
	std::string source_token;
1854 1852
	std::string target_token;
1855 1853

	
1856 1854
	if (!_reader_bits::readToken(line, source_token))
1857 1855
	  throw DataFormatError("Source not found");
1858 1856

	
1859 1857
	if (!_reader_bits::readToken(line, target_token))
1860 1858
	  throw DataFormatError("Source not found");
1861 1859
	
1862 1860
	std::vector<std::string> tokens(map_num);
1863 1861
	for (int i = 0; i < map_num; ++i) {
1864 1862
	  if (!_reader_bits::readToken(line, tokens[i])) {
1865 1863
	    std::ostringstream msg;
1866 1864
	    msg << "Column not found (" << i + 1 << ")";
1867 1865
	    throw DataFormatError(msg.str().c_str());
1868 1866
	  }
1869 1867
	}
1870 1868
	if (line >> std::ws >> c)
1871 1869
	  throw DataFormatError("Extra character on the end of line");
1872 1870
	
1873 1871
	Edge e;
1874 1872
	if (!_use_edges) {
1875 1873

	
1876 1874
          typename NodeIndex::iterator it;
1877 1875
 
1878 1876
          it = _node_index.find(source_token);
1879 1877
          if (it == _node_index.end()) {
1880 1878
            std::ostringstream msg;
1881 1879
            msg << "Item not found: " << source_token;
1882 1880
            throw DataFormatError(msg.str().c_str());
1883 1881
          }
1884 1882
          Node source = it->second;
1885 1883

	
1886 1884
          it = _node_index.find(target_token);
1887 1885
          if (it == _node_index.end()) {       
1888 1886
            std::ostringstream msg;            
1889 1887
            msg << "Item not found: " << target_token;
1890 1888
            throw DataFormatError(msg.str().c_str());
1891 1889
          }                                          
1892 1890
          Node target = it->second;                            
1893 1891

	
1894 1892
	  e = _graph.addEdge(source, target);
1895 1893
	  _edge_index.insert(std::make_pair(tokens[label_index], e));
1896 1894
	} else {
1897 1895
	  typename std::map<std::string, Edge>::iterator it =
1898 1896
	    _edge_index.find(tokens[label_index]);
1899 1897
	  if (it == _edge_index.end()) {
1900 1898
	    std::ostringstream msg;
1901 1899
	    msg << "Edge with label not found: " << tokens[label_index];
1902 1900
	    throw DataFormatError(msg.str().c_str());	    
1903 1901
	  }
1904 1902
	  e = it->second;
1905 1903
	}
1906 1904

	
1907 1905
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1908 1906
	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
1909 1907
	}
1910 1908

	
1911 1909
      }
1912 1910
      if (readSuccess()) {
1913 1911
	line.putback(c);
1914 1912
      }
1915 1913
    }
1916 1914

	
1917 1915
    void readAttributes() {
1918 1916

	
1919 1917
      std::set<std::string> read_attr;
1920 1918

	
1921 1919
      char c;
1922 1920
      while (readLine() && line >> c && c != '@') {
1923 1921
	line.putback(c);
1924 1922
	
1925 1923
	std::string attr, token;
1926 1924
	if (!_reader_bits::readToken(line, attr))
1927 1925
	  throw DataFormatError("Attribute name not found");
1928 1926
	if (!_reader_bits::readToken(line, token))
1929 1927
	  throw DataFormatError("Attribute value not found");
1930 1928
	if (line >> c)
1931 1929
	  throw DataFormatError("Extra character on the end of line");	  
1932 1930

	
1933 1931
	{
1934 1932
	  std::set<std::string>::iterator it = read_attr.find(attr);
1935 1933
	  if (it != read_attr.end()) {
1936 1934
	    std::ostringstream msg;
1937 1935
	    msg << "Multiple occurence of attribute " << attr;
1938 1936
	    throw DataFormatError(msg.str().c_str());
1939 1937
	  }
1940 1938
	  read_attr.insert(attr);
1941 1939
	}
1942 1940
	
1943 1941
	{
1944 1942
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1945 1943
	  while (it != _attributes.end() && it->first == attr) {
1946 1944
	    it->second->set(token);
1947 1945
	    ++it;
1948 1946
	  }
1949 1947
	}
1950 1948

	
1951 1949
      }
1952 1950
      if (readSuccess()) {
1953 1951
	line.putback(c);
1954 1952
      }
1955 1953
      for (typename Attributes::iterator it = _attributes.begin();
1956 1954
	   it != _attributes.end(); ++it) {
1957 1955
	if (read_attr.find(it->first) == read_attr.end()) {
1958 1956
	  std::ostringstream msg;
1959 1957
	  msg << "Attribute not found in file: " << it->first;
1960 1958
	  throw DataFormatError(msg.str().c_str());
1961 1959
	}	
1962 1960
      }
1963 1961
    }
1964 1962

	
1965 1963
  public:
1966 1964

	
1967 1965
    /// \name Execution of the reader    
1968 1966
    /// @{
1969 1967

	
1970 1968
    /// \brief Start the batch processing
1971 1969
    ///
1972 1970
    /// This function starts the batch processing
1973 1971
    void run() {
1974 1972
      
1975 1973
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1976 1974
      
1977 1975
      bool nodes_done = false;
1978 1976
      bool edges_done = false;
1979 1977
      bool attributes_done = false;
1980 1978
      std::set<std::string> extra_sections;
1981 1979

	
1982 1980
      line_num = 0;      
1983 1981
      readLine();
1982
      skipSection();
1984 1983

	
1985 1984
      while (readSuccess()) {
1986
	skipSection();
1987 1985
	try {
1988 1986
	  char c;
1989 1987
	  std::string section, caption;
1990 1988
	  line >> c;
1991 1989
	  _reader_bits::readToken(line, section);
1992 1990
	  _reader_bits::readToken(line, caption);
1993 1991

	
1994 1992
	  if (line >> c) 
1995 1993
	    throw DataFormatError("Extra character on the end of line");
1996 1994

	
1997 1995
	  if (section == "nodes" && !nodes_done) {
1998 1996
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1999 1997
	      readNodes();
2000 1998
	      nodes_done = true;
2001 1999
	    }
2002 2000
	  } else if ((section == "edges" || section == "arcs") && 
2003 2001
		     !edges_done) {
2004 2002
	    if (_edges_caption.empty() || _edges_caption == caption) {
2005 2003
	      readEdges();
2006 2004
	      edges_done = true;
2007 2005
	    }
2008 2006
	  } else if (section == "attributes" && !attributes_done) {
2009 2007
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
2010 2008
	      readAttributes();
2011 2009
	      attributes_done = true;
2012 2010
	    }
2013 2011
	  } else {
2014 2012
	    if (extra_sections.find(section) != extra_sections.end()) {
2015 2013
	      std::ostringstream msg;
2016 2014
	      msg << "Multiple occurence of section " << section;
2017 2015
	      throw DataFormatError(msg.str().c_str());
2018 2016
	    }
2019 2017
	    Sections::iterator it = _sections.find(section);
2020 2018
	    if (it != _sections.end()) {
2021 2019
	      extra_sections.insert(section);
2022 2020
	      it->second->process(*_is, line_num);
2023
	      readLine();
2024
	    } else {
2021
	    }
2025 2022
	      readLine();
2026 2023
	      skipSection();
2027 2024
	    }
2028
	  }
2029 2025
	} catch (DataFormatError& error) {
2030 2026
	  error.line(line_num);
2031 2027
	  throw;
2032 2028
	}	
2033 2029
      }
2034 2030

	
2035 2031
      if (!nodes_done) {
2036 2032
	throw DataFormatError("Section @nodes not found");
2037 2033
      }
2038 2034

	
2039 2035
      if (!edges_done) {
2040 2036
	throw DataFormatError("Section @edges not found");
2041 2037
      }
2042 2038

	
2043 2039
      if (!attributes_done && !_attributes.empty()) {
2044 2040
	throw DataFormatError("Section @attributes not found");
2045 2041
      }
2046 2042

	
2047 2043
    }
2048 2044

	
2049 2045
    /// @}
2050 2046
    
2051 2047
  };
2052 2048

	
2053 2049
  /// \relates GraphReader
2054 2050
  template <typename Graph>
2055 2051
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2056 2052
    GraphReader<Graph> tmp(is, graph);
2057 2053
    return tmp;
2058 2054
  }
2059 2055

	
2060 2056
  /// \relates GraphReader
2061 2057
  template <typename Graph>
2062 2058
  GraphReader<Graph> graphReader(const std::string& fn, 
2063 2059
				       Graph& graph) {
2064 2060
    GraphReader<Graph> tmp(fn, graph);
2065 2061
    return tmp;
2066 2062
  }
2067 2063

	
2068 2064
  /// \relates GraphReader
2069 2065
  template <typename Graph>
2070 2066
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2071 2067
    GraphReader<Graph> tmp(fn, graph);
2072 2068
    return tmp;
2073 2069
  }
2074 2070

	
2075 2071
  /// \ingroup lemon_io
2076 2072
  ///
2077 2073
  /// \brief Reader for the content of the \ref lgf-format "LGF" file 
2078 2074
  ///
2079 2075
  /// This class can be used to read the sections, the map names and
2080 2076
  /// the attributes from a file. Usually, the Lemon programs know
2081 2077
  /// that, which type of graph, which maps and which attributes
2082 2078
  /// should be read from a file, but in general tools (like glemon)
2083 2079
  /// the content of an LGF file should be guessed somehow. This class
2084 2080
  /// reads the graph and stores the appropriate information for
2085 2081
  /// reading the graph.
2086 2082
  ///
2087 2083
  ///\code LgfContent content("graph.lgf"); 
2088 2084
  /// content.run();
2089 2085
  ///
2090 2086
  /// // does it contain any node section and arc section
2091 2087
  /// if (content.nodeSectionNum() == 0 || content.arcSectionNum()) {
2092 2088
  ///   std::cerr << "Failure, cannot find graph" << std::endl;
2093 2089
  ///   return -1;
2094 2090
  /// }
2095 2091
  /// std::cout << "The name of the default node section : " 
2096 2092
  ///           << content.nodeSection(0) << std::endl;
2097 2093
  /// std::cout << "The number of the arc maps : " 
2098 2094
  ///           << content.arcMaps(0).size() << std::endl;
2099 2095
  /// std::cout << "The name of second arc map : " 
2100 2096
  ///           << content.arcMaps(0)[1] << std::endl;
2101 2097
  ///\endcode
2102 2098
  class LgfContent {    
2103 2099
  private:
2104 2100

	
2105 2101
    std::istream* _is;
2106 2102
    bool local_is;
2107 2103

	
2108 2104
    std::vector<std::string> _node_sections;
2109 2105
    std::vector<std::string> _edge_sections;
2110 2106
    std::vector<std::string> _attribute_sections;
2111 2107
    std::vector<std::string> _extra_sections;
2112 2108

	
2113 2109
    std::vector<bool> _arc_sections;
2114 2110

	
2115 2111
    std::vector<std::vector<std::string> > _node_maps;
2116 2112
    std::vector<std::vector<std::string> > _edge_maps;
2117 2113

	
2118 2114
    std::vector<std::vector<std::string> > _attributes;
2119 2115

	
2120 2116

	
2121 2117
    int line_num;
2122 2118
    std::istringstream line;
2123 2119
    
2124 2120
  public:
2125 2121

	
2126 2122
    /// \brief Constructor
2127 2123
    ///
2128 2124
    /// Construct an \e LGF content reader, which reads from the given
2129 2125
    /// input stream.
2130 2126
    LgfContent(std::istream& is) 
2131 2127
      : _is(&is), local_is(false) {}
2132 2128

	
2133 2129
    /// \brief Constructor
2134 2130
    ///
2135 2131
    /// Construct an \e LGF content reader, which reads from the given
2136 2132
    /// file.
2137 2133
    LgfContent(const std::string& fn) 
2138 2134
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2139 2135

	
2140 2136
    /// \brief Constructor
2141 2137
    ///
2142 2138
    /// Construct an \e LGF content reader, which reads from the given
2143 2139
    /// file.
2144 2140
    LgfContent(const char* fn)
2145 2141
      : _is(new std::ifstream(fn)), local_is(true) {}
2146 2142

	
2147 2143
    /// \brief Copy constructor
2148 2144
    ///
2149 2145
    /// The copy constructor transfers all data from the other reader,
2150 2146
    /// therefore the copied reader will not be usable more. 
2151 2147
    LgfContent(LgfContent& other)
2152 2148
      : _is(other._is), local_is(other.local_is) {
2153 2149
      
2154 2150
      other._is = 0;
2155 2151
      other.local_is = false;
2156 2152
      
2157 2153
      _node_sections.swap(other._node_sections);
2158 2154
      _edge_sections.swap(other._edge_sections);
2159 2155
      _attribute_sections.swap(other._attribute_sections);
2160 2156
      _extra_sections.swap(other._extra_sections);
2161 2157

	
2162 2158
      _arc_sections.swap(other._arc_sections);
2163 2159

	
2164 2160
      _node_maps.swap(other._node_maps);
2165 2161
      _edge_maps.swap(other._edge_maps);
2166 2162
      _attributes.swap(other._attributes);
2167 2163
    }
2168 2164
    
2169 2165
    /// \brief Destructor
2170 2166
    ~LgfContent() {
2171 2167
      if (local_is) delete _is;
2172 2168
    }
2173 2169

	
2174 2170

	
2175 2171
    /// \name Node sections
2176 2172
    /// @{
2177 2173

	
2178 2174
    /// \brief Gives back the number of node sections in the file.
2179 2175
    ///
2180 2176
    /// Gives back the number of node sections in the file.
2181 2177
    int nodeSectionNum() const {
2182 2178
      return _node_sections.size();
2183 2179
    }
2184 2180

	
2185 2181
    /// \brief Returns the section name at the given position. 
2186 2182
    ///
2187 2183
    /// Returns the section name at the given position. 
2188 2184
    const std::string& nodeSection(int i) const {
2189 2185
      return _node_sections[i];
2190 2186
    }
2191 2187

	
2192 2188
    /// \brief Gives back the node maps for the given section.
2193 2189
    ///
2194 2190
    /// Gives back the node maps for the given section.
2195 2191
    const std::vector<std::string>& nodeMaps(int i) const {
2196 2192
      return _node_maps[i];
2197 2193
    }
2198 2194

	
2199 2195
    /// @}
2200 2196

	
2201 2197
    /// \name Arc sections 
2202 2198
    /// @{
2203 2199

	
2204 2200
    /// \brief Gives back the number of arc sections in the file.
2205 2201
    ///
2206 2202
    /// Gives back the number of arc sections in the file.
2207 2203
    /// \note It is synonim of \c edgeSectionNum().
2208 2204
    int arcSectionNum() const {
2209 2205
      return _edge_sections.size();
2210 2206
    }
2211 2207

	
2212 2208
    /// \brief Returns the section name at the given position. 
2213 2209
    ///
2214 2210
    /// Returns the section name at the given position. 
2215 2211
    /// \note It is synonim of \c edgeSection().
2216 2212
    const std::string& arcSection(int i) const {
2217 2213
      return _edge_sections[i];
2218 2214
    }
2219 2215

	
2220 2216
    /// \brief Gives back the arc maps for the given section.
0 comments (0 inline)