src/work/deba/graph_reader.h
changeset 1036 2f514b5c7122
parent 1032 9e903d3a1ef6
child 1037 3eaff8d04171
equal deleted inserted replaced
0:c30e1f293bfa 1:b406e0812af4
    14  *
    14  *
    15  */
    15  */
    16 
    16 
    17 ///\ingroup gio
    17 ///\ingroup gio
    18 ///\file
    18 ///\file
    19 ///\brief Map utilities.
    19 ///\brief Graph reader.
    20 
    20 
    21 #include <iostream>
    21 #include <iostream>
    22 #include <sstream>
    22 #include <sstream>
    23 
    23 
    24 #include <map>
    24 #include <map>
    28 
    28 
    29 /// \todo fix exceptions
    29 /// \todo fix exceptions
    30 
    30 
    31 
    31 
    32 namespace lemon {
    32 namespace lemon {
       
    33 
       
    34   // Exceptions
       
    35 
       
    36   class IOException {
       
    37   public:
       
    38     virtual string what() const = 0;
       
    39   };
       
    40 
       
    41   class DataFormatException : public IOException {
       
    42     std::string message;
       
    43   public:
       
    44     DataFormatException(const std::string& _message) 
       
    45       : message(_message) {}
       
    46     std::string what() const {
       
    47       return "DataFormatException: " + message; 
       
    48     }
       
    49   };
       
    50 
       
    51   class StreamException : public IOException {
       
    52   public:
       
    53     virtual int line() = 0;
       
    54   private:
       
    55     IOException* exception;
       
    56     int line_num;
       
    57   };  
       
    58 
       
    59 
       
    60   // Readers and ReaderTraits
    33   
    61   
    34   struct DefaultReaderTraits {
    62   struct DefaultReaderTraits {
    35 
    63 
    36     template <typename _Value>
    64     template <typename _Value>
    37     struct Reader {
    65     struct Reader {
    38       typedef _Value Value;
    66       typedef _Value Value;
    39       void read(std::istream& is, Value& value) {
    67       void read(std::istream& is, Value& value) {
    40 	is >> value;
    68 	if (!(is >> value)) 
    41       }
    69 	  throw DataFormatException("Default Reader format exception");
    42     };
    70       }
    43 
    71     };
    44     template <typename _Value>
    72 
    45     struct Skipper {
    73     typedef Reader<std::string> DefaultReader;
    46       typedef _Value Value;
    74 
    47       void read(std::istream& is) {
       
    48 	Value tmp;
       
    49 	is >> tmp;
       
    50       }      
       
    51     };
       
    52 
       
    53     struct DefaultSkipper {
       
    54       void read(std::istream& is) {
       
    55 	std::string tmp;
       
    56 	is >> tmp;
       
    57       }
       
    58     };
       
    59   };
    75   };
    60 
    76 
    61   class IOException {
    77   class QuotedStringReader {
    62     virtual string message() = 0;
    78   public:
       
    79     typedef std::string Value;
       
    80 
       
    81     QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
       
    82 
       
    83     void read(std::istream& is, std::string& value) {
       
    84       char c;
       
    85       value.clear();
       
    86       is >> ws;
       
    87       if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception");
       
    88       while (is.get(c) && c != '\"') {
       
    89 	if (escaped && c == '\\') {
       
    90 	  value += readEscape(is);
       
    91 	} else {
       
    92 	  value += c;
       
    93 	}
       
    94       }
       
    95       if (!is) throw DataFormatException("Quoted string format exception");
       
    96     }
       
    97 
       
    98   private:
       
    99     
       
   100     static char readEscape(std::istream& is) {
       
   101       char c;
       
   102       switch (is.get(c), c) {
       
   103       case '\\':
       
   104 	return '\\';
       
   105       case '\"':
       
   106 	return '\"';
       
   107       case '\'':
       
   108 	return '\'';
       
   109       case '\?':
       
   110 	return '\?';
       
   111       case 'a':
       
   112 	return '\a';
       
   113       case 'b':
       
   114 	return '\b';
       
   115       case 'f':
       
   116 	return '\f';
       
   117       case 'n':
       
   118 	return '\n';
       
   119       case 'r':
       
   120 	return '\r';
       
   121       case 't':
       
   122 	return '\t';
       
   123       case 'v':
       
   124 	return '\v';
       
   125       case 'x':
       
   126 	{
       
   127 	  int code;
       
   128 	  if (!is.get(c) || !isHex(c)) throw DataFormatException("Escape format exception");
       
   129 	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
       
   130 	  else code = code * 16 + valueHex(c);
       
   131 	  return code;
       
   132 	}
       
   133       default:
       
   134 	{
       
   135 	  int code;
       
   136 	  if (!isOct(c)) throw DataFormatException("Escape format exception");
       
   137 	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
       
   138 	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) is.putback(c);
       
   139 	  else code = code * 8 + valueOct(c);
       
   140 	  return code;
       
   141 	}	      
       
   142       } 
       
   143     }
       
   144 
       
   145     static bool isOct(char c) {
       
   146       return '0' <= c && c <='7'; 
       
   147     }
       
   148     
       
   149     static int valueOct(char c) {
       
   150       return c - '0';
       
   151     }
       
   152 
       
   153    static bool isHex(char c) {
       
   154       return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 
       
   155     }
       
   156     
       
   157     static int valueHex(char c) {
       
   158       if ('0' <= c && c <= '9') return c - '0';
       
   159       if ('a' <= c && c <= 'z') return c - 'a' + 10;
       
   160       return c - 'A' + 10;
       
   161     }
       
   162 
       
   163     bool escaped;
    63   };
   164   };
    64 
   165 
    65   class FileReaderException {
   166 
    66     virtual int getLine() = 0;    
   167 
    67   };
   168 
    68 
   169 
    69   
   170   // Graph reader
    70   
   171   
    71   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   172   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
    72   class GraphReader {
   173   class GraphReader {
    73 
   174 
    74   public:
   175   public:
    76     typedef _Graph Graph;
   177     typedef _Graph Graph;
    77     typedef typename Graph::Node Node;
   178     typedef typename Graph::Node Node;
    78     typedef typename Graph::Edge Edge;
   179     typedef typename Graph::Edge Edge;
    79 
   180 
    80     typedef _ReaderTraits ReaderTraits;
   181     typedef _ReaderTraits ReaderTraits;
    81     
   182     typedef typename ReaderTraits::DefaultReader DefaultReader;
    82 
   183 
    83     GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {}
   184     GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) 
       
   185       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
       
   186 
       
   187 
       
   188     ~GraphReader() {
       
   189 
       
   190       for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) {
       
   191 	delete it->second;
       
   192       }
       
   193 
       
   194       for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) {
       
   195 	delete it->second;
       
   196       }
       
   197 
       
   198     }
    84 
   199 
    85     template <typename Map>
   200     template <typename Map>
    86     GraphReader& readNodeMap(std::string name, Map& map, 
   201     GraphReader& readNodeMap(std::string name, Map& map) {
    87 			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
   202       return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
    88 			     typename ReaderTraits::template Reader<typename Map::Value>()) {
   203     }
    89       return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
   204 
    90     }
   205     template <typename Reader, typename Map>
    91 
       
    92     template <typename Map, typename Reader>
       
    93     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   206     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
       
   207       if (node_readers.find(name) != node_readers.end()) {
       
   208 	Exception e;
       
   209 	e << "Multiple read rule for node map: " << name;
       
   210 	throw e;
       
   211       }
    94       node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
   212       node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
    95       return *this;
   213       return *this;
    96     }
   214     }
    97 
   215 
       
   216     template <typename Reader>
       
   217     GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) {
       
   218       if (node_readers.find(name) != node_readers.end()) {
       
   219 	Exception e;
       
   220 	e << "Multiple read rule for node map: " << name;
       
   221 	throw e;
       
   222       }
       
   223       node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
       
   224       return *this;
       
   225     }
       
   226 
    98     template <typename Map>
   227     template <typename Map>
    99     GraphReader& readEdgeMap(std::string name, Map& map, 
   228     GraphReader& readEdgeMap(std::string name, Map& map) { 
   100 			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
   229       return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map);
   101 			     typename ReaderTraits::template Reader<typename Map::Value>()) {
   230     }
   102       return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
   231 
   103     }
   232 
   104 
   233     template <typename Reader, typename Map>
   105     template <typename Map, typename Reader>
       
   106     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
   234     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
       
   235       if (edge_readers.find(name) != edge_readers.end()) {
       
   236 	Exception e;
       
   237 	e << "Multiple read rule for edge map: " << name;
       
   238 	throw e;
       
   239       }
   107       edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   240       edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
   108       return *this;
   241       return *this;
   109     }
   242     }
   110 
   243 
       
   244     template <typename Reader>
       
   245     GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) {
       
   246       if (edge_readers.find(name) != edge_readers.end()) {
       
   247 	Exception e;
       
   248 	e << "Multiple read rule for edge map: " << name;
       
   249 	throw e;
       
   250       }
       
   251       edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
       
   252       return *this;
       
   253     }
       
   254 
   111     void read() {
   255     void read() {
   112       int line_num = 0;
   256       int line_num = 0;
   113       readNodeSet(line_num);
   257       InverterBase<Node>* nodeInverter = 0;
   114       readEdgeSet(line_num);
   258       InverterBase<Edge>* edgeInverter = 0;
   115       {
   259       // \todo delete the inverters
   116 	std::string line = readNotEmptyLine(is, line_num);
   260       //      try {
   117       }
   261 	{
       
   262 	  std::string line = readNotEmptyLine(is, line_num);
       
   263 	}
       
   264 	readNodeSet(line_num, nodeInverter);
       
   265 	readEdgeSet(line_num, edgeInverter, nodeInverter);
       
   266 	//      } catch (...){
       
   267 	if (nodeInverter != 0) delete nodeInverter;
       
   268 	if (edgeInverter != 0) delete edgeInverter;
       
   269 	//      }
   118     }
   270     }
   119 
   271 
   120   private:
   272   private:
   121 
   273 
   122     void readNodeSet(int& line_num) {
   274     template <typename Item> class InverterBase;
       
   275     //    template <typename Item> class InverterBase;
       
   276 
       
   277     void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) {
   123       int n = 0;
   278       int n = 0;
   124       {
   279       std::vector<ReaderBase<Node>*> index;
   125 	std::string line = readNotEmptyLine(is, line_num);	
       
   126       }
       
   127       std::vector<MapReaderBase<Node>*> index;
       
   128       {
   280       {
   129 	std::string line = readNotEmptyLine(is, line_num);    
   281 	std::string line = readNotEmptyLine(is, line_num);    
   130 	std::string id;
   282 	std::string id;
   131 	std::istringstream ls(line);	
   283 	std::istringstream ls(line);	
   132 	while (ls >> id) {
   284 	while (ls >> id) {
   133 	  typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id);
   285 	  if (id[0] == '#') break;
       
   286 	  typename NodeReaders::iterator it = node_readers.find(id);
   134 	  if (it != node_readers.end()) {
   287 	  if (it != node_readers.end()) {
   135 	    index.push_back(it->second);
   288 	    index.push_back(it->second);
   136 	  } else {
   289 	  } else {
   137 	    index.push_back(0);
   290 	    index.push_back(&nodeSkipper);
   138 	  }
   291 	  }
   139 	  ++n;
   292 	  ++n;
   140 	}
   293 	}
   141       }
   294       }
       
   295 
       
   296       nodeInverter = index[0]->getInverter();
   142       std::string line;
   297       std::string line;
   143       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   298       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
   144 	Node node = graph.addNode();
   299 	Node node = graph.addNode();
   145 	std::istringstream ls(line);
   300 	std::istringstream ls(line);
   146 	for (int i = 0; i < n; ++i) {
   301 	nodeInverter->read(ls, node);
   147 	  if (index[i] != 0) {	    
   302 	for (int i = 1; i < n; ++i) {
   148 	    index[i]->read(ls, node);
   303 	  index[i]->read(ls, node);
       
   304 	}
       
   305       }
       
   306     }
       
   307 
       
   308     void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) {
       
   309       int n = 0;
       
   310       std::vector<ReaderBase<Edge>*> index;
       
   311       {
       
   312 	std::string line = readNotEmptyLine(is, line_num);    
       
   313 	std::string id;
       
   314 	std::istringstream ls(line);	
       
   315 	while (ls >> id) {
       
   316 	  if (id[0] == '#') break;
       
   317 	  typename EdgeReaders::iterator it = edge_readers.find(id);
       
   318 	  if (it != edge_readers.end()) {
       
   319 	    index.push_back(it->second);
   149 	  } else {
   320 	  } else {
   150 	    default_skipper.read(ls);
   321 	    index.push_back(&edgeSkipper);
   151 	  }
   322 	  }
   152 	}
   323 	  ++n;
   153       }
   324 	}
   154     }
   325       }
   155 
   326       edgeInverter = index[0]->getInverter();
   156     void readEdgeSet(int& line_num) {
   327       std::string line;
   157       
   328       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
       
   329 	std::istringstream ls(line);
       
   330 	Node source = nodeInverter->read(ls);
       
   331 	Node target = nodeInverter->read(ls);
       
   332 	Edge edge = graph.addEdge(source, target);
       
   333 	edgeInverter->read(ls, edge);
       
   334 	for (int i = 1; i < n; ++i) {
       
   335 	  index[i]->read(ls, edge);
       
   336 	}
       
   337       }      
   158     }
   338     }
   159 
   339 
   160     std::string readNotEmptyLine(std::istream& is, int& line_num) {
   340     std::string readNotEmptyLine(std::istream& is, int& line_num) {
   161       std::string line;
   341       std::string line;
   162       while (++line_num, getline(is, line)) {	
   342       while (++line_num, getline(is, line)) {	
   166 	}
   346 	}
   167       }
   347       }
   168       throw Exception();
   348       throw Exception();
   169     }
   349     }
   170     
   350     
   171     istream& is;
   351     template <typename _Item>
   172     Graph& graph;
   352     class InverterBase {
   173 
   353     public:
   174     typename ReaderTraits::DefaultSkipper default_skipper;
   354       typedef _Item Item;
       
   355       virtual void read(istream&, const Item&) = 0;
       
   356       virtual Item read(istream&) = 0;
       
   357     };
       
   358 
       
   359     template <typename _Item, typename _Map, typename _Reader>
       
   360     class MapReaderInverter : public InverterBase<_Item> {
       
   361     public:
       
   362       typedef _Item Item;
       
   363       typedef _Reader Reader;
       
   364       typedef typename Reader::Value Value;
       
   365       typedef _Map Map;
       
   366       typedef std::map<Value, Item> Inverse;
       
   367 
       
   368       Map& map;
       
   369       Reader reader;
       
   370       Inverse inverse;
       
   371 
       
   372       MapReaderInverter(Map& _map, const Reader& _reader) 
       
   373 	: map(_map), reader(_reader) {}
       
   374 
       
   375       virtual void read(istream& is, const Item& item) {
       
   376 	Value value;
       
   377 	reader.read(is, value);
       
   378 	map.set(item, value);
       
   379 	typename Inverse::iterator it = inverse.find(value);
       
   380 	if (it == inverse.end()) {
       
   381 	  inverse.insert(make_pair(value, item));
       
   382 	} else {
       
   383 	  throw DataFormatException("Multiple ID occurence");
       
   384 	}
       
   385       }
       
   386 
       
   387       virtual Item read(istream& is) {
       
   388 	Value value;
       
   389 	reader.read(is, value);	
       
   390 	typename Inverse::const_iterator it = inverse.find(value);
       
   391 	if (it != inverse.end()) {
       
   392 	  return it->second;
       
   393 	} else {
       
   394 	  throw DataFormatException("Invalid ID");
       
   395 	}
       
   396       }      
       
   397     };
       
   398 
       
   399     template <typename _Item, typename _Reader>
       
   400     class SkipReaderInverter : public InverterBase<_Item> {
       
   401     public:
       
   402       typedef _Item Item;
       
   403       typedef _Reader Reader;
       
   404       typedef typename Reader::Value Value;
       
   405       typedef std::map<Value, Item> Inverse;
       
   406 
       
   407       Reader reader;
       
   408 
       
   409       SkipReaderInverter(const Reader& _reader) 
       
   410 	: reader(_reader) {}
       
   411 
       
   412       virtual void read(istream& is, const Item& item) {
       
   413 	Value value;
       
   414 	reader.read(is, value);
       
   415 	typename Inverse::iterator it = inverse.find(value);
       
   416 	if (it == inverse.end()) {
       
   417 	  inverse.insert(make_pair(value, item));
       
   418 	} else {
       
   419 	  throw DataFormatException("Multiple ID occurence");
       
   420 	}
       
   421       }
       
   422 
       
   423       virtual Item read(istream& is) {
       
   424 	Value value;
       
   425 	reader.read(is, value);	
       
   426 	typename Inverse::const_iterator it = inverse.find(value);
       
   427 	if (it != inverse.end()) {
       
   428 	  return it->second;
       
   429 	} else {
       
   430 	  throw DataFormatException("Invalid ID");
       
   431 	}
       
   432       }      
       
   433     private:
       
   434       Inverse inverse;
       
   435     };
       
   436 
   175 
   437 
   176     template <typename _Item>    
   438     template <typename _Item>    
   177     class MapReaderBase {
   439     class ReaderBase {
   178     public:
   440     public:
   179       typedef _Item Item;
   441       typedef _Item Item;
   180       virtual void read(istream& is, const Item& item) = 0;
   442       virtual void read(istream& is, const Item& item) = 0;
   181     };
   443       virtual InverterBase<_Item>* getInverter() = 0;
   182     
   444     };
       
   445 
   183     template <typename _Item, typename _Map, typename _Reader>
   446     template <typename _Item, typename _Map, typename _Reader>
   184     class MapReader : public MapReaderBase<_Item> {
   447     class MapReader : public ReaderBase<_Item> {
   185     public:
   448     public:
   186       typedef _Map Map;
   449       typedef _Map Map;
   187       typedef _Reader Reader;
   450       typedef _Reader Reader;
       
   451       typedef typename Reader::Value Value;
   188       typedef _Item Item;
   452       typedef _Item Item;
   189       
   453       
   190       Map& map;
   454       Map& map;
   191       Reader reader;
   455       Reader reader;
   192 
   456 
   193       MapReader(Map& _map, const Reader& _reader) 
   457       MapReader(Map& _map, const Reader& _reader) 
   194 	: map(_map), reader(_reader) {}
   458 	: map(_map), reader(_reader) {}
   195 
   459 
   196 
   460 
   197       virtual void read(istream& is, const Item& item) {
   461       virtual void read(istream& is, const Item& item) {
   198 	typename Reader::Value value;
   462 	Value value;
   199 	reader.read(is, value);
   463 	reader.read(is, value);
   200 	map.set(item, value);
   464 	map.set(item, value);
   201       }
   465       }
   202     };
   466 
   203 
   467       virtual InverterBase<_Item>* getInverter() {
   204     typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders;
   468 	return new MapReaderInverter<Item, Map, Reader>(map, reader);
       
   469       }
       
   470     };
       
   471 
       
   472 
       
   473     template <typename _Item, typename _Reader>
       
   474     class SkipReader : public ReaderBase<_Item> {
       
   475     public:
       
   476       typedef _Reader Reader;
       
   477       typedef typename Reader::Value Value;
       
   478       typedef _Item Item;
       
   479 
       
   480       Reader reader;
       
   481       SkipReader(const Reader& _reader) : reader(_reader) {}
       
   482 
       
   483       virtual void read(istream& is, const Item& item) {
       
   484 	Value value;
       
   485 	reader.read(is, value);
       
   486       }      
       
   487 
       
   488       virtual InverterBase<Item>* getInverter() {
       
   489 	return new SkipReaderInverter<Item, Reader>(reader);
       
   490       }
       
   491     };
       
   492 
       
   493 
       
   494     typedef std::map<std::string, ReaderBase<Node>* > NodeReaders;
   205     NodeReaders node_readers;
   495     NodeReaders node_readers;
   206 
   496 
   207     typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders;
   497     typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders;
   208     EdgeReaders edge_readers;
   498     EdgeReaders edge_readers;
   209 
   499 
       
   500     std::istream& is;
       
   501     Graph& graph;
       
   502 
       
   503     SkipReader<Node, DefaultReader> nodeSkipper;
       
   504     SkipReader<Edge, DefaultReader> edgeSkipper;
       
   505 
   210   };
   506   };
   211 
   507 
   212 }
   508 }