lemon/lgf_reader.h
changeset 165 b4c336c27a03
parent 163 c82fd9568d75
child 172 c94a80f38d7f
child 173 b026e9779b28
equal deleted inserted replaced
6:20430796ad79 7:2dbf9764175b
    98       virtual void set(const Item& item ,const std::string& value) {
    98       virtual void set(const Item& item ,const std::string& value) {
    99 	_map.set(item, _converter(value));
    99 	_map.set(item, _converter(value));
   100       }
   100       }
   101     };
   101     };
   102 
   102 
       
   103     template <typename _Graph, bool _dir, typename _Map, 
       
   104 	      typename _Converter = DefaultConverter<typename _Map::Value> >
       
   105     class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
       
   106     public:
       
   107       typedef _Map Map;
       
   108       typedef _Converter Converter;
       
   109       typedef _Graph Graph;
       
   110       typedef typename Graph::Edge Item;
       
   111       static const bool dir = _dir;
       
   112       
       
   113     private:
       
   114       const Graph& _graph;
       
   115       Map& _map;
       
   116       Converter _converter;
       
   117 
       
   118     public:
       
   119       GraphArcMapStorage(const Graph& graph, Map& map, 
       
   120 			 const Converter& converter = Converter()) 
       
   121 	: _graph(graph), _map(map), _converter(converter) {}
       
   122       virtual ~GraphArcMapStorage() {}
       
   123 
       
   124       virtual void set(const Item& item ,const std::string& value) {
       
   125 	_map.set(_graph.direct(item, dir), _converter(value));
       
   126       }
       
   127     };
       
   128 
   103     class ValueStorageBase {
   129     class ValueStorageBase {
   104     public:
   130     public:
   105       ValueStorageBase() {}
   131       ValueStorageBase() {}
   106       virtual ~ValueStorageBase() {}
   132       virtual ~ValueStorageBase() {}
   107 
   133 
   141           std::ostringstream msg;
   167           std::ostringstream msg;
   142           msg << "Item not found: " << str;
   168           msg << "Item not found: " << str;
   143           throw DataFormatError(msg.str().c_str());
   169           throw DataFormatError(msg.str().c_str());
   144         }
   170         }
   145         return it->second;
   171         return it->second;
       
   172       }
       
   173     };
       
   174 
       
   175     template <typename Graph>
       
   176     struct GraphArcLookUpConverter {
       
   177       const Graph& _graph;
       
   178       const std::map<std::string, typename Graph::Edge>& _map;
       
   179       
       
   180       GraphArcLookUpConverter(const Graph& graph, 
       
   181 			      const std::map<std::string,
       
   182 			                     typename Graph::Edge>& map) 
       
   183 	: _graph(graph), _map(map) {}
       
   184       
       
   185       typename Graph::Arc operator()(const std::string& str) {
       
   186 	if (str.empty() || (str[0] != '+' && str[0] != '-')) {
       
   187 	  throw DataFormatError("Item must start with '+' or '-'");
       
   188 	}
       
   189 	typename std::map<std::string, typename Graph::Edge>
       
   190 	  ::const_iterator it = _map.find(str.substr(1));
       
   191 	if (it == _map.end()) {
       
   192 	  throw DataFormatError("Item not found");
       
   193 	}
       
   194 	return _graph.direct(it->second, str[0] == '+');
   146       }
   195       }
   147     };
   196     };
   148 
   197 
   149     bool isWhiteSpace(char c) {
   198     bool isWhiteSpace(char c) {
   150       return c == ' ' || c == '\t' || c == '\v' || 
   199       return c == ' ' || c == '\t' || c == '\v' || 
  1178   template <typename Digraph>
  1227   template <typename Digraph>
  1179   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
  1228   DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
  1180     DigraphReader<Digraph> tmp(fn, digraph);
  1229     DigraphReader<Digraph> tmp(fn, digraph);
  1181     return tmp;
  1230     return tmp;
  1182   }
  1231   }
       
  1232 
       
  1233   /// \ingroup lemon_io
       
  1234   ///  
       
  1235   /// \brief LGF reader for undirected graphs
       
  1236   ///
       
  1237   /// This utility reads an \ref lgf-format "LGF" file.
       
  1238   template <typename _Graph>
       
  1239   class GraphReader {
       
  1240   public:
       
  1241 
       
  1242     typedef _Graph Graph;
       
  1243     TEMPLATE_GRAPH_TYPEDEFS(Graph);
       
  1244     
       
  1245   private:
       
  1246 
       
  1247 
       
  1248     std::istream* _is;
       
  1249     bool local_is;
       
  1250 
       
  1251     Graph& _graph;
       
  1252 
       
  1253     std::string _nodes_caption;
       
  1254     std::string _edges_caption;
       
  1255     std::string _attributes_caption;
       
  1256 
       
  1257     typedef std::map<std::string, Node> NodeIndex;
       
  1258     NodeIndex _node_index;
       
  1259     typedef std::map<std::string, Edge> EdgeIndex;
       
  1260     EdgeIndex _edge_index;
       
  1261     
       
  1262     typedef std::vector<std::pair<std::string, 
       
  1263       _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
       
  1264     NodeMaps _node_maps; 
       
  1265 
       
  1266     typedef std::vector<std::pair<std::string,
       
  1267       _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
       
  1268     EdgeMaps _edge_maps;
       
  1269 
       
  1270     typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
       
  1271       Attributes;
       
  1272     Attributes _attributes;
       
  1273 
       
  1274     typedef std::map<std::string, _reader_bits::Section*> Sections;
       
  1275     Sections _sections;
       
  1276 
       
  1277     bool _use_nodes;
       
  1278     bool _use_edges;
       
  1279 
       
  1280     int line_num;
       
  1281     std::istringstream line;
       
  1282 
       
  1283   public:
       
  1284 
       
  1285     /// \brief Constructor
       
  1286     ///
       
  1287     /// Construct a undirected graph reader, which reads from the given
       
  1288     /// input stream.
       
  1289     GraphReader(std::istream& is, Graph& graph) 
       
  1290       : _is(&is), local_is(false), _graph(graph),
       
  1291 	_use_nodes(false), _use_edges(false) {}
       
  1292 
       
  1293     /// \brief Constructor
       
  1294     ///
       
  1295     /// Construct a undirected graph reader, which reads from the given
       
  1296     /// file.
       
  1297     GraphReader(const std::string& fn, Graph& graph) 
       
  1298       : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
       
  1299     	_use_nodes(false), _use_edges(false) {}
       
  1300     
       
  1301     /// \brief Constructor
       
  1302     ///
       
  1303     /// Construct a undirected graph reader, which reads from the given
       
  1304     /// file.
       
  1305     GraphReader(const char* fn, Graph& graph) 
       
  1306       : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
       
  1307     	_use_nodes(false), _use_edges(false) {}
       
  1308 
       
  1309     /// \brief Copy constructor
       
  1310     ///
       
  1311     /// The copy constructor transfers all data from the other reader,
       
  1312     /// therefore the copied reader will not be usable more. 
       
  1313     GraphReader(GraphReader& other) 
       
  1314       : _is(other._is), local_is(other.local_is), _graph(other._graph),
       
  1315 	_use_nodes(other._use_nodes), _use_edges(other._use_edges) {
       
  1316 
       
  1317       other._is = 0;
       
  1318       other.local_is = false;
       
  1319       
       
  1320       _node_index.swap(other._node_index);
       
  1321       _edge_index.swap(other._edge_index);
       
  1322 
       
  1323       _node_maps.swap(other._node_maps);
       
  1324       _edge_maps.swap(other._edge_maps);
       
  1325       _attributes.swap(other._attributes);
       
  1326 
       
  1327       _nodes_caption = other._nodes_caption;
       
  1328       _edges_caption = other._edges_caption;
       
  1329       _attributes_caption = other._attributes_caption;
       
  1330 
       
  1331       _sections.swap(other._sections);
       
  1332     }
       
  1333 
       
  1334     /// \brief Destructor
       
  1335     ~GraphReader() {
       
  1336       for (typename NodeMaps::iterator it = _node_maps.begin(); 
       
  1337 	   it != _node_maps.end(); ++it) {
       
  1338 	delete it->second;
       
  1339       }
       
  1340 
       
  1341       for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
       
  1342 	   it != _edge_maps.end(); ++it) {
       
  1343 	delete it->second;
       
  1344       }
       
  1345 
       
  1346       for (typename Attributes::iterator it = _attributes.begin(); 
       
  1347 	   it != _attributes.end(); ++it) {
       
  1348 	delete it->second;
       
  1349       }
       
  1350 
       
  1351       for (typename Sections::iterator it = _sections.begin(); 
       
  1352 	   it != _sections.end(); ++it) {
       
  1353 	delete it->second;
       
  1354       }
       
  1355 
       
  1356       if (local_is) {
       
  1357 	delete _is;
       
  1358       }
       
  1359 
       
  1360     }
       
  1361 
       
  1362   private:
       
  1363     
       
  1364     GraphReader& operator=(const GraphReader&);
       
  1365 
       
  1366   public:
       
  1367 
       
  1368     /// \name Reading rules
       
  1369     /// @{
       
  1370     
       
  1371     /// \brief Node map reading rule
       
  1372     ///
       
  1373     /// Add a node map reading rule to the reader.
       
  1374     template <typename Map>
       
  1375     GraphReader& nodeMap(const std::string& caption, Map& map) {
       
  1376       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
       
  1377       _reader_bits::MapStorageBase<Node>* storage = 
       
  1378 	new _reader_bits::MapStorage<Node, Map>(map);
       
  1379       _node_maps.push_back(std::make_pair(caption, storage));
       
  1380       return *this;
       
  1381     }
       
  1382 
       
  1383     /// \brief Node map reading rule
       
  1384     ///
       
  1385     /// Add a node map reading rule with specialized converter to the
       
  1386     /// reader.
       
  1387     template <typename Map, typename Converter>
       
  1388     GraphReader& nodeMap(const std::string& caption, Map& map, 
       
  1389 			   const Converter& converter = Converter()) {
       
  1390       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
       
  1391       _reader_bits::MapStorageBase<Node>* storage = 
       
  1392 	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
       
  1393       _node_maps.push_back(std::make_pair(caption, storage));
       
  1394       return *this;
       
  1395     }
       
  1396 
       
  1397     /// \brief Edge map reading rule
       
  1398     ///
       
  1399     /// Add an edge map reading rule to the reader.
       
  1400     template <typename Map>
       
  1401     GraphReader& edgeMap(const std::string& caption, Map& map) {
       
  1402       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
       
  1403       _reader_bits::MapStorageBase<Edge>* storage = 
       
  1404 	new _reader_bits::MapStorage<Edge, Map>(map);
       
  1405       _edge_maps.push_back(std::make_pair(caption, storage));
       
  1406       return *this;
       
  1407     }
       
  1408 
       
  1409     /// \brief Edge map reading rule
       
  1410     ///
       
  1411     /// Add an edge map reading rule with specialized converter to the
       
  1412     /// reader.
       
  1413     template <typename Map, typename Converter>
       
  1414     GraphReader& edgeMap(const std::string& caption, Map& map, 
       
  1415 			  const Converter& converter = Converter()) {
       
  1416       checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
       
  1417       _reader_bits::MapStorageBase<Edge>* storage = 
       
  1418 	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
       
  1419       _edge_maps.push_back(std::make_pair(caption, storage));
       
  1420       return *this;
       
  1421     }
       
  1422 
       
  1423     /// \brief Arc map reading rule
       
  1424     ///
       
  1425     /// Add an arc map reading rule to the reader.
       
  1426     template <typename Map>
       
  1427     GraphReader& arcMap(const std::string& caption, Map& map) {
       
  1428       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
       
  1429       _reader_bits::MapStorageBase<Edge>* forward_storage = 
       
  1430 	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
       
  1431       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       
  1432       _reader_bits::MapStorageBase<Edge>* backward_storage = 
       
  1433 	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
       
  1434       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
       
  1435       return *this;
       
  1436     }
       
  1437 
       
  1438     /// \brief Arc map reading rule
       
  1439     ///
       
  1440     /// Add an arc map reading rule with specialized converter to the
       
  1441     /// reader.
       
  1442     template <typename Map, typename Converter>
       
  1443     GraphReader& arcMap(const std::string& caption, Map& map, 
       
  1444 			  const Converter& converter = Converter()) {
       
  1445       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
       
  1446       _reader_bits::MapStorageBase<Edge>* forward_storage = 
       
  1447 	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
       
  1448 	(_graph, map, converter);
       
  1449       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       
  1450       _reader_bits::MapStorageBase<Edge>* backward_storage = 
       
  1451 	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
       
  1452 	(_graph, map, converter);
       
  1453       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
       
  1454       return *this;
       
  1455     }
       
  1456 
       
  1457     /// \brief Attribute reading rule
       
  1458     ///
       
  1459     /// Add an attribute reading rule to the reader.
       
  1460     template <typename Value>
       
  1461     GraphReader& attribute(const std::string& caption, Value& value) {
       
  1462       _reader_bits::ValueStorageBase* storage = 
       
  1463 	new _reader_bits::ValueStorage<Value>(value);
       
  1464       _attributes.insert(std::make_pair(caption, storage));
       
  1465       return *this;
       
  1466     }
       
  1467 
       
  1468     /// \brief Attribute reading rule
       
  1469     ///
       
  1470     /// Add an attribute reading rule with specialized converter to the
       
  1471     /// reader.
       
  1472     template <typename Value, typename Converter>
       
  1473     GraphReader& attribute(const std::string& caption, Value& value, 
       
  1474 			     const Converter& converter = Converter()) {
       
  1475       _reader_bits::ValueStorageBase* storage = 
       
  1476 	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
       
  1477       _attributes.insert(std::make_pair(caption, storage));
       
  1478       return *this;
       
  1479     }
       
  1480 
       
  1481     /// \brief Node reading rule
       
  1482     ///
       
  1483     /// Add a node reading rule to reader.
       
  1484     GraphReader& node(const std::string& caption, Node& node) {
       
  1485       typedef _reader_bits::MapLookUpConverter<Node> Converter;
       
  1486       Converter converter(_node_index);
       
  1487       _reader_bits::ValueStorageBase* storage = 
       
  1488 	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
       
  1489       _attributes.insert(std::make_pair(caption, storage));
       
  1490       return *this;
       
  1491     }
       
  1492 
       
  1493     /// \brief Edge reading rule
       
  1494     ///
       
  1495     /// Add an edge reading rule to reader.
       
  1496     GraphReader& edge(const std::string& caption, Edge& edge) {
       
  1497       typedef _reader_bits::MapLookUpConverter<Edge> Converter;
       
  1498       Converter converter(_edge_index);
       
  1499       _reader_bits::ValueStorageBase* storage = 
       
  1500 	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
       
  1501       _attributes.insert(std::make_pair(caption, storage));
       
  1502       return *this;
       
  1503     }
       
  1504 
       
  1505     /// \brief Arc reading rule
       
  1506     ///
       
  1507     /// Add an arc reading rule to reader.
       
  1508     GraphReader& arc(const std::string& caption, Arc& arc) {
       
  1509       typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
       
  1510       Converter converter(_graph, _edge_index);
       
  1511       _reader_bits::ValueStorageBase* storage = 
       
  1512 	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
       
  1513       _attributes.insert(std::make_pair(caption, storage));
       
  1514       return *this;
       
  1515     }
       
  1516 
       
  1517     /// @}
       
  1518 
       
  1519     /// \name Select section by name
       
  1520     /// @{
       
  1521 
       
  1522     /// \brief Set \c \@nodes section to be read
       
  1523     ///
       
  1524     /// Set \c \@nodes section to be read
       
  1525     GraphReader& nodes(const std::string& caption) {
       
  1526       _nodes_caption = caption;
       
  1527       return *this;
       
  1528     }
       
  1529 
       
  1530     /// \brief Set \c \@edges section to be read
       
  1531     ///
       
  1532     /// Set \c \@edges section to be read
       
  1533     GraphReader& edges(const std::string& caption) {
       
  1534       _edges_caption = caption;
       
  1535       return *this;
       
  1536     }
       
  1537 
       
  1538     /// \brief Set \c \@attributes section to be read
       
  1539     ///
       
  1540     /// Set \c \@attributes section to be read
       
  1541     GraphReader& attributes(const std::string& caption) {
       
  1542       _attributes_caption = caption;
       
  1543       return *this;
       
  1544     }
       
  1545 
       
  1546     /// @}
       
  1547 
       
  1548     /// \name Section readers
       
  1549     /// @{
       
  1550 
       
  1551     /// \brief Add a section processor with line oriented reading
       
  1552     ///
       
  1553     /// In the \e LGF file extra sections can be placed, which contain
       
  1554     /// any data in arbitrary format. These sections can be read with
       
  1555     /// this function line by line. The first parameter is the type
       
  1556     /// descriptor of the section, the second is a functor, which
       
  1557     /// takes just one \c std::string parameter. At the reading
       
  1558     /// process, each line of the section will be given to the functor
       
  1559     /// object. However, the empty lines and the comment lines are
       
  1560     /// filtered out, and the leading whitespaces are stipped from
       
  1561     /// each processed string.
       
  1562     ///
       
  1563     /// For example let's see a section, which contain several
       
  1564     /// integers, which should be inserted into a vector.
       
  1565     ///\code
       
  1566     ///  @numbers
       
  1567     ///  12 45 23
       
  1568     ///  4
       
  1569     ///  23 6
       
  1570     ///\endcode
       
  1571     ///
       
  1572     /// The functor is implemented as an struct:
       
  1573     ///\code
       
  1574     ///  struct NumberSection {
       
  1575     ///    std::vector<int>& _data;
       
  1576     ///    NumberSection(std::vector<int>& data) : _data(data) {}
       
  1577     ///    void operator()(const std::string& line) {
       
  1578     ///      std::istringstream ls(line);
       
  1579     ///      int value;
       
  1580     ///      while (ls >> value) _data.push_back(value);
       
  1581     ///    }
       
  1582     ///  };
       
  1583     ///
       
  1584     ///  // ...
       
  1585     ///
       
  1586     ///  reader.sectionLines("numbers", NumberSection(vec));  
       
  1587     ///\endcode
       
  1588     template <typename Functor>
       
  1589     GraphReader& sectionLines(const std::string& type, Functor functor) {
       
  1590       LEMON_ASSERT(!type.empty(), "Type is not empty.");
       
  1591       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
       
  1592 		   "Multiple reading of section.");
       
  1593       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
       
  1594 		   type != "attributes", "Multiple reading of section.");
       
  1595       _sections.insert(std::make_pair(type, 
       
  1596         new _reader_bits::LineSection<Functor>(functor)));
       
  1597       return *this;
       
  1598     }
       
  1599 
       
  1600 
       
  1601     /// \brief Add a section processor with stream oriented reading
       
  1602     ///
       
  1603     /// In the \e LGF file extra sections can be placed, which contain
       
  1604     /// any data in arbitrary format. These sections can be read
       
  1605     /// directly with this function. The first parameter is the type
       
  1606     /// of the section, the second is a functor, which takes an \c
       
  1607     /// std::istream& and an int& parameter, the latter regard to the
       
  1608     /// line number of stream. The functor can read the input while
       
  1609     /// the section go on, and the line number should be modified
       
  1610     /// accordingly.
       
  1611     template <typename Functor>
       
  1612     GraphReader& sectionStream(const std::string& type, Functor functor) {
       
  1613       LEMON_ASSERT(!type.empty(), "Type is not empty.");
       
  1614       LEMON_ASSERT(_sections.find(type) == _sections.end(), 
       
  1615 		   "Multiple reading of section.");
       
  1616       LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
       
  1617 		   type != "attributes", "Multiple reading of section.");
       
  1618       _sections.insert(std::make_pair(type, 
       
  1619 	 new _reader_bits::StreamSection<Functor>(functor)));
       
  1620       return *this;
       
  1621     }    
       
  1622     
       
  1623     /// @}
       
  1624 
       
  1625     /// \name Using previously constructed node or edge set
       
  1626     /// @{
       
  1627 
       
  1628     /// \brief Use previously constructed node set
       
  1629     ///
       
  1630     /// Use previously constructed node set, and specify the node
       
  1631     /// label map.
       
  1632     template <typename Map>
       
  1633     GraphReader& useNodes(const Map& map) {
       
  1634       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
  1635       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
       
  1636       _use_nodes = true;
       
  1637       _writer_bits::DefaultConverter<typename Map::Value> converter;
       
  1638       for (NodeIt n(_graph); n != INVALID; ++n) {
       
  1639 	_node_index.insert(std::make_pair(converter(map[n]), n));
       
  1640       }
       
  1641       return *this;
       
  1642     }
       
  1643 
       
  1644     /// \brief Use previously constructed node set
       
  1645     ///
       
  1646     /// Use previously constructed node set, and specify the node
       
  1647     /// label map and a functor which converts the label map values to
       
  1648     /// std::string.
       
  1649     template <typename Map, typename Converter>
       
  1650     GraphReader& useNodes(const Map& map, 
       
  1651 			    const Converter& converter = Converter()) {
       
  1652       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
       
  1653       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
       
  1654       _use_nodes = true;
       
  1655       for (NodeIt n(_graph); n != INVALID; ++n) {
       
  1656 	_node_index.insert(std::make_pair(converter(map[n]), n));
       
  1657       }
       
  1658       return *this;
       
  1659     }
       
  1660 
       
  1661     /// \brief Use previously constructed edge set
       
  1662     ///
       
  1663     /// Use previously constructed edge set, and specify the edge
       
  1664     /// label map.
       
  1665     template <typename Map>
       
  1666     GraphReader& useEdges(const Map& map) {
       
  1667       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
       
  1668       LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
       
  1669       _use_edges = true;
       
  1670       _writer_bits::DefaultConverter<typename Map::Value> converter;
       
  1671       for (EdgeIt a(_graph); a != INVALID; ++a) {
       
  1672 	_edge_index.insert(std::make_pair(converter(map[a]), a));
       
  1673       }
       
  1674       return *this;
       
  1675     }
       
  1676 
       
  1677     /// \brief Use previously constructed edge set
       
  1678     ///
       
  1679     /// Use previously constructed edge set, and specify the edge
       
  1680     /// label map and a functor which converts the label map values to
       
  1681     /// std::string.
       
  1682     template <typename Map, typename Converter>
       
  1683     GraphReader& useEdges(const Map& map, 
       
  1684 			    const Converter& converter = Converter()) {
       
  1685       checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
       
  1686       LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
       
  1687       _use_edges = true;
       
  1688       for (EdgeIt a(_graph); a != INVALID; ++a) {
       
  1689 	_edge_index.insert(std::make_pair(converter(map[a]), a));
       
  1690       }
       
  1691       return *this;
       
  1692     }
       
  1693 
       
  1694     /// @}
       
  1695 
       
  1696   private:
       
  1697 
       
  1698     bool readLine() {
       
  1699       std::string str;
       
  1700       while(++line_num, std::getline(*_is, str)) {
       
  1701 	line.clear(); line.str(str);
       
  1702 	char c;
       
  1703 	if (line >> std::ws >> c && c != '#') {
       
  1704 	  line.putback(c);
       
  1705 	  return true;
       
  1706 	}
       
  1707       }
       
  1708       return false;
       
  1709     }
       
  1710 
       
  1711     bool readSuccess() {
       
  1712       return static_cast<bool>(*_is);
       
  1713     }
       
  1714     
       
  1715     void skipSection() {
       
  1716       char c;
       
  1717       while (readSuccess() && line >> c && c != '@') {
       
  1718 	readLine();
       
  1719       }
       
  1720       line.putback(c);
       
  1721     }
       
  1722 
       
  1723     void readNodes() {
       
  1724 
       
  1725       std::vector<int> map_index(_node_maps.size());
       
  1726       int map_num, label_index;
       
  1727 
       
  1728       if (!readLine()) 
       
  1729 	throw DataFormatError("Cannot find map captions");
       
  1730       
       
  1731       {
       
  1732 	std::map<std::string, int> maps;
       
  1733 	
       
  1734 	std::string map;
       
  1735 	int index = 0;
       
  1736 	while (_reader_bits::readToken(line, map)) {
       
  1737 	  if (maps.find(map) != maps.end()) {
       
  1738 	    std::ostringstream msg;
       
  1739 	    msg << "Multiple occurence of node map: " << map;
       
  1740 	    throw DataFormatError(msg.str().c_str());
       
  1741 	  }
       
  1742 	  maps.insert(std::make_pair(map, index));
       
  1743 	  ++index;
       
  1744 	}
       
  1745 	
       
  1746 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
       
  1747 	  std::map<std::string, int>::iterator jt = 
       
  1748 	    maps.find(_node_maps[i].first);
       
  1749 	  if (jt == maps.end()) {
       
  1750 	    std::ostringstream msg;
       
  1751 	    msg << "Map not found in file: " << _node_maps[i].first;
       
  1752 	    throw DataFormatError(msg.str().c_str());
       
  1753 	  }
       
  1754 	  map_index[i] = jt->second;
       
  1755 	}
       
  1756 
       
  1757 	{
       
  1758 	  std::map<std::string, int>::iterator jt = maps.find("label");
       
  1759 	  if (jt == maps.end())
       
  1760 	    throw DataFormatError("Label map not found in file");
       
  1761 	  label_index = jt->second;
       
  1762 	}
       
  1763 	map_num = maps.size();
       
  1764       }
       
  1765 
       
  1766       char c;
       
  1767       while (readLine() && line >> c && c != '@') {
       
  1768 	line.putback(c);
       
  1769 
       
  1770 	std::vector<std::string> tokens(map_num);
       
  1771 	for (int i = 0; i < map_num; ++i) {
       
  1772 	  if (!_reader_bits::readToken(line, tokens[i])) {
       
  1773 	    std::ostringstream msg;
       
  1774 	    msg << "Column not found (" << i + 1 << ")";
       
  1775 	    throw DataFormatError(msg.str().c_str());
       
  1776 	  }
       
  1777 	}
       
  1778 	if (line >> std::ws >> c)
       
  1779 	  throw DataFormatError("Extra character on the end of line");
       
  1780 	
       
  1781 	Node n;
       
  1782 	if (!_use_nodes) {
       
  1783 	  n = _graph.addNode();
       
  1784 	  _node_index.insert(std::make_pair(tokens[label_index], n));
       
  1785 	} else {
       
  1786 	  typename std::map<std::string, Node>::iterator it =
       
  1787 	    _node_index.find(tokens[label_index]);
       
  1788 	  if (it == _node_index.end()) {
       
  1789 	    std::ostringstream msg;
       
  1790 	    msg << "Node with label not found: " << tokens[label_index];
       
  1791 	    throw DataFormatError(msg.str().c_str());	    
       
  1792 	  }
       
  1793 	  n = it->second;
       
  1794 	}
       
  1795 
       
  1796 	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
       
  1797 	  _node_maps[i].second->set(n, tokens[map_index[i]]);
       
  1798 	}
       
  1799 
       
  1800       }
       
  1801       if (readSuccess()) {
       
  1802 	line.putback(c);
       
  1803       }
       
  1804     }
       
  1805 
       
  1806     void readEdges() {
       
  1807 
       
  1808       std::vector<int> map_index(_edge_maps.size());
       
  1809       int map_num, label_index;
       
  1810 
       
  1811       if (!readLine()) 
       
  1812 	throw DataFormatError("Cannot find map captions");
       
  1813       
       
  1814       {
       
  1815 	std::map<std::string, int> maps;
       
  1816 	
       
  1817 	std::string map;
       
  1818 	int index = 0;
       
  1819 	while (_reader_bits::readToken(line, map)) {
       
  1820 	  if (maps.find(map) != maps.end()) {
       
  1821 	    std::ostringstream msg;
       
  1822 	    msg << "Multiple occurence of edge map: " << map;
       
  1823 	    throw DataFormatError(msg.str().c_str());
       
  1824 	  }
       
  1825 	  maps.insert(std::make_pair(map, index));
       
  1826 	  ++index;
       
  1827 	}
       
  1828 	
       
  1829 	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
       
  1830 	  std::map<std::string, int>::iterator jt = 
       
  1831 	    maps.find(_edge_maps[i].first);
       
  1832 	  if (jt == maps.end()) {
       
  1833 	    std::ostringstream msg;
       
  1834 	    msg << "Map not found in file: " << _edge_maps[i].first;
       
  1835 	    throw DataFormatError(msg.str().c_str());
       
  1836 	  }
       
  1837 	  map_index[i] = jt->second;
       
  1838 	}
       
  1839 
       
  1840 	{
       
  1841 	  std::map<std::string, int>::iterator jt = maps.find("label");
       
  1842 	  if (jt == maps.end())
       
  1843 	    throw DataFormatError("Label map not found in file");
       
  1844 	  label_index = jt->second;
       
  1845 	}
       
  1846 	map_num = maps.size();
       
  1847       }
       
  1848 
       
  1849       char c;
       
  1850       while (readLine() && line >> c && c != '@') {
       
  1851 	line.putback(c);
       
  1852 
       
  1853 	std::string source_token;
       
  1854 	std::string target_token;
       
  1855 
       
  1856 	if (!_reader_bits::readToken(line, source_token))
       
  1857 	  throw DataFormatError("Source not found");
       
  1858 
       
  1859 	if (!_reader_bits::readToken(line, target_token))
       
  1860 	  throw DataFormatError("Source not found");
       
  1861 	
       
  1862 	std::vector<std::string> tokens(map_num);
       
  1863 	for (int i = 0; i < map_num; ++i) {
       
  1864 	  if (!_reader_bits::readToken(line, tokens[i])) {
       
  1865 	    std::ostringstream msg;
       
  1866 	    msg << "Column not found (" << i + 1 << ")";
       
  1867 	    throw DataFormatError(msg.str().c_str());
       
  1868 	  }
       
  1869 	}
       
  1870 	if (line >> std::ws >> c)
       
  1871 	  throw DataFormatError("Extra character on the end of line");
       
  1872 	
       
  1873 	Edge e;
       
  1874 	if (!_use_edges) {
       
  1875 
       
  1876           typename NodeIndex::iterator it;
       
  1877  
       
  1878           it = _node_index.find(source_token);
       
  1879           if (it == _node_index.end()) {
       
  1880             std::ostringstream msg;
       
  1881             msg << "Item not found: " << source_token;
       
  1882             throw DataFormatError(msg.str().c_str());
       
  1883           }
       
  1884           Node source = it->second;
       
  1885 
       
  1886           it = _node_index.find(target_token);
       
  1887           if (it == _node_index.end()) {       
       
  1888             std::ostringstream msg;            
       
  1889             msg << "Item not found: " << target_token;
       
  1890             throw DataFormatError(msg.str().c_str());
       
  1891           }                                          
       
  1892           Node target = it->second;                            
       
  1893 
       
  1894 	  e = _graph.addEdge(source, target);
       
  1895 	  _edge_index.insert(std::make_pair(tokens[label_index], e));
       
  1896 	} else {
       
  1897 	  typename std::map<std::string, Edge>::iterator it =
       
  1898 	    _edge_index.find(tokens[label_index]);
       
  1899 	  if (it == _edge_index.end()) {
       
  1900 	    std::ostringstream msg;
       
  1901 	    msg << "Edge with label not found: " << tokens[label_index];
       
  1902 	    throw DataFormatError(msg.str().c_str());	    
       
  1903 	  }
       
  1904 	  e = it->second;
       
  1905 	}
       
  1906 
       
  1907 	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
       
  1908 	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
       
  1909 	}
       
  1910 
       
  1911       }
       
  1912       if (readSuccess()) {
       
  1913 	line.putback(c);
       
  1914       }
       
  1915     }
       
  1916 
       
  1917     void readAttributes() {
       
  1918 
       
  1919       std::set<std::string> read_attr;
       
  1920 
       
  1921       char c;
       
  1922       while (readLine() && line >> c && c != '@') {
       
  1923 	line.putback(c);
       
  1924 	
       
  1925 	std::string attr, token;
       
  1926 	if (!_reader_bits::readToken(line, attr))
       
  1927 	  throw DataFormatError("Attribute name not found");
       
  1928 	if (!_reader_bits::readToken(line, token))
       
  1929 	  throw DataFormatError("Attribute value not found");
       
  1930 	if (line >> c)
       
  1931 	  throw DataFormatError("Extra character on the end of line");	  
       
  1932 
       
  1933 	{
       
  1934 	  std::set<std::string>::iterator it = read_attr.find(attr);
       
  1935 	  if (it != read_attr.end()) {
       
  1936 	    std::ostringstream msg;
       
  1937 	    msg << "Multiple occurence of attribute " << attr;
       
  1938 	    throw DataFormatError(msg.str().c_str());
       
  1939 	  }
       
  1940 	  read_attr.insert(attr);
       
  1941 	}
       
  1942 	
       
  1943 	{
       
  1944 	  typename Attributes::iterator it = _attributes.lower_bound(attr);
       
  1945 	  while (it != _attributes.end() && it->first == attr) {
       
  1946 	    it->second->set(token);
       
  1947 	    ++it;
       
  1948 	  }
       
  1949 	}
       
  1950 
       
  1951       }
       
  1952       if (readSuccess()) {
       
  1953 	line.putback(c);
       
  1954       }
       
  1955       for (typename Attributes::iterator it = _attributes.begin();
       
  1956 	   it != _attributes.end(); ++it) {
       
  1957 	if (read_attr.find(it->first) == read_attr.end()) {
       
  1958 	  std::ostringstream msg;
       
  1959 	  msg << "Attribute not found in file: " << it->first;
       
  1960 	  throw DataFormatError(msg.str().c_str());
       
  1961 	}	
       
  1962       }
       
  1963     }
       
  1964 
       
  1965   public:
       
  1966 
       
  1967     /// \name Execution of the reader    
       
  1968     /// @{
       
  1969 
       
  1970     /// \brief Start the batch processing
       
  1971     ///
       
  1972     /// This function starts the batch processing
       
  1973     void run() {
       
  1974       
       
  1975       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
       
  1976       
       
  1977       bool nodes_done = false;
       
  1978       bool edges_done = false;
       
  1979       bool attributes_done = false;
       
  1980       std::set<std::string> extra_sections;
       
  1981 
       
  1982       line_num = 0;      
       
  1983       readLine();
       
  1984 
       
  1985       while (readSuccess()) {
       
  1986 	skipSection();
       
  1987 	try {
       
  1988 	  char c;
       
  1989 	  std::string section, caption;
       
  1990 	  line >> c;
       
  1991 	  _reader_bits::readToken(line, section);
       
  1992 	  _reader_bits::readToken(line, caption);
       
  1993 
       
  1994 	  if (line >> c) 
       
  1995 	    throw DataFormatError("Extra character on the end of line");
       
  1996 
       
  1997 	  if (section == "nodes" && !nodes_done) {
       
  1998 	    if (_nodes_caption.empty() || _nodes_caption == caption) {
       
  1999 	      readNodes();
       
  2000 	      nodes_done = true;
       
  2001 	    }
       
  2002 	  } else if ((section == "edges" || section == "arcs") && 
       
  2003 		     !edges_done) {
       
  2004 	    if (_edges_caption.empty() || _edges_caption == caption) {
       
  2005 	      readEdges();
       
  2006 	      edges_done = true;
       
  2007 	    }
       
  2008 	  } else if (section == "attributes" && !attributes_done) {
       
  2009 	    if (_attributes_caption.empty() || _attributes_caption == caption) {
       
  2010 	      readAttributes();
       
  2011 	      attributes_done = true;
       
  2012 	    }
       
  2013 	  } else {
       
  2014 	    if (extra_sections.find(section) != extra_sections.end()) {
       
  2015 	      std::ostringstream msg;
       
  2016 	      msg << "Multiple occurence of section " << section;
       
  2017 	      throw DataFormatError(msg.str().c_str());
       
  2018 	    }
       
  2019 	    Sections::iterator it = _sections.find(section);
       
  2020 	    if (it != _sections.end()) {
       
  2021 	      extra_sections.insert(section);
       
  2022 	      it->second->process(*_is, line_num);
       
  2023 	      readLine();
       
  2024 	    } else {
       
  2025 	      readLine();
       
  2026 	      skipSection();
       
  2027 	    }
       
  2028 	  }
       
  2029 	} catch (DataFormatError& error) {
       
  2030 	  error.line(line_num);
       
  2031 	  throw;
       
  2032 	}	
       
  2033       }
       
  2034 
       
  2035       if (!nodes_done) {
       
  2036 	throw DataFormatError("Section @nodes not found");
       
  2037       }
       
  2038 
       
  2039       if (!edges_done) {
       
  2040 	throw DataFormatError("Section @edges not found");
       
  2041       }
       
  2042 
       
  2043       if (!attributes_done && !_attributes.empty()) {
       
  2044 	throw DataFormatError("Section @attributes not found");
       
  2045       }
       
  2046 
       
  2047     }
       
  2048 
       
  2049     /// @}
       
  2050     
       
  2051   };
       
  2052 
       
  2053   /// \relates GraphReader
       
  2054   template <typename Graph>
       
  2055   GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
       
  2056     GraphReader<Graph> tmp(is, graph);
       
  2057     return tmp;
       
  2058   }
       
  2059 
       
  2060   /// \relates GraphReader
       
  2061   template <typename Graph>
       
  2062   GraphReader<Graph> graphReader(const std::string& fn, 
       
  2063 				       Graph& graph) {
       
  2064     GraphReader<Graph> tmp(fn, graph);
       
  2065     return tmp;
       
  2066   }
       
  2067 
       
  2068   /// \relates GraphReader
       
  2069   template <typename Graph>
       
  2070   GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
       
  2071     GraphReader<Graph> tmp(fn, graph);
       
  2072     return tmp;
       
  2073   }
  1183 }
  2074 }
  1184 
  2075 
  1185 #endif
  2076 #endif