|    169  |    181  | 
|    170   // Graph reader |    182   // Graph reader | 
|    171    |    183    | 
|    172   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>  |    184   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>  | 
|    173   class GraphReader { |    185   class GraphReader { | 
|    174  |         | 
|    175   public: |    186   public: | 
|    176      |    187      | 
|    177     typedef _Graph Graph; |    188     typedef _Graph Graph; | 
|    178     typedef typename Graph::Node Node; |    189     typedef typename Graph::Node Node; | 
|    179     typedef typename Graph::Edge Edge; |    190     typedef typename Graph::Edge Edge; | 
|    180  |    191  | 
|    181     typedef _ReaderTraits ReaderTraits; |    192     typedef _ReaderTraits ReaderTraits; | 
|    182     typedef typename ReaderTraits::DefaultReader DefaultReader; |    193     typedef typename ReaderTraits::DefaultReader DefaultReader; | 
|    183  |    194  | 
|    184     GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader())  |    195     GraphReader(std::istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader())  | 
|    185       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |    196       : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} | 
|    186  |    197  | 
|    187  |    198  | 
|    188     ~GraphReader() { |    199     ~GraphReader() { | 
|    189  |    200  | 
|    190       for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) { |    201       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); it != node_map_readers.end(); ++it) { | 
|    191 	delete it->second; |    202 	delete it->second; | 
|    192       } |    203       } | 
|    193  |    204  | 
|    194       for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) { |    205       for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); it != edge_map_readers.end(); ++it) { | 
|    195 	delete it->second; |    206 	delete it->second; | 
|    196       } |    207       } | 
|    197  |    208  | 
|    198     } |    209     } | 
|         |    210  | 
|         |    211     // Node map rules | 
|    199  |    212  | 
|    200     template <typename Map> |    213     template <typename Map> | 
|    201     GraphReader& readNodeMap(std::string name, Map& map) { |    214     GraphReader& readNodeMap(std::string name, Map& map) { | 
|    202       return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |    215       return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); | 
|    203     } |    216     } | 
|    204  |    217  | 
|    205     template <typename Reader, typename Map> |    218     template <typename Reader, typename Map> | 
|    206     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |    219     GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { | 
|    207       if (node_readers.find(name) != node_readers.end()) { |    220       if (node_map_readers.find(name) != node_map_readers.end()) { | 
|    208 	Exception e; |    221 	throw Exception() << "Multiple read rule for node map: " << name; | 
|    209 	e << "Multiple read rule for node map: " << name; |    222       } | 
|    210 	throw e; |    223       node_map_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); | 
|    211       } |         | 
|    212       node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |         | 
|    213       return *this; |    224       return *this; | 
|    214     } |    225     } | 
|    215  |    226  | 
|    216     template <typename Reader> |    227     template <typename Reader> | 
|    217     GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { |    228     GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { | 
|    218       if (node_readers.find(name) != node_readers.end()) { |    229       if (node_map_readers.find(name) != node_map_readers.end()) { | 
|    219 	Exception e; |    230 	throw Exception() << "Multiple read rule for node map: " << name; | 
|    220 	e << "Multiple read rule for node map: " << name; |    231       } | 
|    221 	throw e; |    232       node_map_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); | 
|    222       } |         | 
|    223       node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |         | 
|    224       return *this; |    233       return *this; | 
|    225     } |    234     } | 
|         |    235  | 
|         |    236     // Edge map rules | 
|    226  |    237  | 
|    227     template <typename Map> |    238     template <typename Map> | 
|    228     GraphReader& readEdgeMap(std::string name, Map& map) {  |    239     GraphReader& readEdgeMap(std::string name, Map& map) {  | 
|    229       return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |    240       return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); | 
|    230     } |    241     } | 
|    231  |    242  | 
|    232  |    243  | 
|    233     template <typename Reader, typename Map> |    244     template <typename Reader, typename Map> | 
|    234     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |    245     GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { | 
|    235       if (edge_readers.find(name) != edge_readers.end()) { |    246       if (edge_map_readers.find(name) != edge_map_readers.end()) { | 
|    236 	Exception e; |    247 	throw Exception() << "Multiple read rule for edge map: " << name; | 
|    237 	e << "Multiple read rule for edge map: " << name; |    248       } | 
|    238 	throw e; |    249       edge_map_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); | 
|    239       } |         | 
|    240       edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |         | 
|    241       return *this; |    250       return *this; | 
|    242     } |    251     } | 
|    243  |    252  | 
|    244     template <typename Reader> |    253     template <typename Reader> | 
|    245     GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { |    254     GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { | 
|         |    255       if (edge_map_readers.find(name) != edge_map_readers.end()) { | 
|         |    256 	throw Exception() << "Multiple read rule for edge map: " << name; | 
|         |    257       } | 
|         |    258       edge_map_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); | 
|         |    259       return *this; | 
|         |    260     } | 
|         |    261  | 
|         |    262     // Node rules | 
|         |    263     GraphReader& readNode(std::string name, Node& node) { | 
|         |    264       if (node_readers.find(name) != node_readers.end()) { | 
|         |    265 	throw Exception() << "Multiple read rule for node"; | 
|         |    266       } | 
|         |    267       node_readers.insert(make_pair(name, &node)); | 
|         |    268     } | 
|         |    269  | 
|         |    270     // Edge rules | 
|         |    271  | 
|         |    272     GraphReader& readEdge(std::string name, Edge& edge) { | 
|    246       if (edge_readers.find(name) != edge_readers.end()) { |    273       if (edge_readers.find(name) != edge_readers.end()) { | 
|    247 	Exception e; |    274 	throw Exception() << "Multiple read rule for edge"; | 
|    248 	e << "Multiple read rule for edge map: " << name; |    275       } | 
|    249 	throw e; |    276       edge_readers.insert(make_pair(name, &edge)); | 
|    250       } |         | 
|    251       edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |         | 
|    252       return *this; |         | 
|    253     } |    277     } | 
|    254  |    278  | 
|    255     void read() { |    279     void read() { | 
|    256       int line_num = 0; |    280       int line_num = 0; | 
|    257       InverterBase<Node>* nodeInverter = 0; |    281       std::auto_ptr<InverterBase<Node> > nodeInverter; | 
|    258       InverterBase<Edge>* edgeInverter = 0; |    282       std::auto_ptr<InverterBase<Edge> > edgeInverter; | 
|    259       // \todo delete the inverters |    283       try { | 
|    260       //      try { |    284 	std::string line = readNotEmptyLine(is, line_num); | 
|    261 	{ |    285 	if (line.find("@nodeset") == 0) { | 
|    262 	  std::string line = readNotEmptyLine(is, line_num); |    286 	  line = readNodeSet(line_num, nodeInverter); | 
|    263 	} |    287 	}  | 
|    264 	readNodeSet(line_num, nodeInverter); |    288 	if (line.find("@edgeset") == 0) { | 
|    265 	readEdgeSet(line_num, edgeInverter, nodeInverter); |    289 	  line = readEdgeSet(line_num, edgeInverter, nodeInverter); | 
|    266 	//      } catch (...){ |    290 	} | 
|    267 	if (nodeInverter != 0) delete nodeInverter; |    291 	if (line.find("@nodes") == 0) { | 
|    268 	if (edgeInverter != 0) delete edgeInverter; |    292 	  line = readNodes(line_num, nodeInverter); | 
|    269 	//      } |    293 	} | 
|         |    294 	if (line.find("@edges") == 0) { | 
|         |    295 	  line = readEdges(line_num, edgeInverter); | 
|         |    296 	} | 
|         |    297 	if (line.find("@end") != 0) { | 
|         |    298 	  throw DataFormatException("Invalid control sequence: " + line); | 
|         |    299 	} | 
|         |    300       } catch (DataFormatException e) { | 
|         |    301 	throw StreamException<DataFormatException>(line_num, e); | 
|         |    302       } | 
|    270     } |    303     } | 
|    271  |    304  | 
|    272   private: |    305   private: | 
|    273  |    306  | 
|    274     template <typename Item> class InverterBase; |    307     template <typename Item> class InverterBase; | 
|    275     //    template <typename Item> class InverterBase; |    308  | 
|    276  |    309     std::string readNodeSet(int& line_num, auto_ptr<InverterBase<Node> > & nodeInverter) { | 
|    277     void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) { |    310       std::vector<ReaderBase<Node>* > index; | 
|    278       int n = 0; |         | 
|    279       std::vector<ReaderBase<Node>*> index; |         | 
|    280       { |    311       { | 
|    281 	std::string line = readNotEmptyLine(is, line_num);     |    312 	std::string line = readNotEmptyLine(is, line_num);     | 
|    282 	std::string id; |    313 	std::string id; | 
|    283 	std::istringstream ls(line);	 |    314 	std::istringstream ls(line);	 | 
|    284 	while (ls >> id) { |    315 	while (ls >> id) { | 
|    285 	  if (id[0] == '#') break; |    316 	  if (id[0] == '#') break; | 
|    286 	  typename NodeReaders::iterator it = node_readers.find(id); |    317 	  typename NodeMapReaders::iterator it = node_map_readers.find(id); | 
|    287 	  if (it != node_readers.end()) { |    318 	  if (it != node_map_readers.end()) { | 
|    288 	    index.push_back(it->second); |    319 	    index.push_back(it->second); | 
|         |    320 	    node_map_readers.erase(it); | 
|    289 	  } else { |    321 	  } else { | 
|    290 	    index.push_back(&nodeSkipper); |    322 	    index.push_back(&nodeSkipper); | 
|    291 	  } |    323 	  } | 
|    292 	  ++n; |    324 	} | 
|    293 	} |    325       } | 
|    294       } |    326  | 
|    295  |    327       if (index.size() == 0) { | 
|    296       nodeInverter = index[0]->getInverter(); |    328 	throw DataFormatException("No node map found"); | 
|         |    329       } | 
|         |    330  | 
|         |    331       nodeInverter = auto_ptr<InverterBase<Node> >(index[0]->getInverter()); | 
|    297       std::string line; |    332       std::string line; | 
|    298       while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |    333       while (line = readNotEmptyLine(is, line_num), line[0] != '@') { | 
|    299 	Node node = graph.addNode(); |    334 	Node node = graph.addNode(); | 
|    300 	std::istringstream ls(line); |    335 	std::istringstream ls(line); | 
|    301 	nodeInverter->read(ls, node); |    336 	nodeInverter->read(ls, node); | 
|    302 	for (int i = 1; i < n; ++i) { |    337 	for (int i = 1; i < index.size(); ++i) { | 
|    303 	  index[i]->read(ls, node); |    338 	  index[i]->read(ls, node); | 
|    304 	} |    339 	} | 
|    305       } |    340       } | 
|    306     } |    341       return line; | 
|    307  |    342     } | 
|    308     void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) { |    343  | 
|    309       int n = 0; |    344     std::string readEdgeSet(int& line_num,  | 
|         |    345 		     auto_ptr<InverterBase<Edge> > & edgeInverter, auto_ptr<InverterBase<Node> > & nodeInverter) { | 
|    310       std::vector<ReaderBase<Edge>*> index; |    346       std::vector<ReaderBase<Edge>*> index; | 
|    311       { |    347       { | 
|    312 	std::string line = readNotEmptyLine(is, line_num);     |    348 	std::string line = readNotEmptyLine(is, line_num);     | 
|    313 	std::string id; |    349 	std::string id; | 
|    314 	std::istringstream ls(line);	 |    350 	std::istringstream ls(line);	 | 
|    315 	while (ls >> id) { |    351 	while (ls >> id) { | 
|    316 	  if (id[0] == '#') break; |    352 	  if (id[0] == '#') break; | 
|    317 	  typename EdgeReaders::iterator it = edge_readers.find(id); |    353 	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id); | 
|    318 	  if (it != edge_readers.end()) { |    354 	  if (it != edge_map_readers.end()) { | 
|    319 	    index.push_back(it->second); |    355 	    index.push_back(it->second); | 
|         |    356 	    edge_map_readers.erase(it); | 
|    320 	  } else { |    357 	  } else { | 
|    321 	    index.push_back(&edgeSkipper); |    358 	    index.push_back(&edgeSkipper); | 
|    322 	  } |    359 	  } | 
|    323 	  ++n; |    360 	} | 
|    324 	} |    361       } | 
|    325       } |    362  | 
|    326       edgeInverter = index[0]->getInverter(); |    363       if (index.size() == 0) { | 
|         |    364 	throw DataFormatException("No edge map found"); | 
|         |    365       } | 
|         |    366  | 
|         |    367       edgeInverter = auto_ptr<InverterBase<Edge> >(index[0]->getInverter()); | 
|    327       std::string line; |    368       std::string line; | 
|    328       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	 |    369       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	 | 
|    329 	std::istringstream ls(line); |    370 	std::istringstream ls(line); | 
|    330 	Node source = nodeInverter->read(ls); |    371 	Node source = nodeInverter->read(ls); | 
|    331 	Node target = nodeInverter->read(ls); |    372 	Node target = nodeInverter->read(ls); | 
|    332 	Edge edge = graph.addEdge(source, target); |    373 	Edge edge = graph.addEdge(source, target); | 
|    333 	edgeInverter->read(ls, edge); |    374 	edgeInverter->read(ls, edge); | 
|    334 	for (int i = 1; i < n; ++i) { |    375 	for (int i = 1; i < index.size(); ++i) { | 
|    335 	  index[i]->read(ls, edge); |    376 	  index[i]->read(ls, edge); | 
|    336 	} |    377 	} | 
|    337       }       |    378       }       | 
|         |    379       return line; | 
|         |    380     } | 
|         |    381  | 
|         |    382     std::string readNodes(int& line_num, auto_ptr<InverterBase<Node> >& nodeInverter) { | 
|         |    383       std::string line; | 
|         |    384       while (line = readNotEmptyLine(is, line_num), line[0] != '@') { | 
|         |    385 	std::istringstream ls(line); | 
|         |    386 	std::string name; | 
|         |    387 	ls >> name; | 
|         |    388 	typename NodeReaders::iterator it = node_readers.find(name); | 
|         |    389 	if (it != node_readers.end()) { | 
|         |    390 	  *(it -> second) = nodeInverter->read(ls); | 
|         |    391 	}  | 
|         |    392       }         | 
|         |    393       return line; | 
|         |    394     } | 
|         |    395  | 
|         |    396     std::string readEdges(int& line_num, auto_ptr<InverterBase<Edge> >& edgeInverter) { | 
|         |    397       std::string line; | 
|         |    398       while (line = readNotEmptyLine(is, line_num), line[0] != '@') { | 
|         |    399 	std::istringstream ls(line); | 
|         |    400 	std::string name; | 
|         |    401 	ls >> name; | 
|         |    402 	typename EdgeReaders::iterator it = edge_readers.find(name); | 
|         |    403 	if (it != edge_readers.end()) { | 
|         |    404 	  *(it -> second) = edgeInverter->read(ls); | 
|         |    405 	}  | 
|         |    406       }         | 
|         |    407       return line;     | 
|    338     } |    408     } | 
|    339  |    409  | 
|    340     std::string readNotEmptyLine(std::istream& is, int& line_num) { |    410     std::string readNotEmptyLine(std::istream& is, int& line_num) { | 
|    341       std::string line; |    411       std::string line; | 
|    342       while (++line_num, getline(is, line)) {	 |    412       while (++line_num, getline(is, line)) {	 | 
|    343 	int vi = line.find_first_not_of(" \t"); |    413 	int vi = line.find_first_not_of(" \t"); | 
|    344 	if (vi != string::npos && line[vi] != '#') { |    414 	if (vi != string::npos && line[vi] != '#') { | 
|    345 	  return line.substr(vi); |    415 	  return line.substr(vi); | 
|    346 	} |    416 	} | 
|    347       } |    417       } | 
|    348       throw Exception(); |    418       throw DataFormatException("End of stream"); | 
|    349     } |    419     } | 
|         |    420      | 
|         |    421     // Inverters store and give back the Item from the id, | 
|         |    422     // and may put the ids into a map. | 
|    350      |    423      | 
|    351     template <typename _Item> |    424     template <typename _Item> | 
|    352     class InverterBase { |    425     class InverterBase { | 
|    353     public: |    426     public: | 
|    354       typedef _Item Item; |    427       typedef _Item Item; | 
|    355       virtual void read(istream&, const Item&) = 0; |    428       virtual void read(std::istream&, const Item&) = 0; | 
|    356       virtual Item read(istream&) = 0; |    429       virtual Item read(std::istream&) = 0; | 
|    357     }; |    430     }; | 
|    358  |    431  | 
|    359     template <typename _Item, typename _Map, typename _Reader> |    432     template <typename _Item, typename _Map, typename _Reader> | 
|    360     class MapReaderInverter : public InverterBase<_Item> { |    433     class MapReaderInverter : public InverterBase<_Item> { | 
|    361     public: |    434     public: |