gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
*Maps() -> *MapNames() in LgfContents
0 1 0
default
1 file changed with 6 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 1536 line context
... ...
@@ -1423,976 +1423,976 @@
1423 1423
    /// Add an arc map reading rule to the reader.
1424 1424
    template <typename Map>
1425 1425
    GraphReader& arcMap(const std::string& caption, Map& map) {
1426 1426
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1427 1427
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1428 1428
	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1429 1429
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1430 1430
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1431 1431
	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1432 1432
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1433 1433
      return *this;
1434 1434
    }
1435 1435

	
1436 1436
    /// \brief Arc map reading rule
1437 1437
    ///
1438 1438
    /// Add an arc map reading rule with specialized converter to the
1439 1439
    /// reader.
1440 1440
    template <typename Map, typename Converter>
1441 1441
    GraphReader& arcMap(const std::string& caption, Map& map, 
1442 1442
			  const Converter& converter = Converter()) {
1443 1443
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1444 1444
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1445 1445
	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1446 1446
	(_graph, map, converter);
1447 1447
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1448 1448
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1449 1449
	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1450 1450
	(_graph, map, converter);
1451 1451
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1452 1452
      return *this;
1453 1453
    }
1454 1454

	
1455 1455
    /// \brief Attribute reading rule
1456 1456
    ///
1457 1457
    /// Add an attribute reading rule to the reader.
1458 1458
    template <typename Value>
1459 1459
    GraphReader& attribute(const std::string& caption, Value& value) {
1460 1460
      _reader_bits::ValueStorageBase* storage = 
1461 1461
	new _reader_bits::ValueStorage<Value>(value);
1462 1462
      _attributes.insert(std::make_pair(caption, storage));
1463 1463
      return *this;
1464 1464
    }
1465 1465

	
1466 1466
    /// \brief Attribute reading rule
1467 1467
    ///
1468 1468
    /// Add an attribute reading rule with specialized converter to the
1469 1469
    /// reader.
1470 1470
    template <typename Value, typename Converter>
1471 1471
    GraphReader& attribute(const std::string& caption, Value& value, 
1472 1472
			     const Converter& converter = Converter()) {
1473 1473
      _reader_bits::ValueStorageBase* storage = 
1474 1474
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1475 1475
      _attributes.insert(std::make_pair(caption, storage));
1476 1476
      return *this;
1477 1477
    }
1478 1478

	
1479 1479
    /// \brief Node reading rule
1480 1480
    ///
1481 1481
    /// Add a node reading rule to reader.
1482 1482
    GraphReader& node(const std::string& caption, Node& node) {
1483 1483
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1484 1484
      Converter converter(_node_index);
1485 1485
      _reader_bits::ValueStorageBase* storage = 
1486 1486
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1487 1487
      _attributes.insert(std::make_pair(caption, storage));
1488 1488
      return *this;
1489 1489
    }
1490 1490

	
1491 1491
    /// \brief Edge reading rule
1492 1492
    ///
1493 1493
    /// Add an edge reading rule to reader.
1494 1494
    GraphReader& edge(const std::string& caption, Edge& edge) {
1495 1495
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1496 1496
      Converter converter(_edge_index);
1497 1497
      _reader_bits::ValueStorageBase* storage = 
1498 1498
	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1499 1499
      _attributes.insert(std::make_pair(caption, storage));
1500 1500
      return *this;
1501 1501
    }
1502 1502

	
1503 1503
    /// \brief Arc reading rule
1504 1504
    ///
1505 1505
    /// Add an arc reading rule to reader.
1506 1506
    GraphReader& arc(const std::string& caption, Arc& arc) {
1507 1507
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1508 1508
      Converter converter(_graph, _edge_index);
1509 1509
      _reader_bits::ValueStorageBase* storage = 
1510 1510
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1511 1511
      _attributes.insert(std::make_pair(caption, storage));
1512 1512
      return *this;
1513 1513
    }
1514 1514

	
1515 1515
    /// @}
1516 1516

	
1517 1517
    /// \name Select section by name
