Changeset 209:765619b7cbb2 in lemon-1.2 for lemon/lgf_reader.h
- Timestamp:
- 07/13/08 20:51:02 (17 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_reader.h
r201 r209 1 /* -*- C++-*-1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 * 3 * This file is a part of LEMON, a generic C++ optimization library 3 * This file is a part of LEMON, a generic C++ optimization library. 4 4 * 5 5 * Copyright (C) 2003-2008 … … 47 47 struct DefaultConverter { 48 48 Value operator()(const std::string& str) { 49 50 51 52 53 54 55 56 57 49 std::istringstream is(str); 50 Value value; 51 is >> value; 52 53 char c; 54 if (is >> std::ws >> c) { 55 throw DataFormatError("Remaining characters in token"); 56 } 57 return value; 58 58 } 59 59 }; … … 62 62 struct DefaultConverter<std::string> { 63 63 std::string operator()(const std::string& str) { 64 64 return str; 65 65 } 66 66 }; 67 67 68 template <typename _Item> 68 template <typename _Item> 69 69 class MapStorageBase { 70 70 public: … … 79 79 }; 80 80 81 template <typename _Item, typename _Map, 82 81 template <typename _Item, typename _Map, 82 typename _Converter = DefaultConverter<typename _Map::Value> > 83 83 class MapStorage : public MapStorageBase<_Item> { 84 84 public: … … 86 86 typedef _Converter Converter; 87 87 typedef _Item Item; 88 88 89 89 private: 90 90 Map& _map; … … 92 92 93 93 public: 94 MapStorage(Map& map, const Converter& converter = Converter()) 95 94 MapStorage(Map& map, const Converter& converter = Converter()) 95 : _map(map), _converter(converter) {} 96 96 virtual ~MapStorage() {} 97 97 98 98 virtual void set(const Item& item ,const std::string& value) { 99 99 _map.set(item, _converter(value)); 100 100 } 101 101 }; 102 102 103 template <typename _Graph, bool _dir, typename _Map, 104 103 template <typename _Graph, bool _dir, typename _Map, 104 typename _Converter = DefaultConverter<typename _Map::Value> > 105 105 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { 106 106 public: … … 110 110 typedef typename Graph::Edge Item; 111 111 static const bool dir = _dir; 112 112 113 113 private: 114 114 const Graph& _graph; … … 117 117 118 118 public: 119 GraphArcMapStorage(const Graph& graph, Map& map, 120 const Converter& converter = Converter()) 121 119 GraphArcMapStorage(const Graph& graph, Map& map, 120 const Converter& converter = Converter()) 121 : _graph(graph), _map(map), _converter(converter) {} 122 122 virtual ~GraphArcMapStorage() {} 123 123 124 124 virtual void set(const Item& item ,const std::string& value) { 125 125 _map.set(_graph.direct(item, dir), _converter(value)); 126 126 } 127 127 }; … … 147 147 public: 148 148 ValueStorage(Value& value, const Converter& converter = Converter()) 149 149 : _value(value), _converter(converter) {} 150 150 151 151 virtual void set(const std::string& value) { 152 152 _value = _converter(value); 153 153 } 154 154 }; … … 177 177 const Graph& _graph; 178 178 const std::map<std::string, typename Graph::Edge>& _map; 179 180 GraphArcLookUpConverter(const Graph& graph, 181 182 typename Graph::Edge>& map) 183 184 179 180 GraphArcLookUpConverter(const Graph& graph, 181 const std::map<std::string, 182 typename Graph::Edge>& map) 183 : _graph(graph), _map(map) {} 184 185 185 typename Graph::Arc operator()(const std::string& str) { 186 187 188 189 190 191 192 193 194 186 if (str.empty() || (str[0] != '+' && str[0] != '-')) { 187 throw DataFormatError("Item must start with '+' or '-'"); 188 } 189 typename std::map<std::string, typename Graph::Edge> 190 ::const_iterator it = _map.find(str.substr(1)); 191 if (it == _map.end()) { 192 throw DataFormatError("Item not found"); 193 } 194 return _graph.direct(it->second, str[0] == '+'); 195 195 } 196 196 }; 197 197 198 198 inline bool isWhiteSpace(char c) { 199 return c == ' ' || c == '\t' || c == '\v' || 200 c == '\n' || c == '\r' || c == '\f'; 201 } 202 199 return c == ' ' || c == '\t' || c == '\v' || 200 c == '\n' || c == '\r' || c == '\f'; 201 } 202 203 203 inline bool isOct(char c) { 204 return '0' <= c && c <='7'; 205 } 206 204 return '0' <= c && c <='7'; 205 } 206 207 207 inline int valueOct(char c) { 208 208 LEMON_ASSERT(isOct(c), "The character is not octal."); … … 211 211 212 212 inline bool isHex(char c) { 213 return ('0' <= c && c <= '9') || 214 ('a' <= c && c <= 'z') || 215 ('A' <= c && c <= 'Z'); 216 } 217 213 return ('0' <= c && c <= '9') || 214 ('a' <= c && c <= 'z') || 215 ('A' <= c && c <= 'Z'); 216 } 217 218 218 inline int valueHex(char c) { 219 219 LEMON_ASSERT(isHex(c), "The character is not hexadecimal."); … … 225 225 inline bool isIdentifierFirstChar(char c) { 226 226 return ('a' <= c && c <= 'z') || 227 227 ('A' <= c && c <= 'Z') || c == '_'; 228 228 } 229 229 230 230 inline bool isIdentifierChar(char c) { 231 231 return isIdentifierFirstChar(c) || 232 232 ('0' <= c && c <= '9'); 233 233 } 234 234 … … 236 236 char c; 237 237 if (!is.get(c)) 238 238 throw DataFormatError("Escape format error"); 239 239 240 240 switch (c) { 241 241 case '\\': 242 242 return '\\'; 243 243 case '\"': 244 244 return '\"'; 245 245 case '\'': 246 246 return '\''; 247 247 case '\?': 248 248 return '\?'; 249 249 case 'a': 250 250 return '\a'; 251 251 case 'b': 252 252 return '\b'; 253 253 case 'f': 254 254 return '\f'; 255 255 case 'n': 256 256 return '\n'; 257 257 case 'r': 258 258 return '\r'; 259 259 case 't': 260 260 return '\t'; 261 261 case 'v': 262 262 return '\v'; 263 263 case 'x': 264 265 266 if (!is.get(c) || !isHex(c)) 267 268 269 270 271 264 { 265 int code; 266 if (!is.get(c) || !isHex(c)) 267 throw DataFormatError("Escape format error"); 268 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); 269 else code = code * 16 + valueHex(c); 270 return code; 271 } 272 272 default: 273 274 275 if (!isOct(c)) 276 277 else if (code = valueOct(c), !is.get(c) || !isOct(c)) 278 279 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 280 281 282 283 } 284 } 285 } 286 273 { 274 int code; 275 if (!isOct(c)) 276 throw DataFormatError("Escape format error"); 277 else if (code = valueOct(c), !is.get(c) || !isOct(c)) 278 is.putback(c); 279 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 280 is.putback(c); 281 else code = code * 8 + valueOct(c); 282 return code; 283 } 284 } 285 } 286 287 287 inline std::istream& readToken(std::istream& is, std::string& str) { 288 288 std::ostringstream os; … … 290 290 char c; 291 291 is >> std::ws; 292 293 if (!is.get(c)) 294 292 293 if (!is.get(c)) 294 return is; 295 295 296 296 if (c == '\"') { 297 298 if (c == '\\') 299 300 301 302 if (!is) 303 297 while (is.get(c) && c != '\"') { 298 if (c == '\\') 299 c = readEscape(is); 300 os << c; 301 } 302 if (!is) 303 throw DataFormatError("Quoted format error"); 304 304 } else { 305 306 307 if (c == '\\') 308 309 310 311 312 313 314 315 305 is.putback(c); 306 while (is.get(c) && !isWhiteSpace(c)) { 307 if (c == '\\') 308 c = readEscape(is); 309 os << c; 310 } 311 if (!is) { 312 is.clear(); 313 } else { 314 is.putback(c); 315 } 316 316 } 317 317 str = os.str(); … … 332 332 333 333 public: 334 334 335 335 LineSection(const Functor& functor) : _functor(functor) {} 336 336 virtual ~LineSection() {} 337 337 338 338 virtual void process(std::istream& is, int& line_num) { 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 339 char c; 340 std::string line; 341 while (is.get(c) && c != '@') { 342 if (c == '\n') { 343 ++line_num; 344 } else if (c == '#') { 345 getline(is, line); 346 ++line_num; 347 } else if (!isWhiteSpace(c)) { 348 is.putback(c); 349 getline(is, line); 350 _functor(line); 351 ++line_num; 352 } 353 } 354 if (is) is.putback(c); 355 else if (is.eof()) is.clear(); 356 356 } 357 357 }; … … 364 364 365 365 public: 366 366 367 367 StreamSection(const Functor& functor) : _functor(functor) {} 368 virtual ~StreamSection() {} 368 virtual ~StreamSection() {} 369 369 370 370 virtual void process(std::istream& is, int& line_num) { 371 372 373 374 375 376 377 378 379 380 381 382 383 else if (is.eof()) is.clear(); 371 _functor(is, line_num); 372 char c; 373 std::string line; 374 while (is.get(c) && c != '@') { 375 if (c == '\n') { 376 ++line_num; 377 } else if (!isWhiteSpace(c)) { 378 getline(is, line); 379 ++line_num; 380 } 381 } 382 if (is) is.putback(c); 383 else if (is.eof()) is.clear(); 384 384 } 385 385 }; 386 386 387 387 } 388 388 … … 400 400 401 401 /// \ingroup lemon_io 402 /// 402 /// 403 403 /// \brief \ref lgf-format "LGF" reader for directed graphs 404 404 /// … … 454 454 typedef _Digraph Digraph; 455 455 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); 456 456 457 457 private: 458 458 … … 471 471 typedef std::map<std::string, Arc> ArcIndex; 472 472 ArcIndex _arc_index; 473 474 typedef std::vector<std::pair<std::string, 475 _reader_bits::MapStorageBase<Node>*> > NodeMaps; 476 NodeMaps _node_maps; 473 474 typedef std::vector<std::pair<std::string, 475 _reader_bits::MapStorageBase<Node>*> > NodeMaps; 476 NodeMaps _node_maps; 477 477 478 478 typedef std::vector<std::pair<std::string, … … 480 480 ArcMaps _arc_maps; 481 481 482 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 482 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 483 483 Attributes; 484 484 Attributes _attributes; … … 499 499 /// Construct a directed graph reader, which reads from the given 500 500 /// input stream. 501 DigraphReader(std::istream& is, Digraph& digraph) 501 DigraphReader(std::istream& is, Digraph& digraph) 502 502 : _is(&is), local_is(false), _digraph(digraph), 503 504 503 _use_nodes(false), _use_arcs(false), 504 _skip_nodes(false), _skip_arcs(false) {} 505 505 506 506 /// \brief Constructor … … 508 508 /// Construct a directed graph reader, which reads from the given 509 509 /// file. 510 DigraphReader(const std::string& fn, Digraph& digraph) 510 DigraphReader(const std::string& fn, Digraph& digraph) 511 511 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph), 512 513 514 512 _use_nodes(false), _use_arcs(false), 513 _skip_nodes(false), _skip_arcs(false) {} 514 515 515 /// \brief Constructor 516 516 /// 517 517 /// Construct a directed graph reader, which reads from the given 518 518 /// file. 519 DigraphReader(const char* fn, Digraph& digraph) 519 DigraphReader(const char* fn, Digraph& digraph) 520 520 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph), 521 522 521 _use_nodes(false), _use_arcs(false), 522 _skip_nodes(false), _skip_arcs(false) {} 523 523 524 524 /// \brief Destructor 525 525 ~DigraphReader() { 526 for (typename NodeMaps::iterator it = _node_maps.begin(); 527 528 529 } 530 531 for (typename ArcMaps::iterator it = _arc_maps.begin(); 532 533 534 } 535 536 for (typename Attributes::iterator it = _attributes.begin(); 537 538 526 for (typename NodeMaps::iterator it = _node_maps.begin(); 527 it != _node_maps.end(); ++it) { 528 delete it->second; 529 } 530 531 for (typename ArcMaps::iterator it = _arc_maps.begin(); 532 it != _arc_maps.end(); ++it) { 533 delete it->second; 534 } 535 536 for (typename Attributes::iterator it = _attributes.begin(); 537 it != _attributes.end(); ++it) { 538 delete it->second; 539 539 } 540 540 541 541 if (local_is) { 542 542 delete _is; 543 543 } 544 544 … … 547 547 private: 548 548 549 friend DigraphReader<Digraph> digraphReader<>(std::istream& is, 550 Digraph& digraph); 551 friend DigraphReader<Digraph> digraphReader<>(const std::string& fn, 552 Digraph& digraph); 553 friend DigraphReader<Digraph> digraphReader<>(const char *fn, 554 Digraph& digraph); 555 556 DigraphReader(DigraphReader& other) 549 friend DigraphReader<Digraph> digraphReader<>(std::istream& is, 550 Digraph& digraph); 551 friend DigraphReader<Digraph> digraphReader<>(const std::string& fn, 552 Digraph& digraph); 553 friend DigraphReader<Digraph> digraphReader<>(const char *fn, 554 Digraph& digraph); 555 556 DigraphReader(DigraphReader& other) 557 557 : _is(other._is), local_is(other.local_is), _digraph(other._digraph), 558 559 558 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs), 559 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) { 560 560 561 561 other._is = 0; 562 562 other.local_is = false; 563 563 564 564 _node_index.swap(other._node_index); 565 565 _arc_index.swap(other._arc_index); … … 581 581 /// \name Reading rules 582 582 /// @{ 583 583 584 584 /// \brief Node map reading rule 585 585 /// … … 588 588 DigraphReader& nodeMap(const std::string& caption, Map& map) { 589 589 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 590 _reader_bits::MapStorageBase<Node>* storage = 591 590 _reader_bits::MapStorageBase<Node>* storage = 591 new _reader_bits::MapStorage<Node, Map>(map); 592 592 _node_maps.push_back(std::make_pair(caption, storage)); 593 593 return *this; … … 599 599 /// reader. 600 600 template <typename Map, typename Converter> 601 DigraphReader& nodeMap(const std::string& caption, Map& map, 602 601 DigraphReader& nodeMap(const std::string& caption, Map& map, 602 const Converter& converter = Converter()) { 603 603 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 604 _reader_bits::MapStorageBase<Node>* storage = 605 604 _reader_bits::MapStorageBase<Node>* storage = 605 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); 606 606 _node_maps.push_back(std::make_pair(caption, storage)); 607 607 return *this; … … 614 614 DigraphReader& arcMap(const std::string& caption, Map& map) { 615 615 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 616 _reader_bits::MapStorageBase<Arc>* storage = 617 616 _reader_bits::MapStorageBase<Arc>* storage = 617 new _reader_bits::MapStorage<Arc, Map>(map); 618 618 _arc_maps.push_back(std::make_pair(caption, storage)); 619 619 return *this; … … 625 625 /// reader. 626 626 template <typename Map, typename Converter> 627 DigraphReader& arcMap(const std::string& caption, Map& map, 628 627 DigraphReader& arcMap(const std::string& caption, Map& map, 628 const Converter& converter = Converter()) { 629 629 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 630 _reader_bits::MapStorageBase<Arc>* storage = 631 630 _reader_bits::MapStorageBase<Arc>* storage = 631 new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); 632 632 _arc_maps.push_back(std::make_pair(caption, storage)); 633 633 return *this; … … 639 639 template <typename Value> 640 640 DigraphReader& attribute(const std::string& caption, Value& value) { 641 _reader_bits::ValueStorageBase* storage = 642 641 _reader_bits::ValueStorageBase* storage = 642 new _reader_bits::ValueStorage<Value>(value); 643 643 _attributes.insert(std::make_pair(caption, storage)); 644 644 return *this; … … 650 650 /// reader. 651 651 template <typename Value, typename Converter> 652 DigraphReader& attribute(const std::string& caption, Value& value, 653 654 _reader_bits::ValueStorageBase* storage = 655 652 DigraphReader& attribute(const std::string& caption, Value& value, 653 const Converter& converter = Converter()) { 654 _reader_bits::ValueStorageBase* storage = 655 new _reader_bits::ValueStorage<Value, Converter>(value, converter); 656 656 _attributes.insert(std::make_pair(caption, storage)); 657 657 return *this; … … 664 664 typedef _reader_bits::MapLookUpConverter<Node> Converter; 665 665 Converter converter(_node_index); 666 _reader_bits::ValueStorageBase* storage = 667 666 _reader_bits::ValueStorageBase* storage = 667 new _reader_bits::ValueStorage<Node, Converter>(node, converter); 668 668 _attributes.insert(std::make_pair(caption, storage)); 669 669 return *this; … … 676 676 typedef _reader_bits::MapLookUpConverter<Arc> Converter; 677 677 Converter converter(_arc_index); 678 _reader_bits::ValueStorageBase* storage = 679 678 _reader_bits::ValueStorageBase* storage = 679 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); 680 680 _attributes.insert(std::make_pair(caption, storage)); 681 681 return *this; … … 723 723 DigraphReader& useNodes(const Map& map) { 724 724 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 725 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 725 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 726 726 _use_nodes = true; 727 727 _writer_bits::DefaultConverter<typename Map::Value> converter; 728 728 for (NodeIt n(_digraph); n != INVALID; ++n) { 729 729 _node_index.insert(std::make_pair(converter(map[n]), n)); 730 730 } 731 731 return *this; … … 738 738 /// \c std::string. 739 739 template <typename Map, typename Converter> 740 DigraphReader& useNodes(const Map& map, 741 740 DigraphReader& useNodes(const Map& map, 741 const Converter& converter = Converter()) { 742 742 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 743 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 743 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 744 744 _use_nodes = true; 745 745 for (NodeIt n(_digraph); n != INVALID; ++n) { 746 746 _node_index.insert(std::make_pair(converter(map[n]), n)); 747 747 } 748 748 return *this; … … 760 760 _writer_bits::DefaultConverter<typename Map::Value> converter; 761 761 for (ArcIt a(_digraph); a != INVALID; ++a) { 762 762 _arc_index.insert(std::make_pair(converter(map[a]), a)); 763 763 } 764 764 return *this; … … 771 771 /// \c std::string. 772 772 template <typename Map, typename Converter> 773 DigraphReader& useArcs(const Map& map, 774 773 DigraphReader& useArcs(const Map& map, 774 const Converter& converter = Converter()) { 775 775 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 776 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 776 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 777 777 _use_arcs = true; 778 778 for (ArcIt a(_digraph); a != INVALID; ++a) { 779 779 _arc_index.insert(std::make_pair(converter(map[a]), a)); 780 780 } 781 781 return *this; … … 791 791 /// \c useNodes() should be used to specify the label of the nodes. 792 792 DigraphReader& skipNodes() { 793 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 793 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 794 794 _skip_nodes = true; 795 795 return *this; … … 802 802 /// will not be constructed. 803 803 DigraphReader& skipArcs() { 804 LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 804 LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); 805 805 _skip_arcs = true; 806 806 return *this; … … 814 814 std::string str; 815 815 while(++line_num, std::getline(*_is, str)) { 816 817 818 819 820 821 816 line.clear(); line.str(str); 817 char c; 818 if (line >> std::ws >> c && c != '#') { 819 line.putback(c); 820 return true; 821 } 822 822 } 823 823 return false; … … 827 827 return static_cast<bool>(*_is); 828 828 } 829 829 830 830 void skipSection() { 831 831 char c; 832 832 while (readSuccess() && line >> c && c != '@') { 833 833 readLine(); 834 834 } 835 835 line.putback(c); … … 843 843 char c; 844 844 if (!readLine() || !(line >> c) || c == '@') { 845 846 if (!_node_maps.empty()) 847 848 845 if (readSuccess() && line) line.putback(c); 846 if (!_node_maps.empty()) 847 throw DataFormatError("Cannot find map names"); 848 return; 849 849 } 850 850 line.putback(c); 851 851 852 852 { 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 std::map<std::string, int>::iterator jt = 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 853 std::map<std::string, int> maps; 854 855 std::string map; 856 int index = 0; 857 while (_reader_bits::readToken(line, map)) { 858 if (maps.find(map) != maps.end()) { 859 std::ostringstream msg; 860 msg << "Multiple occurence of node map: " << map; 861 throw DataFormatError(msg.str().c_str()); 862 } 863 maps.insert(std::make_pair(map, index)); 864 ++index; 865 } 866 867 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 868 std::map<std::string, int>::iterator jt = 869 maps.find(_node_maps[i].first); 870 if (jt == maps.end()) { 871 std::ostringstream msg; 872 msg << "Map not found in file: " << _node_maps[i].first; 873 throw DataFormatError(msg.str().c_str()); 874 } 875 map_index[i] = jt->second; 876 } 877 878 { 879 std::map<std::string, int>::iterator jt = maps.find("label"); 880 if (jt != maps.end()) { 881 label_index = jt->second; 882 } else { 883 label_index = -1; 884 } 885 } 886 map_num = maps.size(); 887 887 } 888 888 889 889 while (readLine() && line >> c && c != '@') { 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 if (label_index == -1) 910 911 912 913 914 915 916 throw DataFormatError(msg.str().c_str()); 917 918 919 920 921 922 923 890 line.putback(c); 891 892 std::vector<std::string> tokens(map_num); 893 for (int i = 0; i < map_num; ++i) { 894 if (!_reader_bits::readToken(line, tokens[i])) { 895 std::ostringstream msg; 896 msg << "Column not found (" << i + 1 << ")"; 897 throw DataFormatError(msg.str().c_str()); 898 } 899 } 900 if (line >> std::ws >> c) 901 throw DataFormatError("Extra character on the end of line"); 902 903 Node n; 904 if (!_use_nodes) { 905 n = _digraph.addNode(); 906 if (label_index != -1) 907 _node_index.insert(std::make_pair(tokens[label_index], n)); 908 } else { 909 if (label_index == -1) 910 throw DataFormatError("Label map not found in file"); 911 typename std::map<std::string, Node>::iterator it = 912 _node_index.find(tokens[label_index]); 913 if (it == _node_index.end()) { 914 std::ostringstream msg; 915 msg << "Node with label not found: " << tokens[label_index]; 916 throw DataFormatError(msg.str().c_str()); 917 } 918 n = it->second; 919 } 920 921 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 922 _node_maps[i].second->set(n, tokens[map_index[i]]); 923 } 924 924 925 925 } 926 926 if (readSuccess()) { 927 927 line.putback(c); 928 928 } 929 929 } … … 936 936 char c; 937 937 if (!readLine() || !(line >> c) || c == '@') { 938 939 if (!_arc_maps.empty()) 940 941 938 if (readSuccess() && line) line.putback(c); 939 if (!_arc_maps.empty()) 940 throw DataFormatError("Cannot find map names"); 941 return; 942 942 } 943 943 line.putback(c); 944 944 945 945 { 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 std::map<std::string, int>::iterator jt = 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 946 std::map<std::string, int> maps; 947 948 std::string map; 949 int index = 0; 950 while (_reader_bits::readToken(line, map)) { 951 if (maps.find(map) != maps.end()) { 952 std::ostringstream msg; 953 msg << "Multiple occurence of arc map: " << map; 954 throw DataFormatError(msg.str().c_str()); 955 } 956 maps.insert(std::make_pair(map, index)); 957 ++index; 958 } 959 960 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) { 961 std::map<std::string, int>::iterator jt = 962 maps.find(_arc_maps[i].first); 963 if (jt == maps.end()) { 964 std::ostringstream msg; 965 msg << "Map not found in file: " << _arc_maps[i].first; 966 throw DataFormatError(msg.str().c_str()); 967 } 968 map_index[i] = jt->second; 969 } 970 971 { 972 std::map<std::string, int>::iterator jt = maps.find("label"); 973 if (jt != maps.end()) { 974 label_index = jt->second; 975 } else { 976 label_index = -1; 977 } 978 } 979 map_num = maps.size(); 980 980 } 981 981 982 982 while (readLine() && line >> c && c != '@') { 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 983 line.putback(c); 984 985 std::string source_token; 986 std::string target_token; 987 988 if (!_reader_bits::readToken(line, source_token)) 989 throw DataFormatError("Source not found"); 990 991 if (!_reader_bits::readToken(line, target_token)) 992 throw DataFormatError("Target not found"); 993 994 std::vector<std::string> tokens(map_num); 995 for (int i = 0; i < map_num; ++i) { 996 if (!_reader_bits::readToken(line, tokens[i])) { 997 std::ostringstream msg; 998 msg << "Column not found (" << i + 1 << ")"; 999 throw DataFormatError(msg.str().c_str()); 1000 } 1001 } 1002 if (line >> std::ws >> c) 1003 throw DataFormatError("Extra character on the end of line"); 1004 1005 Arc a; 1006 if (!_use_arcs) { 1007 1007 1008 1008 typename NodeIndex::iterator it; 1009 1009 1010 1010 it = _node_index.find(source_token); 1011 1011 if (it == _node_index.end()) { … … 1017 1017 1018 1018 it = _node_index.find(target_token); 1019 if (it == _node_index.end()) { 1020 std::ostringstream msg; 1019 if (it == _node_index.end()) { 1020 std::ostringstream msg; 1021 1021 msg << "Item not found: " << target_token; 1022 1022 throw DataFormatError(msg.str().c_str()); 1023 } 1024 Node target = it->second; 1025 1026 1027 if (label_index != -1) 1028 1029 1030 if (label_index == -1) 1031 1032 1033 1034 1035 1036 1037 throw DataFormatError(msg.str().c_str()); 1038 1039 1040 1041 1042 1043 1044 1023 } 1024 Node target = it->second; 1025 1026 a = _digraph.addArc(source, target); 1027 if (label_index != -1) 1028 _arc_index.insert(std::make_pair(tokens[label_index], a)); 1029 } else { 1030 if (label_index == -1) 1031 throw DataFormatError("Label map not found in file"); 1032 typename std::map<std::string, Arc>::iterator it = 1033 _arc_index.find(tokens[label_index]); 1034 if (it == _arc_index.end()) { 1035 std::ostringstream msg; 1036 msg << "Arc with label not found: " << tokens[label_index]; 1037 throw DataFormatError(msg.str().c_str()); 1038 } 1039 a = it->second; 1040 } 1041 1042 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) { 1043 _arc_maps[i].second->set(a, tokens[map_index[i]]); 1044 } 1045 1045 1046 1046 } 1047 1047 if (readSuccess()) { 1048 1048 line.putback(c); 1049 1049 } 1050 1050 } … … 1056 1056 char c; 1057 1057 while (readLine() && line >> c && c != '@') { 1058 1059 1060 1061 1062 1063 1064 1065 1066 throw DataFormatError("Extra character on the end of line"); 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1058 line.putback(c); 1059 1060 std::string attr, token; 1061 if (!_reader_bits::readToken(line, attr)) 1062 throw DataFormatError("Attribute name not found"); 1063 if (!_reader_bits::readToken(line, token)) 1064 throw DataFormatError("Attribute value not found"); 1065 if (line >> c) 1066 throw DataFormatError("Extra character on the end of line"); 1067 1068 { 1069 std::set<std::string>::iterator it = read_attr.find(attr); 1070 if (it != read_attr.end()) { 1071 std::ostringstream msg; 1072 msg << "Multiple occurence of attribute " << attr; 1073 throw DataFormatError(msg.str().c_str()); 1074 } 1075 read_attr.insert(attr); 1076 } 1077 1078 { 1079 typename Attributes::iterator it = _attributes.lower_bound(attr); 1080 while (it != _attributes.end() && it->first == attr) { 1081 it->second->set(token); 1082 ++it; 1083 } 1084 } 1085 1085 1086 1086 } 1087 1087 if (readSuccess()) { 1088 1088 line.putback(c); 1089 1089 } 1090 1090 for (typename Attributes::iterator it = _attributes.begin(); 1091 1092 1093 1094 1095 1096 } 1091 it != _attributes.end(); ++it) { 1092 if (read_attr.find(it->first) == read_attr.end()) { 1093 std::ostringstream msg; 1094 msg << "Attribute not found in file: " << it->first; 1095 throw DataFormatError(msg.str().c_str()); 1096 } 1097 1097 } 1098 1098 } … … 1100 1100 public: 1101 1101 1102 /// \name Execution of the reader 1102 /// \name Execution of the reader 1103 1103 /// @{ 1104 1104 … … 1109 1109 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 1110 1110 if (!*_is) { 1111 1112 } 1113 1111 throw DataFormatError("Cannot find file"); 1112 } 1113 1114 1114 bool nodes_done = _skip_nodes; 1115 1115 bool arcs_done = _skip_arcs; 1116 1116 bool attributes_done = false; 1117 1117 1118 line_num = 0; 1118 line_num = 0; 1119 1119 readLine(); 1120 1120 skipSection(); 1121 1121 1122 1122 while (readSuccess()) { 1123 1124 1125 1126 1127 1128 1129 1130 if (line >> c) 1131 1132 1133 1134 1135 1136 1137 1138 } else if ((section == "arcs" || section == "edges") && 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 } 1123 try { 1124 char c; 1125 std::string section, caption; 1126 line >> c; 1127 _reader_bits::readToken(line, section); 1128 _reader_bits::readToken(line, caption); 1129 1130 if (line >> c) 1131 throw DataFormatError("Extra character on the end of line"); 1132 1133 if (section == "nodes" && !nodes_done) { 1134 if (_nodes_caption.empty() || _nodes_caption == caption) { 1135 readNodes(); 1136 nodes_done = true; 1137 } 1138 } else if ((section == "arcs" || section == "edges") && 1139 !arcs_done) { 1140 if (_arcs_caption.empty() || _arcs_caption == caption) { 1141 readArcs(); 1142 arcs_done = true; 1143 } 1144 } else if (section == "attributes" && !attributes_done) { 1145 if (_attributes_caption.empty() || _attributes_caption == caption) { 1146 readAttributes(); 1147 attributes_done = true; 1148 } 1149 } else { 1150 readLine(); 1151 skipSection(); 1152 } 1153 } catch (DataFormatError& error) { 1154 error.line(line_num); 1155 throw; 1156 } 1157 1157 } 1158 1158 1159 1159 if (!nodes_done) { 1160 1160 throw DataFormatError("Section @nodes not found"); 1161 1161 } 1162 1162 1163 1163 if (!arcs_done) { 1164 1164 throw DataFormatError("Section @arcs not found"); 1165 1165 } 1166 1166 1167 1167 if (!attributes_done && !_attributes.empty()) { 1168 1168 throw DataFormatError("Section @attributes not found"); 1169 1169 } 1170 1170 … … 1172 1172 1173 1173 /// @} 1174 1174 1175 1175 }; 1176 1176 1177 1177 /// \brief Return a \ref DigraphReader class 1178 /// 1178 /// 1179 1179 /// This function just returns a \ref DigraphReader class. 1180 1180 /// \relates DigraphReader … … 1186 1186 1187 1187 /// \brief Return a \ref DigraphReader class 1188 /// 1188 /// 1189 1189 /// This function just returns a \ref DigraphReader class. 1190 1190 /// \relates DigraphReader 1191 1191 template <typename Digraph> 1192 DigraphReader<Digraph> digraphReader(const std::string& fn, 1193 1192 DigraphReader<Digraph> digraphReader(const std::string& fn, 1193 Digraph& digraph) { 1194 1194 DigraphReader<Digraph> tmp(fn, digraph); 1195 1195 return tmp; … … 1197 1197 1198 1198 /// \brief Return a \ref DigraphReader class 1199 /// 1199 /// 1200 1200 /// This function just returns a \ref DigraphReader class. 1201 1201 /// \relates DigraphReader … … 1210 1210 1211 1211 template <typename Graph> 1212 GraphReader<Graph> graphReader(std::istream& is, Graph& graph); 1212 GraphReader<Graph> graphReader(std::istream& is, Graph& graph); 1213 1213 1214 1214 template <typename Graph> 1215 GraphReader<Graph> graphReader(const std::string& fn, Graph& graph); 1215 GraphReader<Graph> graphReader(const std::string& fn, Graph& graph); 1216 1216 1217 1217 template <typename Graph> 1218 GraphReader<Graph> graphReader(const char *fn, Graph& graph); 1218 GraphReader<Graph> graphReader(const char *fn, Graph& graph); 1219 1219 1220 1220 /// \ingroup lemon_io 1221 /// 1221 /// 1222 1222 /// \brief \ref lgf-format "LGF" reader for undirected graphs 1223 1223 /// … … 1239 1239 typedef _Graph Graph; 1240 1240 TEMPLATE_GRAPH_TYPEDEFS(Graph); 1241 1241 1242 1242 private: 1243 1243 … … 1255 1255 typedef std::map<std::string, Edge> EdgeIndex; 1256 1256 EdgeIndex _edge_index; 1257 1258 typedef std::vector<std::pair<std::string, 1259 _reader_bits::MapStorageBase<Node>*> > NodeMaps; 1260 NodeMaps _node_maps; 1257 1258 typedef std::vector<std::pair<std::string, 1259 _reader_bits::MapStorageBase<Node>*> > NodeMaps; 1260 NodeMaps _node_maps; 1261 1261 1262 1262 typedef std::vector<std::pair<std::string, … … 1264 1264 EdgeMaps _edge_maps; 1265 1265 1266 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 1266 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 1267 1267 Attributes; 1268 1268 Attributes _attributes; … … 1283 1283 /// Construct an undirected graph reader, which reads from the given 1284 1284 /// input stream. 1285 GraphReader(std::istream& is, Graph& graph) 1285 GraphReader(std::istream& is, Graph& graph) 1286 1286 : _is(&is), local_is(false), _graph(graph), 1287 1288 1287 _use_nodes(false), _use_edges(false), 1288 _skip_nodes(false), _skip_edges(false) {} 1289 1289 1290 1290 /// \brief Constructor … … 1292 1292 /// Construct an undirected graph reader, which reads from the given 1293 1293 /// file. 1294 GraphReader(const std::string& fn, Graph& graph) 1294 GraphReader(const std::string& fn, Graph& graph) 1295 1295 : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph), 1296 1297 1298 1296 _use_nodes(false), _use_edges(false), 1297 _skip_nodes(false), _skip_edges(false) {} 1298 1299 1299 /// \brief Constructor 1300 1300 /// 1301 1301 /// Construct an undirected graph reader, which reads from the given 1302 1302 /// file. 1303 GraphReader(const char* fn, Graph& graph) 1303 GraphReader(const char* fn, Graph& graph) 1304 1304 : _is(new std::ifstream(fn)), local_is(true), _graph(graph), 1305 1306 1305 _use_nodes(false), _use_edges(false), 1306 _skip_nodes(false), _skip_edges(false) {} 1307 1307 1308 1308 /// \brief Destructor 1309 1309 ~GraphReader() { 1310 for (typename NodeMaps::iterator it = _node_maps.begin(); 1311 1312 1313 } 1314 1315 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1316 1317 1318 } 1319 1320 for (typename Attributes::iterator it = _attributes.begin(); 1321 1322 1310 for (typename NodeMaps::iterator it = _node_maps.begin(); 1311 it != _node_maps.end(); ++it) { 1312 delete it->second; 1313 } 1314 1315 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1316 it != _edge_maps.end(); ++it) { 1317 delete it->second; 1318 } 1319 1320 for (typename Attributes::iterator it = _attributes.begin(); 1321 it != _attributes.end(); ++it) { 1322 delete it->second; 1323 1323 } 1324 1324 1325 1325 if (local_is) { 1326 1326 delete _is; 1327 1327 } 1328 1328 … … 1330 1330 1331 1331 private: 1332 friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph); 1333 friend GraphReader<Graph> graphReader<>(const std::string& fn, 1334 Graph& graph); 1335 friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph); 1336 1337 GraphReader(GraphReader& other) 1332 friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph); 1333 friend GraphReader<Graph> graphReader<>(const std::string& fn, 1334 Graph& graph); 1335 friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph); 1336 1337 GraphReader(GraphReader& other) 1338 1338 : _is(other._is), local_is(other.local_is), _graph(other._graph), 1339 1340 1339 _use_nodes(other._use_nodes), _use_edges(other._use_edges), 1340 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 1341 1341 1342 1342 other._is = 0; 1343 1343 other.local_is = false; 1344 1344 1345 1345 _node_index.swap(other._node_index); 1346 1346 _edge_index.swap(other._edge_index); … … 1362 1362 /// \name Reading rules 1363 1363 /// @{ 1364 1364 1365 1365 /// \brief Node map reading rule 1366 1366 /// … … 1369 1369 GraphReader& nodeMap(const std::string& caption, Map& map) { 1370 1370 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 1371 _reader_bits::MapStorageBase<Node>* storage = 1372 1371 _reader_bits::MapStorageBase<Node>* storage = 1372 new _reader_bits::MapStorage<Node, Map>(map); 1373 1373 _node_maps.push_back(std::make_pair(caption, storage)); 1374 1374 return *this; … … 1380 1380 /// reader. 1381 1381 template <typename Map, typename Converter> 1382 GraphReader& nodeMap(const std::string& caption, Map& map, 1383 1382 GraphReader& nodeMap(const std::string& caption, Map& map, 1383 const Converter& converter = Converter()) { 1384 1384 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); 1385 _reader_bits::MapStorageBase<Node>* storage = 1386 1385 _reader_bits::MapStorageBase<Node>* storage = 1386 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); 1387 1387 _node_maps.push_back(std::make_pair(caption, storage)); 1388 1388 return *this; … … 1395 1395 GraphReader& edgeMap(const std::string& caption, Map& map) { 1396 1396 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 1397 _reader_bits::MapStorageBase<Edge>* storage = 1398 1397 _reader_bits::MapStorageBase<Edge>* storage = 1398 new _reader_bits::MapStorage<Edge, Map>(map); 1399 1399 _edge_maps.push_back(std::make_pair(caption, storage)); 1400 1400 return *this; … … 1406 1406 /// reader. 1407 1407 template <typename Map, typename Converter> 1408 GraphReader& edgeMap(const std::string& caption, Map& map, 1409 1408 GraphReader& edgeMap(const std::string& caption, Map& map, 1409 const Converter& converter = Converter()) { 1410 1410 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); 1411 _reader_bits::MapStorageBase<Edge>* storage = 1412 1411 _reader_bits::MapStorageBase<Edge>* storage = 1412 new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter); 1413 1413 _edge_maps.push_back(std::make_pair(caption, storage)); 1414 1414 return *this; … … 1421 1421 GraphReader& arcMap(const std::string& caption, Map& map) { 1422 1422 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 1423 _reader_bits::MapStorageBase<Edge>* forward_storage = 1424 1423 _reader_bits::MapStorageBase<Edge>* forward_storage = 1424 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 1425 1425 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1426 _reader_bits::MapStorageBase<Edge>* backward_storage = 1427 1426 _reader_bits::MapStorageBase<Edge>* backward_storage = 1427 new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); 1428 1428 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1429 1429 return *this; … … 1435 1435 /// reader. 1436 1436 template <typename Map, typename Converter> 1437 GraphReader& arcMap(const std::string& caption, Map& map, 1438 1437 GraphReader& arcMap(const std::string& caption, Map& map, 1438 const Converter& converter = Converter()) { 1439 1439 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); 1440 _reader_bits::MapStorageBase<Edge>* forward_storage = 1441 1442 1440 _reader_bits::MapStorageBase<Edge>* forward_storage = 1441 new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter> 1442 (_graph, map, converter); 1443 1443 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1444 _reader_bits::MapStorageBase<Edge>* backward_storage = 1445 1446 1444 _reader_bits::MapStorageBase<Edge>* backward_storage = 1445 new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter> 1446 (_graph, map, converter); 1447 1447 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1448 1448 return *this; … … 1454 1454 template <typename Value> 1455 1455 GraphReader& attribute(const std::string& caption, Value& value) { 1456 _reader_bits::ValueStorageBase* storage = 1457 1456 _reader_bits::ValueStorageBase* storage = 1457 new _reader_bits::ValueStorage<Value>(value); 1458 1458 _attributes.insert(std::make_pair(caption, storage)); 1459 1459 return *this; … … 1465 1465 /// reader. 1466 1466 template <typename Value, typename Converter> 1467 GraphReader& attribute(const std::string& caption, Value& value, 1468 1469 _reader_bits::ValueStorageBase* storage = 1470 1467 GraphReader& attribute(const std::string& caption, Value& value, 1468 const Converter& converter = Converter()) { 1469 _reader_bits::ValueStorageBase* storage = 1470 new _reader_bits::ValueStorage<Value, Converter>(value, converter); 1471 1471 _attributes.insert(std::make_pair(caption, storage)); 1472 1472 return *this; … … 1479 1479 typedef _reader_bits::MapLookUpConverter<Node> Converter; 1480 1480 Converter converter(_node_index); 1481 _reader_bits::ValueStorageBase* storage = 1482 1481 _reader_bits::ValueStorageBase* storage = 1482 new _reader_bits::ValueStorage<Node, Converter>(node, converter); 1483 1483 _attributes.insert(std::make_pair(caption, storage)); 1484 1484 return *this; … … 1491 1491 typedef _reader_bits::MapLookUpConverter<Edge> Converter; 1492 1492 Converter converter(_edge_index); 1493 _reader_bits::ValueStorageBase* storage = 1494 1493 _reader_bits::ValueStorageBase* storage = 1494 new _reader_bits::ValueStorage<Edge, Converter>(edge, converter); 1495 1495 _attributes.insert(std::make_pair(caption, storage)); 1496 1496 return *this; … … 1503 1503 typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter; 1504 1504 Converter converter(_graph, _edge_index); 1505 _reader_bits::ValueStorageBase* storage = 1506 1505 _reader_bits::ValueStorageBase* storage = 1506 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); 1507 1507 _attributes.insert(std::make_pair(caption, storage)); 1508 1508 return *this; … … 1550 1550 GraphReader& useNodes(const Map& map) { 1551 1551 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1552 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1552 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1553 1553 _use_nodes = true; 1554 1554 _writer_bits::DefaultConverter<typename Map::Value> converter; 1555 1555 for (NodeIt n(_graph); n != INVALID; ++n) { 1556 1556 _node_index.insert(std::make_pair(converter(map[n]), n)); 1557 1557 } 1558 1558 return *this; … … 1565 1565 /// \c std::string. 1566 1566 template <typename Map, typename Converter> 1567 GraphReader& useNodes(const Map& map, 1568 1567 GraphReader& useNodes(const Map& map, 1568 const Converter& converter = Converter()) { 1569 1569 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1570 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1570 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 1571 1571 _use_nodes = true; 1572 1572 for (NodeIt n(_graph); n != INVALID; ++n) { 1573 1573 _node_index.insert(std::make_pair(converter(map[n]), n)); 1574 1574 } 1575 1575 return *this; … … 1587 1587 _writer_bits::DefaultConverter<typename Map::Value> converter; 1588 1588 for (EdgeIt a(_graph); a != INVALID; ++a) { 1589 1589 _edge_index.insert(std::make_pair(converter(map[a]), a)); 1590 1590 } 1591 1591 return *this; … … 1598 1598 /// \c std::string. 1599 1599 template <typename Map, typename Converter> 1600 GraphReader& useEdges(const Map& map, 1601 1600 GraphReader& useEdges(const Map& map, 1601 const Converter& converter = Converter()) { 1602 1602 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1603 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 1603 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 1604 1604 _use_edges = true; 1605 1605 for (EdgeIt a(_graph); a != INVALID; ++a) { 1606 1606 _edge_index.insert(std::make_pair(converter(map[a]), a)); 1607 1607 } 1608 1608 return *this; … … 1619 1619 /// \c useNodes() should be used to specify the label of the nodes. 1620 1620 GraphReader& skipNodes() { 1621 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 1621 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); 1622 1622 _skip_nodes = true; 1623 1623 return *this; … … 1630 1630 /// will not be constructed. 1631 1631 GraphReader& skipEdges() { 1632 LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 1632 LEMON_ASSERT(!_skip_edges, "Skip edges already set"); 1633 1633 _skip_edges = true; 1634 1634 return *this; … … 1642 1642 std::string str; 1643 1643 while(++line_num, std::getline(*_is, str)) { 1644 1645 1646 1647 1648 1649 1644 line.clear(); line.str(str); 1645 char c; 1646 if (line >> std::ws >> c && c != '#') { 1647 line.putback(c); 1648 return true; 1649 } 1650 1650 } 1651 1651 return false; … … 1655 1655 return static_cast<bool>(*_is); 1656 1656 } 1657 1657 1658 1658 void skipSection() { 1659 1659 char c; 1660 1660 while (readSuccess() && line >> c && c != '@') { 1661 1661 readLine(); 1662 1662 } 1663 1663 line.putback(c); … … 1671 1671 char c; 1672 1672 if (!readLine() || !(line >> c) || c == '@') { 1673 1674 if (!_node_maps.empty()) 1675 1676 1673 if (readSuccess() && line) line.putback(c); 1674 if (!_node_maps.empty()) 1675 throw DataFormatError("Cannot find map names"); 1676 return; 1677 1677 } 1678 1678 line.putback(c); 1679 1679 1680 1680 { 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 std::map<std::string, int>::iterator jt = 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1681 std::map<std::string, int> maps; 1682 1683 std::string map; 1684 int index = 0; 1685 while (_reader_bits::readToken(line, map)) { 1686 if (maps.find(map) != maps.end()) { 1687 std::ostringstream msg; 1688 msg << "Multiple occurence of node map: " << map; 1689 throw DataFormatError(msg.str().c_str()); 1690 } 1691 maps.insert(std::make_pair(map, index)); 1692 ++index; 1693 } 1694 1695 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 1696 std::map<std::string, int>::iterator jt = 1697 maps.find(_node_maps[i].first); 1698 if (jt == maps.end()) { 1699 std::ostringstream msg; 1700 msg << "Map not found in file: " << _node_maps[i].first; 1701 throw DataFormatError(msg.str().c_str()); 1702 } 1703 map_index[i] = jt->second; 1704 } 1705 1706 { 1707 std::map<std::string, int>::iterator jt = maps.find("label"); 1708 if (jt != maps.end()) { 1709 label_index = jt->second; 1710 } else { 1711 label_index = -1; 1712 } 1713 } 1714 map_num = maps.size(); 1715 1715 } 1716 1716 1717 1717 while (readLine() && line >> c && c != '@') { 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 if (label_index != -1) 1735 1736 1737 if (label_index == -1) 1738 1739 1740 1741 1742 1743 1744 throw DataFormatError(msg.str().c_str()); 1745 1746 1747 1748 1749 1750 1751 1718 line.putback(c); 1719 1720 std::vector<std::string> tokens(map_num); 1721 for (int i = 0; i < map_num; ++i) { 1722 if (!_reader_bits::readToken(line, tokens[i])) { 1723 std::ostringstream msg; 1724 msg << "Column not found (" << i + 1 << ")"; 1725 throw DataFormatError(msg.str().c_str()); 1726 } 1727 } 1728 if (line >> std::ws >> c) 1729 throw DataFormatError("Extra character on the end of line"); 1730 1731 Node n; 1732 if (!_use_nodes) { 1733 n = _graph.addNode(); 1734 if (label_index != -1) 1735 _node_index.insert(std::make_pair(tokens[label_index], n)); 1736 } else { 1737 if (label_index == -1) 1738 throw DataFormatError("Label map not found in file"); 1739 typename std::map<std::string, Node>::iterator it = 1740 _node_index.find(tokens[label_index]); 1741 if (it == _node_index.end()) { 1742 std::ostringstream msg; 1743 msg << "Node with label not found: " << tokens[label_index]; 1744 throw DataFormatError(msg.str().c_str()); 1745 } 1746 n = it->second; 1747 } 1748 1749 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { 1750 _node_maps[i].second->set(n, tokens[map_index[i]]); 1751 } 1752 1752 1753 1753 } 1754 1754 if (readSuccess()) { 1755 1755 line.putback(c); 1756 1756 } 1757 1757 } … … 1764 1764 char c; 1765 1765 if (!readLine() || !(line >> c) || c == '@') { 1766 1767 if (!_edge_maps.empty()) 1768 1769 1766 if (readSuccess() && line) line.putback(c); 1767 if (!_edge_maps.empty()) 1768 throw DataFormatError("Cannot find map names"); 1769 return; 1770 1770 } 1771 1771 line.putback(c); 1772 1772 1773 1773 { 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 std::map<std::string, int>::iterator jt = 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1774 std::map<std::string, int> maps; 1775 1776 std::string map; 1777 int index = 0; 1778 while (_reader_bits::readToken(line, map)) { 1779 if (maps.find(map) != maps.end()) { 1780 std::ostringstream msg; 1781 msg << "Multiple occurence of edge map: " << map; 1782 throw DataFormatError(msg.str().c_str()); 1783 } 1784 maps.insert(std::make_pair(map, index)); 1785 ++index; 1786 } 1787 1788 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 1789 std::map<std::string, int>::iterator jt = 1790 maps.find(_edge_maps[i].first); 1791 if (jt == maps.end()) { 1792 std::ostringstream msg; 1793 msg << "Map not found in file: " << _edge_maps[i].first; 1794 throw DataFormatError(msg.str().c_str()); 1795 } 1796 map_index[i] = jt->second; 1797 } 1798 1799 { 1800 std::map<std::string, int>::iterator jt = maps.find("label"); 1801 if (jt != maps.end()) { 1802 label_index = jt->second; 1803 } else { 1804 label_index = -1; 1805 } 1806 } 1807 map_num = maps.size(); 1808 1808 } 1809 1809 1810 1810 while (readLine() && line >> c && c != '@') { 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1811 line.putback(c); 1812 1813 std::string source_token; 1814 std::string target_token; 1815 1816 if (!_reader_bits::readToken(line, source_token)) 1817 throw DataFormatError("Node u not found"); 1818 1819 if (!_reader_bits::readToken(line, target_token)) 1820 throw DataFormatError("Node v not found"); 1821 1822 std::vector<std::string> tokens(map_num); 1823 for (int i = 0; i < map_num; ++i) { 1824 if (!_reader_bits::readToken(line, tokens[i])) { 1825 std::ostringstream msg; 1826 msg << "Column not found (" << i + 1 << ")"; 1827 throw DataFormatError(msg.str().c_str()); 1828 } 1829 } 1830 if (line >> std::ws >> c) 1831 throw DataFormatError("Extra character on the end of line"); 1832 1833 Edge e; 1834 if (!_use_edges) { 1835 1835 1836 1836 typename NodeIndex::iterator it; 1837 1837 1838 1838 it = _node_index.find(source_token); 1839 1839 if (it == _node_index.end()) { … … 1845 1845 1846 1846 it = _node_index.find(target_token); 1847 if (it == _node_index.end()) { 1848 std::ostringstream msg; 1847 if (it == _node_index.end()) { 1848 std::ostringstream msg; 1849 1849 msg << "Item not found: " << target_token; 1850 1850 throw DataFormatError(msg.str().c_str()); 1851 } 1852 Node target = it->second; 1853 1854 1855 if (label_index != -1) 1856 1857 1858 if (label_index == -1) 1859 1860 1861 1862 1863 1864 1865 throw DataFormatError(msg.str().c_str()); 1866 1867 1868 1869 1870 1871 1872 1851 } 1852 Node target = it->second; 1853 1854 e = _graph.addEdge(source, target); 1855 if (label_index != -1) 1856 _edge_index.insert(std::make_pair(tokens[label_index], e)); 1857 } else { 1858 if (label_index == -1) 1859 throw DataFormatError("Label map not found in file"); 1860 typename std::map<std::string, Edge>::iterator it = 1861 _edge_index.find(tokens[label_index]); 1862 if (it == _edge_index.end()) { 1863 std::ostringstream msg; 1864 msg << "Edge with label not found: " << tokens[label_index]; 1865 throw DataFormatError(msg.str().c_str()); 1866 } 1867 e = it->second; 1868 } 1869 1870 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { 1871 _edge_maps[i].second->set(e, tokens[map_index[i]]); 1872 } 1873 1873 1874 1874 } 1875 1875 if (readSuccess()) { 1876 1876 line.putback(c); 1877 1877 } 1878 1878 } … … 1884 1884 char c; 1885 1885 while (readLine() && line >> c && c != '@') { 1886 1887 1888 1889 1890 1891 1892 1893 1894 throw DataFormatError("Extra character on the end of line"); 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1886 line.putback(c); 1887 1888 std::string attr, token; 1889 if (!_reader_bits::readToken(line, attr)) 1890 throw DataFormatError("Attribute name not found"); 1891 if (!_reader_bits::readToken(line, token)) 1892 throw DataFormatError("Attribute value not found"); 1893 if (line >> c) 1894 throw DataFormatError("Extra character on the end of line"); 1895 1896 { 1897 std::set<std::string>::iterator it = read_attr.find(attr); 1898 if (it != read_attr.end()) { 1899 std::ostringstream msg; 1900 msg << "Multiple occurence of attribute " << attr; 1901 throw DataFormatError(msg.str().c_str()); 1902 } 1903 read_attr.insert(attr); 1904 } 1905 1906 { 1907 typename Attributes::iterator it = _attributes.lower_bound(attr); 1908 while (it != _attributes.end() && it->first == attr) { 1909 it->second->set(token); 1910 ++it; 1911 } 1912 } 1913 1913 1914 1914 } 1915 1915 if (readSuccess()) { 1916 1916 line.putback(c); 1917 1917 } 1918 1918 for (typename Attributes::iterator it = _attributes.begin(); 1919 1920 1921 1922 1923 1924 } 1919 it != _attributes.end(); ++it) { 1920 if (read_attr.find(it->first) == read_attr.end()) { 1921 std::ostringstream msg; 1922 msg << "Attribute not found in file: " << it->first; 1923 throw DataFormatError(msg.str().c_str()); 1924 } 1925 1925 } 1926 1926 } … … 1928 1928 public: 1929 1929 1930 /// \name Execution of the reader 1930 /// \name Execution of the reader 1931 1931 /// @{ 1932 1932 … … 1935 1935 /// This function starts the batch processing 1936 1936 void run() { 1937 1937 1938 1938 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 1939 1939 1940 1940 bool nodes_done = _skip_nodes; 1941 1941 bool edges_done = _skip_edges; 1942 1942 bool attributes_done = false; 1943 1943 1944 line_num = 0; 1944 line_num = 0; 1945 1945 readLine(); 1946 1946 skipSection(); 1947 1947 1948 1948 while (readSuccess()) { 1949 1950 1951 1952 1953 1954 1955 1956 if (line >> c) 1957 1958 1959 1960 1961 1962 1963 1964 } else if ((section == "edges" || section == "arcs") && 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 } 1949 try { 1950 char c; 1951 std::string section, caption; 1952 line >> c; 1953 _reader_bits::readToken(line, section); 1954 _reader_bits::readToken(line, caption); 1955 1956 if (line >> c) 1957 throw DataFormatError("Extra character on the end of line"); 1958 1959 if (section == "nodes" && !nodes_done) { 1960 if (_nodes_caption.empty() || _nodes_caption == caption) { 1961 readNodes(); 1962 nodes_done = true; 1963 } 1964 } else if ((section == "edges" || section == "arcs") && 1965 !edges_done) { 1966 if (_edges_caption.empty() || _edges_caption == caption) { 1967 readEdges(); 1968 edges_done = true; 1969 } 1970 } else if (section == "attributes" && !attributes_done) { 1971 if (_attributes_caption.empty() || _attributes_caption == caption) { 1972 readAttributes(); 1973 attributes_done = true; 1974 } 1975 } else { 1976 readLine(); 1977 skipSection(); 1978 } 1979 } catch (DataFormatError& error) { 1980 error.line(line_num); 1981 throw; 1982 } 1983 1983 } 1984 1984 1985 1985 if (!nodes_done) { 1986 1986 throw DataFormatError("Section @nodes not found"); 1987 1987 } 1988 1988 1989 1989 if (!edges_done) { 1990 1990 throw DataFormatError("Section @edges not found"); 1991 1991 } 1992 1992 1993 1993 if (!attributes_done && !_attributes.empty()) { 1994 1994 throw DataFormatError("Section @attributes not found"); 1995 1995 } 1996 1996 … … 1998 1998 1999 1999 /// @} 2000 2000 2001 2001 }; 2002 2002 2003 2003 /// \brief Return a \ref GraphReader class 2004 /// 2004 /// 2005 2005 /// This function just returns a \ref GraphReader class. 2006 2006 /// \relates GraphReader … … 2012 2012 2013 2013 /// \brief Return a \ref GraphReader class 2014 /// 2014 /// 2015 2015 /// This function just returns a \ref GraphReader class. 2016 2016 /// \relates GraphReader 2017 2017 template <typename Graph> 2018 GraphReader<Graph> graphReader(const std::string& fn, 2019 2018 GraphReader<Graph> graphReader(const std::string& fn, 2019 Graph& graph) { 2020 2020 GraphReader<Graph> tmp(fn, graph); 2021 2021 return tmp; … … 2023 2023 2024 2024 /// \brief Return a \ref GraphReader class 2025 /// 2025 /// 2026 2026 /// This function just returns a \ref GraphReader class. 2027 2027 /// \relates GraphReader … … 2037 2037 SectionReader sectionReader(const std::string& fn); 2038 2038 SectionReader sectionReader(const char* fn); 2039 2039 2040 2040 /// \ingroup lemon_io 2041 2041 /// 2042 2042 /// \brief Section reader class 2043 2043 /// 2044 /// In the \ref lgf-format "LGF" file extra sections can be placed, 2044 /// In the \ref lgf-format "LGF" file extra sections can be placed, 2045 2045 /// which contain any data in arbitrary format. Such sections can be 2046 /// read with this class. A reading rule can be added to the class 2046 /// read with this class. A reading rule can be added to the class 2047 2047 /// with two different functions. With the \c sectionLines() function a 2048 2048 /// functor can process the section line-by-line, while with the \c … … 2051 2051 class SectionReader { 2052 2052 private: 2053 2053 2054 2054 std::istream* _is; 2055 2055 bool local_is; … … 2067 2067 /// Construct a section reader, which reads from the given input 2068 2068 /// stream. 2069 SectionReader(std::istream& is) 2069 SectionReader(std::istream& is) 2070 2070 : _is(&is), local_is(false) {} 2071 2071 … … 2073 2073 /// 2074 2074 /// Construct a section reader, which reads from the given file. 2075 SectionReader(const std::string& fn) 2075 SectionReader(const std::string& fn) 2076 2076 : _is(new std::ifstream(fn.c_str())), local_is(true) {} 2077 2077 2078 2078 /// \brief Constructor 2079 2079 /// 2080 2080 /// Construct a section reader, which reads from the given file. 2081 SectionReader(const char* fn) 2081 SectionReader(const char* fn) 2082 2082 : _is(new std::ifstream(fn)), local_is(true) {} 2083 2083 2084 2084 /// \brief Destructor 2085 2085 ~SectionReader() { 2086 for (Sections::iterator it = _sections.begin(); 2087 2088 2086 for (Sections::iterator it = _sections.begin(); 2087 it != _sections.end(); ++it) { 2088 delete it->second; 2089 2089 } 2090 2090 2091 2091 if (local_is) { 2092 2092 delete _is; 2093 2093 } 2094 2094 … … 2101 2101 friend SectionReader sectionReader(const char* fn); 2102 2102 2103 SectionReader(SectionReader& other) 2103 SectionReader(SectionReader& other) 2104 2104 : _is(other._is), local_is(other.local_is) { 2105 2105 2106 2106 other._is = 0; 2107 2107 other.local_is = false; 2108 2108 2109 2109 _sections.swap(other._sections); 2110 2110 } 2111 2111 2112 2112 SectionReader& operator=(const SectionReader&); 2113 2113 … … 2149 2149 /// // ... 2150 2150 /// 2151 /// reader.sectionLines("numbers", NumberSection(vec)); 2151 /// reader.sectionLines("numbers", NumberSection(vec)); 2152 2152 ///\endcode 2153 2153 template <typename Functor> 2154 2154 SectionReader& sectionLines(const std::string& type, Functor functor) { 2155 2155 LEMON_ASSERT(!type.empty(), "Type is empty."); 2156 LEMON_ASSERT(_sections.find(type) == _sections.end(), 2157 2158 _sections.insert(std::make_pair(type, 2156 LEMON_ASSERT(_sections.find(type) == _sections.end(), 2157 "Multiple reading of section."); 2158 _sections.insert(std::make_pair(type, 2159 2159 new _reader_bits::LineSection<Functor>(functor))); 2160 2160 return *this; … … 2172 2172 SectionReader& sectionStream(const std::string& type, Functor functor) { 2173 2173 LEMON_ASSERT(!type.empty(), "Type is empty."); 2174 LEMON_ASSERT(_sections.find(type) == _sections.end(), 2175 2176 _sections.insert(std::make_pair(type, 2177 2178 return *this; 2179 } 2180 2174 LEMON_ASSERT(_sections.find(type) == _sections.end(), 2175 "Multiple reading of section."); 2176 _sections.insert(std::make_pair(type, 2177 new _reader_bits::StreamSection<Functor>(functor))); 2178 return *this; 2179 } 2180 2181 2181 /// @} 2182 2182 … … 2186 2186 std::string str; 2187 2187 while(++line_num, std::getline(*_is, str)) { 2188 2189 2190 2191 2192 2193 2188 line.clear(); line.str(str); 2189 char c; 2190 if (line >> std::ws >> c && c != '#') { 2191 line.putback(c); 2192 return true; 2193 } 2194 2194 } 2195 2195 return false; … … 2199 2199 return static_cast<bool>(*_is); 2200 2200 } 2201 2201 2202 2202 void skipSection() { 2203 2203 char c; 2204 2204 while (readSuccess() && line >> c && c != '@') { 2205 2205 readLine(); 2206 2206 } 2207 2207 line.putback(c); … … 2211 2211 2212 2212 2213 /// \name Execution of the reader 2213 /// \name Execution of the reader 2214 2214 /// @{ 2215 2215 … … 2218 2218 /// This function starts the batch processing. 2219 2219 void run() { 2220 2220 2221 2221 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); 2222 2222 2223 2223 std::set<std::string> extra_sections; 2224 2224 2225 line_num = 0; 2225 line_num = 0; 2226 2226 readLine(); 2227 2227 skipSection(); 2228 2228 2229 2229 while (readSuccess()) { 2230 2231 2232 2233 2234 2235 2236 2237 if (line >> c) 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 } 2230 try { 2231 char c; 2232 std::string section, caption; 2233 line >> c; 2234 _reader_bits::readToken(line, section); 2235 _reader_bits::readToken(line, caption); 2236 2237 if (line >> c) 2238 throw DataFormatError("Extra character on the end of line"); 2239 2240 if (extra_sections.find(section) != extra_sections.end()) { 2241 std::ostringstream msg; 2242 msg << "Multiple occurence of section " << section; 2243 throw DataFormatError(msg.str().c_str()); 2244 } 2245 Sections::iterator it = _sections.find(section); 2246 if (it != _sections.end()) { 2247 extra_sections.insert(section); 2248 it->second->process(*_is, line_num); 2249 } 2250 readLine(); 2251 skipSection(); 2252 } catch (DataFormatError& error) { 2253 error.line(line_num); 2254 throw; 2255 } 2256 2256 } 2257 2257 for (Sections::iterator it = _sections.begin(); 2258 2259 2260 2261 2262 2263 2258 it != _sections.end(); ++it) { 2259 if (extra_sections.find(it->first) == extra_sections.end()) { 2260 std::ostringstream os; 2261 os << "Cannot find section: " << it->first; 2262 throw DataFormatError(os.str().c_str()); 2263 } 2264 2264 } 2265 2265 } 2266 2266 2267 2267 /// @} 2268 2268 2269 2269 }; 2270 2270 2271 2271 /// \brief Return a \ref SectionReader class 2272 /// 2272 /// 2273 2273 /// This function just returns a \ref SectionReader class. 2274 2274 /// \relates SectionReader … … 2279 2279 2280 2280 /// \brief Return a \ref SectionReader class 2281 /// 2281 /// 2282 2282 /// This function just returns a \ref SectionReader class. 2283 2283 /// \relates SectionReader … … 2288 2288 2289 2289 /// \brief Return a \ref SectionReader class 2290 /// 2290 /// 2291 2291 /// This function just returns a \ref SectionReader class. 2292 2292 /// \relates SectionReader … … 2298 2298 /// \ingroup lemon_io 2299 2299 /// 2300 /// \brief Reader for the contents of the \ref lgf-format "LGF" file 2300 /// \brief Reader for the contents of the \ref lgf-format "LGF" file 2301 2301 /// 2302 2302 /// This class can be used to read the sections, the map names and … … 2308 2308 /// reading the graph. 2309 2309 /// 2310 ///\code 2311 /// LgfContents contents("graph.lgf"); 2310 ///\code 2311 /// LgfContents contents("graph.lgf"); 2312 2312 /// contents.run(); 2313 2313 /// … … 2317 2317 /// return -1; 2318 2318 /// } 2319 /// std::cout << "The name of the default node section: " 2319 /// std::cout << "The name of the default node section: " 2320 2320 /// << contents.nodeSection(0) << std::endl; 2321 /// std::cout << "The number of the arc maps: " 2321 /// std::cout << "The number of the arc maps: " 2322 2322 /// << contents.arcMaps(0).size() << std::endl; 2323 /// std::cout << "The name of second arc map: " 2323 /// std::cout << "The name of second arc map: " 2324 2324 /// << contents.arcMaps(0)[1] << std::endl; 2325 2325 ///\endcode 2326 class LgfContents { 2326 class LgfContents { 2327 2327 private: 2328 2328 … … 2345 2345 int line_num; 2346 2346 std::istringstream line; 2347 2347 2348 2348 public: 2349 2349 … … 2352 2352 /// Construct an \e LGF contents reader, which reads from the given 2353 2353 /// input stream. 2354 LgfContents(std::istream& is) 2354 LgfContents(std::istream& is) 2355 2355 : _is(&is), local_is(false) {} 2356 2356 … … 2359 2359 /// Construct an \e LGF contents reader, which reads from the given 2360 2360 /// file. 2361 LgfContents(const std::string& fn) 2361 LgfContents(const std::string& fn) 2362 2362 : _is(new std::ifstream(fn.c_str())), local_is(true) {} 2363 2363 … … 2368 2368 LgfContents(const char* fn) 2369 2369 : _is(new std::ifstream(fn)), local_is(true) {} 2370 2370 2371 2371 /// \brief Destructor 2372 2372 ~LgfContents() { … … 2375 2375 2376 2376 private: 2377 2377 2378 2378 LgfContents(const LgfContents&); 2379 2379 LgfContents& operator=(const LgfContents&); … … 2392 2392 } 2393 2393 2394 /// \brief Returns the node section name at the given position. 2395 /// 2396 /// Returns the node section name at the given position. 2394 /// \brief Returns the node section name at the given position. 2395 /// 2396 /// Returns the node section name at the given position. 2397 2397 const std::string& nodeSection(int i) const { 2398 2398 return _node_sections[i]; … … 2408 2408 /// @} 2409 2409 2410 /// \name Arc/Edge sections 2410 /// \name Arc/Edge sections 2411 2411 /// @{ 2412 2412 … … 2419 2419 } 2420 2420 2421 /// \brief Returns the arc/edge section name at the given position. 2422 /// 2423 /// Returns the arc/edge section name at the given position. 2421 /// \brief Returns the arc/edge section name at the given position. 2422 /// 2423 /// Returns the arc/edge section name at the given position. 2424 2424 /// \note It is synonym of \c edgeSection(). 2425 2425 const std::string& arcSection(int i) const { … … 2448 2448 } 2449 2449 2450 /// \brief Returns the section name at the given position. 2451 /// 2452 /// Returns the section name at the given position. 2450 /// \brief Returns the section name at the given position. 2451 /// 2452 /// Returns the section name at the given position. 2453 2453 /// \note It is synonym of \c arcSection(). 2454 2454 const std::string& edgeSection(int i) const { … … 2466 2466 /// @} 2467 2467 2468 /// \name Attribute sections 2468 /// \name Attribute sections 2469 2469 /// @{ 2470 2470 … … 2476 2476 } 2477 2477 2478 /// \brief Returns the attribute section name at the given position. 2479 /// 2480 /// Returns the attribute section name at the given position. 2478 /// \brief Returns the attribute section name at the given position. 2479 /// 2480 /// Returns the attribute section name at the given position. 2481 2481 const std::string& attributeSectionNames(int i) const { 2482 2482 return _attribute_sections[i]; … … 2492 2492 /// @} 2493 2493 2494 /// \name Extra sections 2494 /// \name Extra sections 2495 2495 /// @{ 2496 2496 … … 2502 2502 } 2503 2503 2504 /// \brief Returns the extra section type at the given position. 2505 /// 2506 /// Returns the section type at the given position. 2504 /// \brief Returns the extra section type at the given position. 2505 /// 2506 /// Returns the section type at the given position. 2507 2507 const std::string& extraSection(int i) const { 2508 2508 return _extra_sections[i]; … … 2516 2516 std::string str; 2517 2517 while(++line_num, std::getline(*_is, str)) { 2518 2519 2520 2521 2522 2523 2518 line.clear(); line.str(str); 2519 char c; 2520 if (line >> std::ws >> c && c != '#') { 2521 line.putback(c); 2522 return true; 2523 } 2524 2524 } 2525 2525 return false; … … 2533 2533 char c; 2534 2534 while (readSuccess() && line >> c && c != '@') { 2535 2535 readLine(); 2536 2536 } 2537 2537 line.putback(c); … … 2541 2541 char c; 2542 2542 if (!readLine() || !(line >> c) || c == '@') { 2543 2544 2543 if (readSuccess() && line) line.putback(c); 2544 return; 2545 2545 } 2546 2546 line.putback(c); 2547 2547 std::string map; 2548 2548 while (_reader_bits::readToken(line, map)) { 2549 2549 maps.push_back(map); 2550 2550 } 2551 2551 } … … 2555 2555 char c; 2556 2556 while (readSuccess() && line >> c && c != '@') { 2557 2558 2559 2560 2561 2557 line.putback(c); 2558 std::string attr; 2559 _reader_bits::readToken(line, attr); 2560 attrs.push_back(attr); 2561 readLine(); 2562 2562 } 2563 2563 line.putback(c); … … 2566 2566 public: 2567 2567 2568 /// \name Execution of the contents reader 2568 /// \name Execution of the contents reader 2569 2569 /// @{ 2570 2570 … … 2579 2579 while (readSuccess()) { 2580 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2581 char c; 2582 line >> c; 2583 2584 std::string section, caption; 2585 _reader_bits::readToken(line, section); 2586 _reader_bits::readToken(line, caption); 2587 2588 if (section == "nodes") { 2589 _node_sections.push_back(caption); 2590 _node_maps.push_back(std::vector<std::string>()); 2591 readMaps(_node_maps.back()); 2592 readLine(); skipSection(); 2593 } else if (section == "arcs" || section == "edges") { 2594 _edge_sections.push_back(caption); 2595 _arc_sections.push_back(section == "arcs"); 2596 _edge_maps.push_back(std::vector<std::string>()); 2597 readMaps(_edge_maps.back()); 2598 readLine(); skipSection(); 2599 } else if (section == "attributes") { 2600 _attribute_sections.push_back(caption); 2601 _attributes.push_back(std::vector<std::string>()); 2602 readAttributes(_attributes.back()); 2603 } else { 2604 _extra_sections.push_back(section); 2605 readLine(); skipSection(); 2606 } 2607 2607 } 2608 2608 } 2609 2609 2610 2610 /// @} 2611 2611 2612 2612 }; 2613 2613 }
Note: See TracChangeset
for help on using the changeset viewer.