src/work/deba/graph_reader.h
changeset 1037 3eaff8d04171
parent 1036 2f514b5c7122
child 1115 444f69240539
     1.1 --- a/src/work/deba/graph_reader.h	Tue Dec 14 19:26:50 2004 +0000
     1.2 +++ b/src/work/deba/graph_reader.h	Wed Dec 15 19:56:55 2004 +0000
     1.3 @@ -24,6 +24,8 @@
     1.4  #include <map>
     1.5  #include <vector>
     1.6  
     1.7 +#include <memory>
     1.8 +
     1.9  #include <lemon/error.h>
    1.10  
    1.11  /// \todo fix exceptions
    1.12 @@ -48,11 +50,21 @@
    1.13      }
    1.14    };
    1.15  
    1.16 -  class StreamException : public IOException {
    1.17 +  template <typename _Exception>
    1.18 +  class StreamException : public _Exception {
    1.19    public:
    1.20 -    virtual int line() = 0;
    1.21 +    typedef _Exception Exception;
    1.22 +    StreamException(int _line, Exception _exception) 
    1.23 +      : line_num(_line), Exception(_exception) {}
    1.24 +    virtual int line() const {
    1.25 +      return line_num;
    1.26 +    }
    1.27 +    virtual std::string what() const {
    1.28 +      ostringstream os;
    1.29 +      os << Exception::what() << " in line " << line();
    1.30 +      return os.str();
    1.31 +    }
    1.32    private:
    1.33 -    IOException* exception;
    1.34      int line_num;
    1.35    };  
    1.36  
    1.37 @@ -84,7 +96,7 @@
    1.38        char c;
    1.39        value.clear();
    1.40        is >> ws;
    1.41 -      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
    1.42 +      if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format");
    1.43        while (is.get(c) && c != '\"') {
    1.44  	if (escaped && c == '\\') {
    1.45  	  value += readEscape(is);
    1.46 @@ -92,7 +104,7 @@
    1.47  	  value += c;
    1.48  	}
    1.49        }
    1.50 -      if (!is) throw DataFormatException("Quoted string format exception");
    1.51 +      if (!is) throw DataFormatException("Quoted string format");
    1.52      }
    1.53  
    1.54    private:
    1.55 @@ -171,7 +183,6 @@
    1.56    
    1.57    template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
    1.58    class GraphReader {
    1.59 -
    1.60    public:
    1.61      
    1.62      typedef _Graph Graph;
    1.63 @@ -181,22 +192,24 @@
    1.64      typedef _ReaderTraits ReaderTraits;
    1.65      typedef typename ReaderTraits::DefaultReader DefaultReader;
    1.66  
    1.67 -    GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
    1.68 +    GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
    1.69        : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
    1.70  
    1.71  
    1.72      ~GraphReader() {
    1.73  
    1.74 -      for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
    1.75 +      for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) {
    1.76  	delete it->second;
    1.77        }
    1.78  
    1.79 -      for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
    1.80 +      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) {
    1.81  	delete it->second;
    1.82        }
    1.83  
    1.84      }
    1.85  
    1.86 +    // Node map rules
    1.87 +
    1.88      template <typename Map>
    1.89      GraphReader& readNodeMap(std::string name, Map& map) {
    1.90        return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
    1.91 @@ -204,26 +217,24 @@
    1.92  
    1.93      template <typename Reader, typename Map>
    1.94      GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
    1.95 -      if (node_readers.find(name) != node_readers.end()) {
    1.96 -	Exception e;
    1.97 -	e << "Multiple read rule for node map: " << name;
    1.98 -	throw e;
    1.99 +      if (node_map_readers.find(name) != node_map_readers.end()) {
   1.100 +	throw Exception() << "Multiple read rule for node map: " << name;
   1.101        }
   1.102 -      node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   1.103 +      node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   1.104        return *this;
   1.105      }
   1.106  
   1.107      template <typename Reader>
   1.108      GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
   1.109 -      if (node_readers.find(name) != node_readers.end()) {
   1.110 -	Exception e;
   1.111 -	e << "Multiple read rule for node map: " << name;
   1.112 -	throw e;
   1.113 +      if (node_map_readers.find(name) != node_map_readers.end()) {
   1.114 +	throw Exception() << "Multiple read rule for node map: " << name;
   1.115        }
   1.116 -      node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   1.117 +      node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
   1.118        return *this;
   1.119      }
   1.120  
   1.121 +    // Edge map rules
   1.122 +
   1.123      template <typename Map>
   1.124      GraphReader& readEdgeMap(std::string name, Map& map) { 
   1.125        return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
   1.126 @@ -232,81 +243,106 @@
   1.127  
   1.128      template <typename Reader, typename Map>
   1.129      GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   1.130 -      if (edge_readers.find(name) != edge_readers.end()) {
   1.131 -	Exception e;
   1.132 -	e << "Multiple read rule for edge map: " << name;
   1.133 -	throw e;
   1.134 +      if (edge_map_readers.find(name) != edge_map_readers.end()) {
   1.135 +	throw Exception() << "Multiple read rule for edge map: " << name;
   1.136        }
   1.137 -      edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   1.138 +      edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   1.139        return *this;
   1.140      }
   1.141  
   1.142      template <typename Reader>
   1.143      GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
   1.144 +      if (edge_map_readers.find(name) != edge_map_readers.end()) {
   1.145 +	throw Exception() << "Multiple read rule for edge map: " << name;
   1.146 +      }
   1.147 +      edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   1.148 +      return *this;
   1.149 +    }
   1.150 +
   1.151 +    // Node rules
   1.152 +    GraphReader& readNode(std::string name, Node& node) {
   1.153 +      if (node_readers.find(name) != node_readers.end()) {
   1.154 +	throw Exception() << "Multiple read rule for node";
   1.155 +      }
   1.156 +      node_readers.insert(make_pair(name, &node));
   1.157 +    }
   1.158 +
   1.159 +    // Edge rules
   1.160 +
   1.161 +    GraphReader& readEdge(std::string name, Edge& edge) {
   1.162        if (edge_readers.find(name) != edge_readers.end()) {
   1.163 -	Exception e;
   1.164 -	e << "Multiple read rule for edge map: " << name;
   1.165 -	throw e;
   1.166 +	throw Exception() << "Multiple read rule for edge";
   1.167        }
   1.168 -      edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
   1.169 -      return *this;
   1.170 +      edge_readers.insert(make_pair(name, &edge));
   1.171      }
   1.172  
   1.173      void read() {
   1.174        int line_num = 0;
   1.175 -      InverterBase<Node>* nodeInverter = 0;
   1.176 -      InverterBase<Edge>* edgeInverter = 0;
   1.177 -      // \todo delete the inverters
   1.178 -      //      try {
   1.179 -	{
   1.180 -	  std::string line = readNotEmptyLine(is, line_num);
   1.181 +      std::auto_ptr<InverterBase<Node> > nodeInverter;
   1.182 +      std::auto_ptr<InverterBase<Edge> > edgeInverter;
   1.183 +      try {
   1.184 +	std::string line = readNotEmptyLine(is, line_num);
   1.185 +	if (line.find("@nodeset") == 0) {
   1.186 +	  line = readNodeSet(line_num, nodeInverter);
   1.187 +	} 
   1.188 +	if (line.find("@edgeset") == 0) {
   1.189 +	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
   1.190  	}
   1.191 -	readNodeSet(line_num, nodeInverter);
   1.192 -	readEdgeSet(line_num, edgeInverter, nodeInverter);
   1.193 -	//      } catch (...){
   1.194 -	if (nodeInverter != 0) delete nodeInverter;
   1.195 -	if (edgeInverter != 0) delete edgeInverter;
   1.196 -	//      }
   1.197 +	if (line.find("@nodes") == 0) {
   1.198 +	  line = readNodes(line_num, nodeInverter);
   1.199 +	}
   1.200 +	if (line.find("@edges") == 0) {
   1.201 +	  line = readEdges(line_num, edgeInverter);
   1.202 +	}
   1.203 +	if (line.find("@end") != 0) {
   1.204 +	  throw DataFormatException("Invalid control sequence: " + line);
   1.205 +	}
   1.206 +      } catch (DataFormatException e) {
   1.207 +	throw StreamException<DataFormatException>(line_num, e);
   1.208 +      }
   1.209      }
   1.210  
   1.211    private:
   1.212  
   1.213      template <typename Item> class InverterBase;
   1.214 -    //    template <typename Item> class InverterBase;
   1.215  
   1.216 -    void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
   1.217 -      int n = 0;
   1.218 -      std::vector<ReaderBase<Node>*> index;
   1.219 +    std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) {
   1.220 +      std::vector<ReaderBase<Node>* > index;
   1.221        {
   1.222  	std::string line = readNotEmptyLine(is, line_num);    
   1.223  	std::string id;
   1.224  	std::istringstream ls(line);	
   1.225  	while (ls >> id) {
   1.226  	  if (id[0] == '#') break;
   1.227 -	  typename NodeReaders::iterator it = node_readers.find(id);
   1.228 -	  if (it != node_readers.end()) {
   1.229 +	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
   1.230 +	  if (it != node_map_readers.end()) {
   1.231  	    index.push_back(it->second);
   1.232 +	    node_map_readers.erase(it);
   1.233  	  } else {
   1.234  	    index.push_back(&nodeSkipper);
   1.235  	  }
   1.236 -	  ++n;
   1.237  	}
   1.238        }
   1.239  
   1.240 -      nodeInverter = index[0]->getInverter();
   1.241 +      if (index.size() == 0) {
   1.242 +	throw DataFormatException("No node map found");
   1.243 +      }
   1.244 +
   1.245 +      nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter());
   1.246        std::string line;
   1.247        while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   1.248  	Node node = graph.addNode();
   1.249  	std::istringstream ls(line);
   1.250  	nodeInverter->read(ls, node);
   1.251 -	for (int i = 1; i < n; ++i) {
   1.252 +	for (int i = 1; i < index.size(); ++i) {
   1.253  	  index[i]->read(ls, node);
   1.254  	}
   1.255        }
   1.256 +      return line;
   1.257      }
   1.258  
   1.259 -    void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
   1.260 -      int n = 0;
   1.261 +    std::string readEdgeSet(int& line_num, 
   1.262 +		     auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) {
   1.263        std::vector<ReaderBase<Edge>*> index;
   1.264        {
   1.265  	std::string line = readNotEmptyLine(is, line_num);    
   1.266 @@ -314,16 +350,21 @@
   1.267  	std::istringstream ls(line);	
   1.268  	while (ls >> id) {
   1.269  	  if (id[0] == '#') break;
   1.270 -	  typename EdgeReaders::iterator it = edge_readers.find(id);
   1.271 -	  if (it != edge_readers.end()) {
   1.272 +	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
   1.273 +	  if (it != edge_map_readers.end()) {
   1.274  	    index.push_back(it->second);
   1.275 +	    edge_map_readers.erase(it);
   1.276  	  } else {
   1.277  	    index.push_back(&edgeSkipper);
   1.278  	  }
   1.279 -	  ++n;
   1.280  	}
   1.281        }
   1.282 -      edgeInverter = index[0]->getInverter();
   1.283 +
   1.284 +      if (index.size() == 0) {
   1.285 +	throw DataFormatException("No edge map found");
   1.286 +      }
   1.287 +
   1.288 +      edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
   1.289        std::string line;
   1.290        while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
   1.291  	std::istringstream ls(line);
   1.292 @@ -331,10 +372,39 @@
   1.293  	Node target = nodeInverter->read(ls);
   1.294  	Edge edge = graph.addEdge(source, target);
   1.295  	edgeInverter->read(ls, edge);
   1.296 -	for (int i = 1; i < n; ++i) {
   1.297 +	for (int i = 1; i < index.size(); ++i) {
   1.298  	  index[i]->read(ls, edge);
   1.299  	}
   1.300        }      
   1.301 +      return line;
   1.302 +    }
   1.303 +
   1.304 +    std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) {
   1.305 +      std::string line;
   1.306 +      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   1.307 +	std::istringstream ls(line);
   1.308 +	std::string name;
   1.309 +	ls >> name;
   1.310 +	typename NodeReaders::iterator it = node_readers.find(name);
   1.311 +	if (it != node_readers.end()) {
   1.312 +	  *(it -> second) = nodeInverter->read(ls);
   1.313 +	} 
   1.314 +      }        
   1.315 +      return line;
   1.316 +    }
   1.317 +
   1.318 +    std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) {
   1.319 +      std::string line;
   1.320 +      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   1.321 +	std::istringstream ls(line);
   1.322 +	std::string name;
   1.323 +	ls >> name;
   1.324 +	typename EdgeReaders::iterator it = edge_readers.find(name);
   1.325 +	if (it != edge_readers.end()) {
   1.326 +	  *(it -> second) = edgeInverter->read(ls);
   1.327 +	} 
   1.328 +      }        
   1.329 +      return line;    
   1.330      }
   1.331  
   1.332      std::string readNotEmptyLine(std::istream& is, int& line_num) {
   1.333 @@ -345,15 +415,18 @@
   1.334  	  return line.substr(vi);
   1.335  	}
   1.336        }
   1.337 -      throw Exception();
   1.338 +      throw DataFormatException("End of stream");
   1.339      }
   1.340      
   1.341 +    // Inverters store and give back the Item from the id,
   1.342 +    // and may put the ids into a map.
   1.343 +    
   1.344      template <typename _Item>
   1.345      class InverterBase {
   1.346      public:
   1.347        typedef _Item Item;
   1.348 -      virtual void read(istream&, const Item&) = 0;
   1.349 -      virtual Item read(istream&) = 0;
   1.350 +      virtual void read(std::istream&, const Item&) = 0;
   1.351 +      virtual Item read(std::istream&) = 0;
   1.352      };
   1.353  
   1.354      template <typename _Item, typename _Map, typename _Reader>
   1.355 @@ -372,7 +445,7 @@
   1.356        MapReaderInverter(Map& _map, const Reader& _reader) 
   1.357  	: map(_map), reader(_reader) {}
   1.358  
   1.359 -      virtual void read(istream& is, const Item& item) {
   1.360 +      virtual void read(std::istream& is, const Item& item) {
   1.361  	Value value;
   1.362  	reader.read(is, value);
   1.363  	map.set(item, value);
   1.364 @@ -384,7 +457,7 @@
   1.365  	}
   1.366        }
   1.367  
   1.368 -      virtual Item read(istream& is) {
   1.369 +      virtual Item read(std::istream& is) {
   1.370  	Value value;
   1.371  	reader.read(is, value);	
   1.372  	typename Inverse::const_iterator it = inverse.find(value);
   1.373 @@ -409,7 +482,7 @@
   1.374        SkipReaderInverter(const Reader& _reader) 
   1.375  	: reader(_reader) {}
   1.376  
   1.377 -      virtual void read(istream& is, const Item& item) {
   1.378 +      virtual void read(std::istream& is, const Item& item) {
   1.379  	Value value;
   1.380  	reader.read(is, value);
   1.381  	typename Inverse::iterator it = inverse.find(value);
   1.382 @@ -420,7 +493,7 @@
   1.383  	}
   1.384        }
   1.385  
   1.386 -      virtual Item read(istream& is) {
   1.387 +      virtual Item read(std::istream& is) {
   1.388  	Value value;
   1.389  	reader.read(is, value);	
   1.390  	typename Inverse::const_iterator it = inverse.find(value);
   1.391 @@ -434,12 +507,14 @@
   1.392        Inverse inverse;
   1.393      };
   1.394  
   1.395 +    // Readers
   1.396  
   1.397      template <typename _Item>    
   1.398      class ReaderBase {
   1.399      public:
   1.400        typedef _Item Item;
   1.401 -      virtual void read(istream& is, const Item& item) = 0;
   1.402 +
   1.403 +      virtual void read(std::istream& is, const Item& item) = 0;
   1.404        virtual InverterBase<_Item>* getInverter() = 0;
   1.405      };
   1.406  
   1.407 @@ -458,7 +533,7 @@
   1.408  	: map(_map), reader(_reader) {}
   1.409  
   1.410  
   1.411 -      virtual void read(istream& is, const Item& item) {
   1.412 +      virtual void read(std::istream& is, const Item& item) {
   1.413  	Value value;
   1.414  	reader.read(is, value);
   1.415  	map.set(item, value);
   1.416 @@ -480,7 +555,7 @@
   1.417        Reader reader;
   1.418        SkipReader(const Reader& _reader) : reader(_reader) {}
   1.419  
   1.420 -      virtual void read(istream& is, const Item& item) {
   1.421 +      virtual void read(std::istream& is, const Item& item) {
   1.422  	Value value;
   1.423  	reader.read(is, value);
   1.424        }      
   1.425 @@ -491,10 +566,16 @@
   1.426      };
   1.427  
   1.428  
   1.429 -    typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
   1.430 +    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
   1.431 +    NodeMapReaders node_map_readers;
   1.432 +
   1.433 +    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
   1.434 +    EdgeMapReaders edge_map_readers;
   1.435 +
   1.436 +    typedef std::map<std::string, Node*> NodeReaders;
   1.437      NodeReaders node_readers;
   1.438  
   1.439 -    typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
   1.440 +    typedef std::map<std::string, Edge*> EdgeReaders;
   1.441      EdgeReaders edge_readers;
   1.442  
   1.443      std::istream& is;