1518 1518
    /// @{
1519 1519

	
1520 1520
    /// \brief Set \c \@nodes section to be read
1521 1521
    ///
1522 1522
    /// Set \c \@nodes section to be read
1523 1523
    GraphReader& nodes(const std::string& caption) {
1524 1524
      _nodes_caption = caption;
1525 1525
      return *this;
1526 1526
    }
1527 1527

	
1528 1528
    /// \brief Set \c \@edges section to be read
1529 1529
    ///
1530 1530
    /// Set \c \@edges section to be read
1531 1531
    GraphReader& edges(const std::string& caption) {
1532 1532
      _edges_caption = caption;
1533 1533
      return *this;
1534 1534
    }
1535 1535

	
1536 1536
    /// \brief Set \c \@attributes section to be read
1537 1537
    ///
1538 1538
    /// Set \c \@attributes section to be read
1539 1539
    GraphReader& attributes(const std::string& caption) {
1540 1540
      _attributes_caption = caption;
1541 1541
      return *this;
1542 1542
    }
1543 1543

	
1544 1544
    /// @}
1545 1545

	
1546 1546
    /// \name Section readers
1547 1547
    /// @{
1548 1548

	
1549 1549
    /// \brief Add a section processor with line oriented reading
1550 1550
    ///
1551 1551
    /// In the \e LGF file extra sections can be placed, which contain
1552 1552
    /// any data in arbitrary format. These sections can be read with
1553 1553
    /// this function line by line. The first parameter is the type
1554 1554
    /// descriptor of the section, the second is a functor, which
1555 1555
    /// takes just one \c std::string parameter. At the reading
1556 1556
    /// process, each line of the section will be given to the functor
1557 1557
    /// object. However, the empty lines and the comment lines are
1558 1558
    /// filtered out, and the leading whitespaces are stipped from
1559 1559
    /// each processed string.
1560 1560
    ///
1561 1561
    /// For example let's see a section, which contain several
1562 1562
    /// integers, which should be inserted into a vector.
1563 1563
    ///\code
1564 1564
    ///  @numbers
1565 1565
    ///  12 45 23
1566 1566
    ///  4
1567 1567
    ///  23 6
1568 1568
    ///\endcode
1569 1569
    ///
1570 1570
    /// The functor is implemented as an struct:
1571 1571
    ///\code
1572 1572
    ///  struct NumberSection {
1573 1573
    ///    std::vector<int>& _data;
1574 1574
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
1575 1575
    ///    void operator()(const std::string& line) {
1576 1576
    ///      std::istringstream ls(line);
1577 1577
    ///      int value;
1578 1578
    ///      while (ls >> value) _data.push_back(value);
1579 1579
    ///    }
1580 1580
    ///  };
1581 1581
    ///
1582 1582
    ///  // ...
1583 1583
    ///
1584 1584
    ///  reader.sectionLines("numbers", NumberSection(vec));  
1585 1585
    ///\endcode
1586 1586
    template <typename Functor>
1587 1587
    GraphReader& sectionLines(const std::string& type, Functor functor) {
1588 1588
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1589 1589
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1590 1590
		   "Multiple reading of section.");
1591 1591
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1592 1592
		   type != "attributes", "Multiple reading of section.");
1593 1593
      _sections.insert(std::make_pair(type, 
1594 1594
        new _reader_bits::LineSection<Functor>(functor)));
1595 1595
      return *this;
1596 1596
    }
1597 1597

	
1598 1598

	
1599 1599
    /// \brief Add a section processor with stream oriented reading
1600 1600
    ///
1601 1601
    /// In the \e LGF file extra sections can be placed, which contain
1602 1602
    /// any data in arbitrary format. These sections can be read
1603 1603
    /// directly with this function. The first parameter is the type
1604 1604
    /// of the section, the second is a functor, which takes an \c
1605 1605
    /// std::istream& and an int& parameter, the latter regard to the
1606 1606
    /// line number of stream. The functor can read the input while
1607 1607
    /// the section go on, and the line number should be modified
1608 1608
    /// accordingly.
1609 1609
    template <typename Functor>
1610 1610
    GraphReader& sectionStream(const std::string& type, Functor functor) {
1611 1611
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1612 1612
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1613 1613
		   "Multiple reading of section.");
1614 1614
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1615 1615
		   type != "attributes", "Multiple reading of section.");
1616 1616
      _sections.insert(std::make_pair(type, 
1617 1617
	 new _reader_bits::StreamSection<Functor>(functor)));
1618 1618
      return *this;
1619 1619
    }    
1620 1620
    
1621 1621
    /// @}
1622 1622

	
1623 1623
    /// \name Using previously constructed node or edge set
1624 1624
    /// @{
1625 1625

	
1626 1626
    /// \brief Use previously constructed node set
1627 1627
    ///
1628 1628
    /// Use previously constructed node set, and specify the node
1629 1629
    /// label map.
1630 1630
    template <typename Map>
1631 1631
    GraphReader& useNodes(const Map& map) {
1632 1632
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1633 1633
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1634 1634
      _use_nodes = true;
1635 1635
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1636 1636
      for (NodeIt n(_graph); n != INVALID; ++n) {
1637 1637
	_node_index.insert(std::make_pair(converter(map[n]), n));
1638 1638
      }
1639 1639
      return *this;
1640 1640
    }
1641 1641

	
1642 1642
    /// \brief Use previously constructed node set
1643 1643
    ///
1644 1644
    /// Use previously constructed node set, and specify the node
1645 1645
    /// label map and a functor which converts the label map values to
1646 1646
    /// std::string.
1647 1647
    template <typename Map, typename Converter>
1648 1648
    GraphReader& useNodes(const Map& map, 
1649 1649
			    const Converter& converter = Converter()) {
1650 1650
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1651 1651
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1652 1652
      _use_nodes = true;
1653 1653
      for (NodeIt n(_graph); n != INVALID; ++n) {
1654 1654
	_node_index.insert(std::make_pair(converter(map[n]), n));
1655 1655
      }
1656 1656
      return *this;
1657 1657
    }
1658 1658

	
1659 1659
    /// \brief Use previously constructed edge set
1660 1660
    ///
1661 1661
    /// Use previously constructed edge set, and specify the edge
1662 1662
    /// label map.
1663 1663
    template <typename Map>
1664 1664
    GraphReader& useEdges(const Map& map) {
1665 1665
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1666 1666
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1667 1667
      _use_edges = true;
1668 1668
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1669 1669
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1670 1670
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1671 1671
      }
1672 1672
      return *this;
1673 1673
    }
1674 1674

	
1675 1675
    /// \brief Use previously constructed edge set
1676 1676
    ///
1677 1677
    /// Use previously constructed edge set, and specify the edge
1678 1678
    /// label map and a functor which converts the label map values to
1679 1679
    /// std::string.
1680 1680
    template <typename Map, typename Converter>
1681 1681
    GraphReader& useEdges(const Map& map, 
1682 1682
			    const Converter& converter = Converter()) {
1683 1683
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1684 1684
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
1685 1685
      _use_edges = true;
1686 1686
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1687 1687
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1688 1688
      }
1689 1689
      return *this;
1690 1690
    }
1691 1691

	
1692 1692
    /// @}
1693 1693

	
1694 1694
  private:
1695 1695

	
1696 1696
    bool readLine() {
1697 1697
      std::string str;
1698 1698
      while(++line_num, std::getline(*_is, str)) {
1699 1699
	line.clear(); line.str(str);
1700 1700
	char c;
1701 1701
	if (line >> std::ws >> c && c != '#') {
1702 1702
	  line.putback(c);
1703 1703
	  return true;
1704 1704
	}
1705 1705
      }
1706 1706
      return false;
1707 1707
    }
1708 1708

	
1709 1709
    bool readSuccess() {
1710 1710
      return static_cast<bool>(*_is);
1711 1711
    }
1712 1712
    
1713 1713
    void skipSection() {
1714 1714
      char c;
1715 1715
      while (readSuccess() && line >> c && c != '@') {
1716 1716
	readLine();
1717 1717
      }
1718 1718
      line.putback(c);
1719 1719
    }
1720 1720

	
1721 1721
    void readNodes() {
1722 1722

	
1723 1723
      std::vector<int> map_index(_node_maps.size());
1724 1724
      int map_num, label_index;
1725 1725

	
1726 1726
      if (!readLine()) 
1727 1727
	throw DataFormatError("Cannot find map captions");
1728 1728
      
1729 1729
      {
1730 1730
	std::map<std::string, int> maps;
1731 1731
	
1732 1732
	std::string map;
1733 1733
	int index = 0;
1734 1734
	while (_reader_bits::readToken(line, map)) {
1735 1735
	  if (maps.find(map) != maps.end()) {
1736 1736
	    std::ostringstream msg;
1737 1737
	    msg << "Multiple occurence of node map: " << map;
1738 1738
	    throw DataFormatError(msg.str().c_str());
1739 1739
	  }
1740 1740
	  maps.insert(std::make_pair(map, index));
1741 1741
	  ++index;
1742 1742
	}
1743 1743
	
1744 1744
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1745 1745
	  std::map<std::string, int>::iterator jt = 
1746 1746
	    maps.find(_node_maps[i].first);
1747 1747
	  if (jt == maps.end()) {
1748 1748
	    std::ostringstream msg;
1749 1749
	    msg << "Map not found in file: " << _node_maps[i].first;
1750 1750
	    throw DataFormatError(msg.str().c_str());
1751 1751
	  }
1752 1752
	  map_index[i] = jt->second;
1753 1753
	}
1754 1754

	
1755 1755
	{
1756 1756
	  std::map<std::string, int>::iterator jt = maps.find("label");
1757 1757
	  if (jt == maps.end())
1758 1758
	    throw DataFormatError("Label map not found in file");
1759 1759
	  label_index = jt->second;
1760 1760
	}
1761 1761
	map_num = maps.size();
1762 1762
      }
1763 1763

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

	
1768 1768
	std::vector<std::string> tokens(map_num);
1769 1769
	for (int i = 0; i < map_num; ++i) {
1770 1770
	  if (!_reader_bits::readToken(line, tokens[i])) {
1771 1771
	    std::ostringstream msg;
1772 1772
	    msg << "Column not found (" << i + 1 << ")";
1773 1773
	    throw DataFormatError(msg.str().c_str());
1774 1774
	  }
1775 1775
	}
1776 1776
	if (line >> std::ws >> c)
1777 1777
	  throw DataFormatError("Extra character on the end of line");
1778 1778
	
1779 1779
	Node n;
1780 1780
	if (!_use_nodes) {
1781 1781
	  n = _graph.addNode();
1782 1782
	  _node_index.insert(std::make_pair(tokens[label_index], n));
1783 1783
	} else {
1784 1784
	  typename std::map<std::string, Node>::iterator it =
1785 1785
	    _node_index.find(tokens[label_index]);
1786 1786
	  if (it == _node_index.end()) {
1787 1787
	    std::ostringstream msg;
1788 1788
	    msg << "Node with label not found: " << tokens[label_index];
1789 1789
	    throw DataFormatError(msg.str().c_str());	    
1790 1790
	  }
1791 1791
	  n = it->second;
1792 1792
	}
1793 1793

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

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

	
1804 1804
    void readEdges() {
1805 1805

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

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

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

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

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

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

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

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

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

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

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

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

	
1915 1915
    void readAttributes() {
1916 1916

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

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

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

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

	
1963 1963
  public:
1964 1964

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

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

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

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

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

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

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

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

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

	
2043 2043
    }
2044 2044

	
2045 2045
    /// @}
2046 2046
    
2047 2047
  };
2048 2048

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

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

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

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

	
2101 2101
    std::istream* _is;
2102 2102
    bool local_is;
2103 2103

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

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

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

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

	
2116 2116

	
2117 2117
    int line_num;
2118 2118
    std::istringstream line;
2119 2119
    
2120 2120
  public:
2121 2121

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

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

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

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

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

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

	
2170 2170

	
2171 2171
    /// \name Node sections
2172 2172
    /// @{
2173 2173

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

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

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

	
2195 2195
    /// @}
2196 2196

	
2197 2197
    /// \name Arc/Edge sections 
2198 2198
    /// @{
2199 2199

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

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

	
2216 2216
    /// \brief Gives back the arc/edge maps for the given section.
2217 2217
    ///
2218 2218
    /// Gives back the arc/edge maps for the given section.
2219
    /// \note It is synonym of \c edgeMaps().
2220
    const std::vector<std::string>& arcMaps(int i) const {
2219
    /// \note It is synonym of \c edgeMapNames().
2220
    const std::vector<std::string>& arcMapNames(int i) const {
2221 2221
      return _edge_maps[i];
2222 2222
    }
2223 2223

	
2224 2224
    /// @}
2225 2225

	
2226 2226
    /// \name Synonyms
2227 2227
    /// @{
2228 2228

	
2229 2229
    /// \brief Gives back the number of arc/edge sections in the file.
2230 2230
    ///
2231 2231
    /// Gives back the number of arc/edge sections in the file.
2232 2232
    /// \note It is synonym of \c arcSectionNum().
2233 2233
    int edgeSectionNum() const {
2234 2234
      return _edge_sections.size();
2235 2235
    }
2236 2236

	
2237 2237
    /// \brief Returns the section name at the given position. 
2238 2238
    ///
2239 2239
    /// Returns the section name at the given position. 
2240 2240
    /// \note It is synonym of \c arcSection().
2241 2241
    const std::string& edgeSection(int i) const {
2242 2242
      return _edge_sections[i];
2243 2243
    }
2244 2244

	
2245 2245
    /// \brief Gives back the edge maps for the given section.
2246 2246
    ///
2247 2247
    /// Gives back the edge maps for the given section.
2248
    /// \note It is synonym of \c arcMaps().
2249
    const std::vector<std::string>& edgeMaps(int i) const {
2248
    /// \note It is synonym of \c arcMapNames().
2249
    const std::vector<std::string>& edgeMapNames(int i) const {
2250 2250
      return _edge_maps[i];
2251 2251
    }
2252 2252

	
2253 2253
    /// @}
2254 2254

	
2255 2255
    /// \name Attribute sections   
2256 2256
    /// @{
2257 2257

	
2258 2258
    /// \brief Gives back the number of attribute sections in the file.
2259 2259
    ///
2260 2260
    /// Gives back the number of attribute sections in the file.
2261 2261
    int attributeSectionNum() const {
2262 2262
      return _attribute_sections.size();
2263 2263
    }
2264 2264

	
2265 2265
    /// \brief Returns the section name at the given position. 
2266 2266
    ///
2267 2267
    /// Returns the section name at the given position. 
2268
    const std::string& attributeSection(int i) const {
2268
    const std::string& attributeSectionNames(int i) const {
2269 2269
      return _attribute_sections[i];
2270 2270
    }
2271 2271

	
2272 2272
    /// \brief Gives back the attributes for the given section.
2273 2273
    ///
2274 2274
    /// Gives back the attributes for the given section.
2275 2275
    const std::vector<std::string>& attributes(int i) const {
2276 2276
      return _attributes[i];
2277 2277
    }
2278 2278

	
2279 2279
    /// @}
2280 2280

	
2281 2281
    /// \name Extra sections   
2282 2282
    /// @{
2283 2283

	
2284 2284
    /// \brief Gives back the number of extra sections in the file.
2285 2285
    ///
2286 2286
    /// Gives back the number of extra sections in the file.
2287 2287
    int extraSectionNum() const {
2288 2288
      return _extra_sections.size();
2289 2289
    }
2290 2290

	
2291 2291
    /// \brief Returns the extra section type at the given position. 
2292 2292
    ///
2293 2293
    /// Returns the section type at the given position. 
2294 2294
    const std::string& extraSection(int i) const {
2295 2295
      return _extra_sections[i];
2296 2296
    }
2297 2297

	
2298 2298
    /// @}
2299 2299

	
2300 2300
  private:
2301 2301

	
2302 2302
    bool readLine() {
2303 2303
      std::string str;
2304 2304
      while(++line_num, std::getline(*_is, str)) {
2305 2305
	line.clear(); line.str(str);
2306 2306
	char c;
2307 2307
	if (line >> std::ws >> c && c != '#') {
2308 2308
	  line.putback(c);
2309 2309
	  return true;
2310 2310
	}
2311 2311
      }
2312 2312
      return false;
2313 2313
    }
2314 2314

	
2315 2315
    bool readSuccess() {
2316 2316
      return static_cast<bool>(*_is);
2317 2317
    }
2318 2318

	
2319 2319
    void skipSection() {
2320 2320
      char c;
2321 2321
      while (readSuccess() && line >> c && c != '@') {
2322 2322
	readLine();
2323 2323
      }
2324 2324
      line.putback(c);
2325 2325
    }
2326 2326

	
2327 2327
    void readMaps(std::vector<std::string>& maps) {
2328 2328
      if (!readLine()) 
2329 2329
	throw DataFormatError("Cannot find map captions");
2330 2330
      std::string map;
2331 2331
      while (_reader_bits::readToken(line, map)) {
2332 2332
	maps.push_back(map);
2333 2333
      }
2334 2334
    }
2335 2335

	
2336 2336
    void readAttributes(std::vector<std::string>& attrs) {
2337 2337
      readLine();
2338 2338
      char c;
2339 2339
      while (readSuccess() && line >> c && c != '@') {
2340 2340
	line.putback(c);
2341 2341
	std::string attr;
2342 2342
	_reader_bits::readToken(line, attr);
2343 2343
	attrs.push_back(attr);
2344 2344
	readLine();
2345 2345
      }
2346 2346
      line.putback(c);
2347 2347
    }
2348 2348

	
2349 2349
  public:
2350 2350

	
2351 2351
    /// \name Execution of the contents reader    
2352 2352
    /// @{
2353 2353

	
2354 2354
    /// \brief Start the reading
2355 2355
    ///
2356 2356
    /// This function starts the reading
2357 2357
    void run() {
2358 2358

	
2359 2359
      readLine();
2360 2360
      skipSection();
2361 2361

	
2362 2362
      while (readSuccess()) {
2363 2363

	
2364 2364
	char c;
2365 2365
	line >> c;
2366 2366

	
2367 2367
	std::string section, caption;
2368 2368
	_reader_bits::readToken(line, section);
2369 2369
	_reader_bits::readToken(line, caption);
2370 2370

	
2371 2371
	if (section == "nodes") {
2372 2372
	  _node_sections.push_back(caption);
2373 2373
	  _node_maps.push_back(std::vector<std::string>());
2374 2374
	  readMaps(_node_maps.back());
2375 2375
	  readLine(); skipSection();
2376 2376
	} else if (section == "arcs" || section == "edges") {
2377 2377
	  _edge_sections.push_back(caption);
2378 2378
	  _arc_sections.push_back(section == "arcs");
2379 2379
	  _edge_maps.push_back(std::vector<std::string>());
2380 2380
	  readMaps(_edge_maps.back());
2381 2381
	  readLine(); skipSection();
2382 2382
	} else if (section == "attributes") {
2383 2383
	  _attribute_sections.push_back(caption);
2384 2384
	  _attributes.push_back(std::vector<std::string>());
2385 2385
	  readAttributes(_attributes.back());
2386 2386
	} else {
2387 2387
	  _extra_sections.push_back(section);
2388 2388
	  readLine(); skipSection();
2389 2389
	}
2390 2390
      }
2391 2391
    }
2392 2392

	
2393 2393
    /// @}
2394 2394
    
2395 2395
  };
2396 2396
}
2397 2397

	
2398 2398
#endif
0 comments (0 inline)