00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00022
00023
00024 #ifndef LEMON_LEMON_READER_H
00025 #define LEMON_LEMON_READER_H
00026
00027
00028 #include <iostream>
00029 #include <fstream>
00030 #include <string>
00031 #include <vector>
00032 #include <algorithm>
00033 #include <map>
00034 #include <memory>
00035
00036 #include <lemon/error.h>
00037 #include <lemon/graph_utils.h>
00038 #include <lemon/utility.h>
00039 #include <lemon/bits/item_reader.h>
00040
00041 #include <lemon/xy.h>
00042
00043 #include <lemon/concept_check.h>
00044 #include <lemon/concept/maps.h>
00045
00046 namespace lemon {
00047
00048 namespace _reader_bits {
00049
00050 template <typename T>
00051 bool operator<(T, T) {
00052 throw DataFormatError("Label is not comparable");
00053 }
00054
00055 template <typename T>
00056 struct Less {
00057 bool operator()(const T& p, const T& q) const {
00058 return p < q;
00059 }
00060 };
00061
00062 template <typename Item>
00063 class ItemLabelReader {
00064 public:
00065
00066 bool isLabelReader() { return true; }
00067
00068 void readLabel(std::istream&, Item&) {}
00069
00070 template <class _ItemLabelReader>
00071 struct Constraints {
00072 void constraints() {
00073 bool b = reader.isLabelReader();
00074 ignore_unused_variable_warning(b);
00075 Item item;
00076 reader.readLabel(is, item);
00077 }
00078 _ItemLabelReader& reader;
00079 std::istream& is;
00080 };
00081
00082 };
00083
00084 template <typename Item>
00085 class ItemReader {
00086 public:
00087 void read(std::istream&, Item&) {}
00088
00089 template <class _ItemReader>
00090 struct Constraints {
00091 void constraints() {
00092 Item item;
00093 reader.read(is, item);
00094 }
00095 _ItemReader& reader;
00096 std::istream& is;
00097 };
00098
00099 };
00100
00101 template <typename Map>
00102 struct Ref { typedef Map& Type; };
00103 template <typename Map>
00104 struct Arg { typedef Map& Type; };
00105
00106 template <typename Graph, typename Map>
00107 class ForwardComposeMap {
00108 public:
00109 typedef typename Graph::UEdge Key;
00110 typedef typename Map::Value Value;
00111
00112 ForwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map)
00113 : graph(_graph), map(_map) {}
00114
00115 void set(const Key& key, const Value& val) {
00116 map.set(graph.direct(key, true), val);
00117 }
00118
00119 private:
00120 typename Ref<Map>::Type map;
00121 const Graph& graph;
00122 };
00123
00124 template <typename Graph, typename Map>
00125 ForwardComposeMap<Graph, Map>
00126 forwardComposeMap(const Graph& graph, const Map& map) {
00127 return ForwardComposeMap<Graph, Map>(graph, map);
00128 }
00129
00130 template <typename Graph, typename Map>
00131 ForwardComposeMap<Graph, Map>
00132 forwardComposeMap(const Graph& graph, Map& map) {
00133 return ForwardComposeMap<Graph, Map>(graph, map);
00134 }
00135
00136 template <typename Graph, typename Map>
00137 class BackwardComposeMap {
00138 public:
00139 typedef typename Graph::UEdge Key;
00140 typedef typename Map::Value Value;
00141
00142 BackwardComposeMap(const Graph& _graph, typename Arg<Map>::Type _map)
00143 : graph(_graph), map(_map) {}
00144
00145 void set(const Key& key, const Value& val) {
00146 map.set(graph.direct(key, false), val);
00147 }
00148
00149 private:
00150 typename Ref<Map>::Type map;
00151 const Graph& graph;
00152 };
00153
00154
00155 template <typename Graph, typename Map>
00156 BackwardComposeMap<Graph, Map>
00157 backwardComposeMap(const Graph& graph, const Map& map) {
00158 return BackwardComposeMap<Graph, Map>(graph, map);
00159 }
00160
00161 template <typename Graph, typename Map>
00162 BackwardComposeMap<Graph, Map>
00163 backwardComposeMap(const Graph& graph, Map& map) {
00164 return BackwardComposeMap<Graph, Map>(graph, map);
00165 }
00166
00167 template <typename Graph, typename Map>
00168 struct Ref<ForwardComposeMap<Graph, Map> > {
00169 typedef ForwardComposeMap<Graph, Map> Type;
00170 };
00171 template <typename Graph, typename Map>
00172 struct Arg<ForwardComposeMap<Graph, Map> > {
00173 typedef const ForwardComposeMap<Graph, Map>& Type;
00174 };
00175
00176 template <typename Graph, typename Map>
00177 struct Ref<BackwardComposeMap<Graph, Map> > {
00178 typedef BackwardComposeMap<Graph, Map> Type;
00179 };
00180 template <typename Graph, typename Map>
00181 struct Arg<BackwardComposeMap<Graph, Map> > {
00182 typedef const BackwardComposeMap<Graph, Map>& Type;
00183 };
00184
00185 template <typename Map>
00186 struct Ref<XMap<Map> > {
00187 typedef XMap<Map> Type;
00188 };
00189 template <typename Map>
00190 struct Arg<XMap<Map> > {
00191 typedef const XMap<Map>& Type;
00192 };
00193
00194 template <typename Map>
00195 struct Ref<YMap<Map> > {
00196 typedef YMap<Map> Type;
00197 };
00198 template <typename Map>
00199 struct Arg<YMap<Map> > {
00200 typedef const YMap<Map>& Type;
00201 };
00202
00203
00204 template <typename _Item>
00205 class MapReaderBase;
00206
00207 template <typename _Item>
00208 class MapInverterBase : public MapReaderBase<_Item> {
00209 public:
00210 typedef _Item Item;
00211 virtual void read(std::istream&, const Item&) = 0;
00212 virtual Item read(std::istream&) const = 0;
00213
00214 virtual MapInverterBase<_Item>* getInverter() {
00215 return this;
00216 }
00217 };
00218
00219 template <typename _Item, typename _Map, typename _Reader>
00220 class MapReaderInverter : public MapInverterBase<_Item> {
00221 public:
00222 typedef _Item Item;
00223 typedef _Reader Reader;
00224 typedef typename Reader::Value Value;
00225 typedef _Map Map;
00226 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00227
00228 typename _reader_bits::Ref<Map>::Type map;
00229 Reader reader;
00230 Inverse inverse;
00231
00232 MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map,
00233 const Reader& _reader)
00234 : map(_map), reader(_reader) {}
00235
00236 virtual ~MapReaderInverter() {}
00237
00238 virtual void read(std::istream& is, const Item& item) {
00239 Value value;
00240 reader.read(is, value);
00241 map.set(item, value);
00242 typename Inverse::iterator it = inverse.find(value);
00243 if (it == inverse.end()) {
00244 inverse.insert(std::make_pair(value, item));
00245 } else {
00246 throw DataFormatError("Multiple label occurence");
00247 }
00248 }
00249
00250 virtual Item read(std::istream& is) const {
00251 Value value;
00252 reader.read(is, value);
00253 typename Inverse::const_iterator it = inverse.find(value);
00254 if (it != inverse.end()) {
00255 return it->second;
00256 } else {
00257 throw DataFormatError("Invalid label error");
00258 }
00259 }
00260 };
00261
00262 template <typename _Item, typename _Reader>
00263 class SkipReaderInverter : public MapInverterBase<_Item> {
00264 public:
00265 typedef _Item Item;
00266 typedef _Reader Reader;
00267 typedef typename Reader::Value Value;
00268 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00269
00270 Reader reader;
00271
00272 SkipReaderInverter(const Reader& _reader)
00273 : reader(_reader) {}
00274
00275 virtual ~SkipReaderInverter() {}
00276
00277 virtual void read(std::istream& is, const Item& item) {
00278 Value value;
00279 reader.read(is, value);
00280 typename Inverse::iterator it = inverse.find(value);
00281 if (it == inverse.end()) {
00282 inverse.insert(std::make_pair(value, item));
00283 } else {
00284 throw DataFormatError("Multiple label occurence error");
00285 }
00286 }
00287
00288 virtual Item read(std::istream& is) const {
00289 Value value;
00290 reader.read(is, value);
00291 typename Inverse::const_iterator it = inverse.find(value);
00292 if (it != inverse.end()) {
00293 return it->second;
00294 } else {
00295 throw DataFormatError("Invalid label error");
00296 }
00297 }
00298
00299 private:
00300 Inverse inverse;
00301 };
00302
00303 template <typename _Item>
00304 class MapReaderBase {
00305 public:
00306 typedef _Item Item;
00307
00308 MapReaderBase() { _touched = false; }
00309
00310 void touch() { _touched = true; }
00311 bool touched() const { return _touched; }
00312
00313 virtual ~MapReaderBase() {}
00314
00315 virtual void read(std::istream& is, const Item& item) = 0;
00316 virtual MapInverterBase<_Item>* getInverter() = 0;
00317
00318 private:
00319 bool _touched;
00320
00321 };
00322
00323 template <typename _Item, typename _Map, typename _Reader>
00324 class MapReader : public MapReaderBase<_Item> {
00325 public:
00326 typedef _Map Map;
00327 typedef _Reader Reader;
00328 typedef typename Reader::Value Value;
00329 typedef _Item Item;
00330
00331 typename _reader_bits::Ref<Map>::Type map;
00332 Reader reader;
00333
00334 MapReader(typename _reader_bits::Arg<Map>::Type _map,
00335 const Reader& _reader)
00336 : map(_map), reader(_reader) {}
00337
00338 virtual ~MapReader() {}
00339
00340 virtual void read(std::istream& is, const Item& item) {
00341 Value value;
00342 reader.read(is, value);
00343 map.set(item, value);
00344 }
00345
00346 virtual MapInverterBase<_Item>* getInverter() {
00347 return new MapReaderInverter<Item, Map, Reader>(map, reader);
00348 }
00349 };
00350
00351
00352 template <typename _Item, typename _Reader>
00353 class SkipReader : public MapReaderBase<_Item> {
00354 public:
00355 typedef _Reader Reader;
00356 typedef typename Reader::Value Value;
00357 typedef _Item Item;
00358
00359 Reader reader;
00360 SkipReader(const Reader& _reader) : reader(_reader) {}
00361
00362 virtual ~SkipReader() {}
00363
00364 virtual void read(std::istream& is, const Item&) {
00365 Value value;
00366 reader.read(is, value);
00367 }
00368
00369 virtual MapInverterBase<Item>* getInverter() {
00370 return new SkipReaderInverter<Item, Reader>(reader);
00371 }
00372 };
00373
00374 template <typename _Item>
00375 class LabelReaderBase {
00376 public:
00377 typedef _Item Item;
00378 virtual ~LabelReaderBase() {}
00379 virtual Item read(std::istream& is) const = 0;
00380 virtual bool isLabelReader() const = 0;
00381 };
00382
00383 template <typename _Item, typename _BoxedLabelReader>
00384 class LabelReader : public LabelReaderBase<_Item> {
00385 public:
00386 typedef _Item Item;
00387 typedef _BoxedLabelReader BoxedLabelReader;
00388
00389 const BoxedLabelReader& boxedLabelReader;
00390
00391 LabelReader(const BoxedLabelReader& _boxedLabelReader)
00392 : boxedLabelReader(_boxedLabelReader) {}
00393
00394 virtual Item read(std::istream& is) const {
00395 Item item;
00396 boxedLabelReader.readLabel(is, item);
00397 return item;
00398 }
00399
00400 virtual bool isLabelReader() const {
00401 return boxedLabelReader.isLabelReader();
00402 }
00403 };
00404
00405 template <typename _Item>
00406 class ItemStore {
00407 public:
00408
00409 typedef _Item Item;
00410
00411 ItemStore(Item& _item) : item(&_item) {
00412 _touched = false;
00413 }
00414
00415 void touch() { _touched = true; }
00416 bool touched() const { return _touched; }
00417
00418 void read(const Item& _item) {
00419 *item = _item;
00420 }
00421
00422 private:
00423 Item* item;
00424 bool _touched;
00425 };
00426
00427 class ValueReaderBase {
00428 public:
00429 virtual void read(std::istream&) {};
00430 ValueReaderBase() { _touched = false; }
00431
00432 void touch() { _touched = true; }
00433 bool touched() const { return _touched; }
00434
00435 virtual ~ValueReaderBase() {}
00436 private:
00437 bool _touched;
00438 };
00439
00440 template <typename _Value, typename _Reader>
00441 class ValueReader : public ValueReaderBase {
00442 public:
00443 typedef _Value Value;
00444 typedef _Reader Reader;
00445
00446 ValueReader(Value& _value, const Reader& _reader)
00447 : value(_value), reader(_reader) {}
00448
00449 virtual void read(std::istream& is) {
00450 reader.read(is, value);
00451 }
00452 private:
00453 Value& value;
00454 Reader reader;
00455 };
00456
00457 }
00458
00489 class LemonReader {
00490 private:
00491
00492 class FilterStreamBuf : public std::streambuf {
00493 public:
00494
00495 typedef std::streambuf Parent;
00496 typedef Parent::char_type char_type;
00497 FilterStreamBuf(std::istream& is, int& num)
00498 : _is(is), _base(0), _eptr(0),
00499 _num(num), skip_state(after_endl) {}
00500
00501 protected:
00502
00503 enum skip_state_type {
00504 no_skip,
00505 after_endl,
00506 comment_line
00507 };
00508
00509 char_type small_buf[1];
00510
00511
00512 std::istream& _is;
00513
00514 char_type* _base;
00515 char_type* _eptr;
00516
00517 int& _num;
00518
00519 skip_state_type skip_state;
00520
00521
00522 char_type* base() { return _base; }
00523
00524 char_type* eptr() { return _eptr; }
00525
00526 int blen() { return _eptr - _base; }
00527
00528 void setb(char_type* buf, int len) {
00529 _base = buf;
00530 _eptr = buf + len;
00531 }
00532
00533 virtual std::streambuf* setbuf(char *buf, std::streamsize len) {
00534 if (base()) return 0;
00535 if (buf != 0 && len >= (int)sizeof(small_buf)) {
00536 setb(buf, len);
00537 } else {
00538 setb(small_buf, sizeof(small_buf));
00539 }
00540 setg(0, 0, 0);
00541 return this;
00542 }
00543
00544 bool put_char(char c) {
00545 switch (skip_state) {
00546 case no_skip:
00547 switch (c) {
00548 case '\n':
00549 skip_state = after_endl;
00550 return true;
00551 default:
00552 return true;
00553 }
00554 case after_endl:
00555 switch (c) {
00556 case '@':
00557 return false;
00558 case '\n':
00559 return false;
00560 case '#':
00561 skip_state = comment_line;
00562 return false;
00563 default:
00564 if (!isspace(c)) {
00565 skip_state = no_skip;
00566 return true;
00567 } else {
00568 return false;
00569 }
00570 }
00571 break;
00572 case comment_line:
00573 switch (c) {
00574 case '\n':
00575 skip_state = after_endl;
00576 return false;
00577 default:
00578 return false;
00579 }
00580 }
00581 return false;
00582 }
00583
00584 virtual int underflow() {
00585 char c;
00586 if (_is.read(&c, 1)) {
00587 _is.putback(c);
00588 if (c == '@') {
00589 return EOF;
00590 }
00591 } else {
00592 return EOF;
00593 }
00594 char_type *ptr;
00595 for (ptr = base(); ptr != eptr(); ++ptr) {
00596 if (_is.read(&c, 1)) {
00597 if (c == '\n') ++_num;
00598 if (put_char(c)) {
00599 *ptr = c;
00600 } else {
00601 if (skip_state == after_endl && c == '@') {
00602 _is.putback('@');
00603 break;
00604 }
00605 --ptr;
00606 }
00607 } else {
00608 break;
00609 }
00610 }
00611 setg(base(), base(), ptr);
00612 return *base();
00613 }
00614
00615 virtual int sync() {
00616 return EOF;
00617 }
00618 };
00619
00620 public:
00621
00630 class SectionReader {
00631 friend class LemonReader;
00632 protected:
00637 SectionReader(LemonReader& reader) {
00638 reader.attach(*this);
00639 }
00640
00641 virtual ~SectionReader() {}
00642
00648 virtual bool header(const std::string& line) = 0;
00649
00653 virtual void read(std::istream& is) = 0;
00654 };
00655
00659 LemonReader(std::istream& _is)
00660 : is(&_is), own_is(false) {}
00661
00665 LemonReader(const std::string& filename)
00666 : is(0), own_is(true) {
00667 is = new std::ifstream(filename.c_str());
00668 if (is->fail()) {
00669 throw FileOpenError(filename);
00670 }
00671 }
00672
00676 ~LemonReader() {
00677 if (own_is) {
00678 delete is;
00679 }
00680 }
00681
00682 private:
00683 LemonReader(const LemonReader&);
00684 void operator=(const LemonReader&);
00685
00686 void attach(SectionReader& reader) {
00687 readers.push_back(&reader);
00688 }
00689
00690 public:
00694 void run() {
00695 int line_num = 0;
00696 std::string line;
00697 try {
00698 while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
00699 SectionReaders::iterator it;
00700 for (it = readers.begin(); it != readers.end(); ++it) {
00701 if ((*it)->header(line)) {
00702 char buf[2048];
00703 FilterStreamBuf buffer(*is, line_num);
00704 buffer.pubsetbuf(buf, sizeof(buf));
00705 std::istream is(&buffer);
00706 (*it)->read(is);
00707 break;
00708 }
00709 }
00710 }
00711 } catch (DataFormatError& error) {
00712 error.line(line_num);
00713 throw error;
00714 }
00715 }
00716
00717
00718 private:
00719
00720 std::istream* is;
00721 bool own_is;
00722
00723 typedef std::vector<SectionReader*> SectionReaders;
00724 SectionReaders readers;
00725
00726 };
00727
00745 template <typename _Graph, typename _Traits = DefaultReaderTraits>
00746 class NodeSetReader : public LemonReader::SectionReader {
00747 typedef LemonReader::SectionReader Parent;
00748 public:
00749
00750 typedef _Graph Graph;
00751 typedef _Traits Traits;
00752 typedef typename Graph::Node Node;
00753 typedef typename Traits::Skipper DefaultSkipper;
00754
00761 NodeSetReader(LemonReader& _reader,
00762 Graph& _graph,
00763 const std::string& _name = std::string(),
00764 const DefaultSkipper& _skipper = DefaultSkipper())
00765 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {}
00766
00767
00771 virtual ~NodeSetReader() {
00772 for (typename MapReaders::iterator it = readers.begin();
00773 it != readers.end(); ++it) {
00774 delete it->second;
00775 }
00776 }
00777
00778 private:
00779 NodeSetReader(const NodeSetReader&);
00780 void operator=(const NodeSetReader&);
00781
00782 public:
00783
00787 template <typename Map>
00788 NodeSetReader& readNodeMap(std::string name, Map& map) {
00789 return _readMap<
00790 typename Traits::template Reader<typename Map::Value>, Map,
00791 typename _reader_bits::Arg<Map>::Type>(name, map);
00792 }
00793
00794 template <typename Map>
00795 NodeSetReader& readNodeMap(std::string name, const Map& map) {
00796 return _readMap<
00797 typename Traits::template Reader<typename Map::Value>, Map,
00798 typename _reader_bits::Arg<Map>::Type>(name, map);
00799 }
00800
00804 template <typename Reader, typename Map>
00805 NodeSetReader& readNodeMap(std::string name, Map& map,
00806 const Reader& reader = Reader()) {
00807 return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
00808 (name, map, reader);
00809 }
00810
00811 template <typename Reader, typename Map>
00812 NodeSetReader& readNodeMap(std::string name, const Map& map,
00813 const Reader& reader = Reader()) {
00814 return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
00815 (name, map, reader);
00816 }
00817
00818 private:
00819
00820 template <typename Reader, typename Map, typename MapParameter>
00821 NodeSetReader& _readMap(std::string name, MapParameter map,
00822 const Reader& reader = Reader()) {
00823 checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
00824 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
00825 if (readers.find(name) != readers.end()) {
00826 ErrorMessage msg;
00827 msg << "Multiple read rule for node map: " << name;
00828 throw IOParameterError(msg.message());
00829 }
00830 readers.insert(
00831 make_pair(name, new _reader_bits::
00832 MapReader<Node, Map, Reader>(map, reader)));
00833 return *this;
00834 }
00835
00836 public:
00837
00841 template <typename Reader>
00842 NodeSetReader& skipNodeMap(std::string name,
00843 const Reader& reader = Reader()) {
00844 if (readers.find(name) != readers.end()) {
00845 ErrorMessage msg;
00846 msg << "Multiple read rule for node map: " << name;
00847 throw IOParameterError(msg.message());
00848 }
00849 readers.insert(make_pair(name, new _reader_bits::
00850 SkipReader<Node, Reader>(reader)));
00851 return *this;
00852 }
00853
00854 protected:
00855
00861 virtual bool header(const std::string& line) {
00862 std::istringstream ls(line);
00863 std::string command;
00864 std::string id;
00865 ls >> command >> name;
00866 return command == "@nodeset" && name == id;
00867 }
00868
00872 virtual void read(std::istream& is) {
00873 std::vector<_reader_bits::MapReaderBase<Node>* > index;
00874 std::string line;
00875
00876 getline(is, line);
00877 std::istringstream ls(line);
00878 std::string id;
00879 while (ls >> id) {
00880 typename MapReaders::iterator it = readers.find(id);
00881 if (it != readers.end()) {
00882 it->second->touch();
00883 index.push_back(it->second);
00884 } else {
00885 index.push_back(&skipper);
00886 }
00887 if (id == "label" || (id =="id" && inverter.get() == 0)) {
00888 inverter.reset(index.back()->getInverter());
00889 index.back() = inverter.get();
00890 }
00891 }
00892 for (typename MapReaders::iterator it = readers.begin();
00893 it != readers.end(); ++it) {
00894 if (!it->second->touched()) {
00895 ErrorMessage msg;
00896 msg << "Map not found in file: " << it->first;
00897 throw IOParameterError(msg.message());
00898 }
00899 }
00900 while (getline(is, line)) {
00901 Node node = graph.addNode();
00902 std::istringstream ls(line);
00903 for (int i = 0; i < (int)index.size(); ++i) {
00904 index[i]->read(ls, node);
00905 }
00906 }
00907 }
00908
00909 public:
00910
00915 bool isLabelReader() const {
00916 return inverter.get() != 0;
00917 }
00918
00923 void readLabel(std::istream& is, Node& node) const {
00924 node = inverter->read(is);
00925 }
00926
00927 private:
00928
00929 typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders;
00930 MapReaders readers;
00931
00932 Graph& graph;
00933 std::string name;
00934 _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
00935
00936 std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
00937 };
00938
00961 template <typename _Graph, typename _Traits = DefaultReaderTraits>
00962 class EdgeSetReader : public LemonReader::SectionReader {
00963 typedef LemonReader::SectionReader Parent;
00964 public:
00965
00966 typedef _Graph Graph;
00967 typedef _Traits Traits;
00968 typedef typename Graph::Node Node;
00969 typedef typename Graph::Edge Edge;
00970 typedef typename Traits::Skipper DefaultSkipper;
00971
00980 template <typename NodeLabelReader>
00981 EdgeSetReader(LemonReader& _reader,
00982 Graph& _graph,
00983 const NodeLabelReader& _nodeLabelReader,
00984 const std::string& _name = std::string(),
00985 const DefaultSkipper& _skipper = DefaultSkipper())
00986 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
00987 checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
00988 nodeLabelReader.reset(new _reader_bits::
00989 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
00990 }
00994 virtual ~EdgeSetReader() {
00995 for (typename MapReaders::iterator it = readers.begin();
00996 it != readers.end(); ++it) {
00997 delete it->second;
00998 }
00999 }
01000
01001 private:
01002 EdgeSetReader(const EdgeSetReader&);
01003 void operator=(const EdgeSetReader&);
01004
01005 public:
01006
01010 template <typename Map>
01011 EdgeSetReader& readEdgeMap(std::string name, Map& map) {
01012 return _readMap<
01013 typename Traits::template Reader<typename Map::Value>, Map,
01014 typename _reader_bits::Arg<Map>::Type>(name, map);
01015 }
01016
01017 template <typename Map>
01018 EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
01019 return _readMap<
01020 typename Traits::template Reader<typename Map::Value>, Map,
01021 typename _reader_bits::Arg<Map>::Type>(name, map);
01022 }
01023
01027 template <typename Reader, typename Map>
01028 EdgeSetReader& readEdgeMap(std::string name, Map& map,
01029 const Reader& reader = Reader()) {
01030 return _readMap<Reader, Map,
01031 typename _reader_bits::Arg<Map>::Type>(name, map, reader);
01032 }
01033
01034 template <typename Reader, typename Map>
01035 EdgeSetReader& readEdgeMap(std::string name, const Map& map,
01036 const Reader& reader = Reader()) {
01037 return _readMap<Reader, Map,
01038 typename _reader_bits::Arg<Map>::Type>(name, map, reader);
01039 }
01040
01041 private:
01042
01043 template <typename Reader, typename Map, typename MapParameter>
01044 EdgeSetReader& _readMap(std::string name, MapParameter map,
01045 const Reader& reader = Reader()) {
01046 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
01047 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01048 if (readers.find(name) != readers.end()) {
01049 ErrorMessage msg;
01050 msg << "Multiple read rule for edge map: " << name;
01051 throw IOParameterError(msg.message());
01052 }
01053 readers.insert(
01054 make_pair(name, new _reader_bits::
01055 MapReader<Edge, Map, Reader>(map, reader)));
01056 return *this;
01057 }
01058
01059 public:
01060
01064 template <typename Reader>
01065 EdgeSetReader& skipEdgeMap(std::string name,
01066 const Reader& reader = Reader()) {
01067 if (readers.find(name) != readers.end()) {
01068 ErrorMessage msg;
01069 msg << "Multiple read rule for edge map: " << name;
01070 throw IOParameterError(msg.message());
01071 }
01072 readers.insert(make_pair(name, new _reader_bits::
01073 SkipReader<Edge, Reader>(reader)));
01074 return *this;
01075 }
01076
01077 protected:
01078
01084 virtual bool header(const std::string& line) {
01085 std::istringstream ls(line);
01086 std::string command;
01087 std::string id;
01088 ls >> command >> name;
01089 return command == "@edgeset" && name == id;
01090 }
01091
01095 virtual void read(std::istream& is) {
01096 if (!nodeLabelReader->isLabelReader()) {
01097 throw DataFormatError("Cannot find nodeset or label map");
01098 }
01099 std::vector<_reader_bits::MapReaderBase<Edge>* > index;
01100 std::string line;
01101
01102 getline(is, line);
01103 std::istringstream ls(line);
01104 std::string id;
01105 while (ls >> id) {
01106 typename MapReaders::iterator it = readers.find(id);
01107 if (it != readers.end()) {
01108 index.push_back(it->second);
01109 it->second->touch();
01110 } else {
01111 index.push_back(&skipper);
01112 }
01113 if (id == "label" || (id =="id" && inverter.get() == 0)) {
01114 inverter.reset(index.back()->getInverter());
01115 index.back() = inverter.get();
01116 }
01117 }
01118 for (typename MapReaders::iterator it = readers.begin();
01119 it != readers.end(); ++it) {
01120 if (!it->second->touched()) {
01121 ErrorMessage msg;
01122 msg << "Map not found in file: " << it->first;
01123 throw IOParameterError(msg.message());
01124 }
01125 }
01126 while (getline(is, line)) {
01127 std::istringstream ls(line);
01128 Node from = nodeLabelReader->read(ls);
01129 Node to = nodeLabelReader->read(ls);
01130 Edge edge = graph.addEdge(from, to);
01131 for (int i = 0; i < (int)index.size(); ++i) {
01132 index[i]->read(ls, edge);
01133 }
01134 }
01135 }
01136
01137 public:
01138
01143 bool isLabelReader() const {
01144 return inverter.get() != 0;
01145 }
01146
01151 void readLabel(std::istream& is, Edge& edge) const {
01152 edge = inverter->read(is);
01153 }
01154
01155 private:
01156
01157 typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders;
01158 MapReaders readers;
01159
01160 Graph& graph;
01161 std::string name;
01162 _reader_bits::SkipReader<Edge, DefaultSkipper> skipper;
01163
01164 std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter;
01165 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01166 };
01167
01195 template <typename _Graph, typename _Traits = DefaultReaderTraits>
01196 class UEdgeSetReader : public LemonReader::SectionReader {
01197 typedef LemonReader::SectionReader Parent;
01198 public:
01199
01200 typedef _Graph Graph;
01201 typedef _Traits Traits;
01202 typedef typename Graph::Node Node;
01203 typedef typename Graph::Edge Edge;
01204 typedef typename Graph::UEdge UEdge;
01205 typedef typename Traits::Skipper DefaultSkipper;
01206
01215 template <typename NodeLabelReader>
01216 UEdgeSetReader(LemonReader& _reader,
01217 Graph& _graph,
01218 const NodeLabelReader& _nodeLabelReader,
01219 const std::string& _name = std::string(),
01220 const DefaultSkipper& _skipper = DefaultSkipper())
01221 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {
01222 checkConcept<_reader_bits::ItemLabelReader<Node>, NodeLabelReader>();
01223 nodeLabelReader.reset(new _reader_bits::
01224 LabelReader<Node, NodeLabelReader>(_nodeLabelReader));
01225 }
01229 virtual ~UEdgeSetReader() {
01230 for (typename MapReaders::iterator it = readers.begin();
01231 it != readers.end(); ++it) {
01232 delete it->second;
01233 }
01234 }
01235
01236 private:
01237 UEdgeSetReader(const UEdgeSetReader&);
01238 void operator=(const UEdgeSetReader&);
01239
01240 public:
01241
01245 template <typename Map>
01246 UEdgeSetReader& readUEdgeMap(std::string name, Map& map) {
01247 return _readMap<
01248 typename Traits::template Reader<typename Map::Value>, Map,
01249 typename _reader_bits::Arg<Map>::Type>(name, map);
01250 }
01251
01252 template <typename Map>
01253 UEdgeSetReader& readUEdgeMap(std::string name, const Map& map) {
01254 return _readMap<
01255 typename Traits::template Reader<typename Map::Value>, Map,
01256 typename _reader_bits::Arg<Map>::Type>(name, map);
01257 }
01258
01262 template <typename Reader, typename Map>
01263 UEdgeSetReader& readUEdgeMap(std::string name, Map& map,
01264 const Reader& reader = Reader()) {
01265 return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01266 (name, map, reader);
01267 }
01268
01269 template <typename Reader, typename Map>
01270 UEdgeSetReader& readUEdgeMap(std::string name, const Map& map,
01271 const Reader& reader = Reader()) {
01272 return _readMap<Reader, Map, typename _reader_bits::Arg<Map>::Type >
01273 (name, map, reader);
01274 }
01275
01276 private:
01277
01278 template <typename Reader, typename Map, typename MapParameter>
01279 UEdgeSetReader& _readMap(std::string name, MapParameter map,
01280 const Reader& reader = Reader()) {
01281 checkConcept<concept::WriteMap<UEdge, typename Map::Value>, Map>();
01282 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01283 if (readers.find(name) != readers.end()) {
01284 ErrorMessage msg;
01285 msg << "Multiple read rule for edge map: " << name;
01286 throw IOParameterError(msg.message());
01287 }
01288 readers.insert(
01289 make_pair(name, new _reader_bits::
01290 MapReader<UEdge, Map, Reader>(map, reader)));
01291 return *this;
01292 }
01293
01294 public:
01295
01299 template <typename Reader>
01300 UEdgeSetReader& skipUEdgeMap(std::string name,
01301 const Reader& reader = Reader()) {
01302 if (readers.find(name) != readers.end()) {
01303 ErrorMessage msg;
01304 msg << "Multiple read rule for node map: " << name;
01305 throw IOParameterError(msg.message());
01306 }
01307 readers.insert(make_pair(name, new _reader_bits::
01308 SkipReader<UEdge, Reader>(reader)));
01309 return *this;
01310 }
01311
01315 template <typename Map>
01316 UEdgeSetReader& readEdgeMap(std::string name, Map& map) {
01317 return _readDirMap<
01318 typename Traits::template Reader<typename Map::Value>, Map,
01319 typename _reader_bits::Arg<Map>::Type>(name, map);
01320 }
01321
01322 template <typename Map>
01323 UEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
01324 return _readDirMap<
01325 typename Traits::template Reader<typename Map::Value>, Map,
01326 typename _reader_bits::Arg<Map>::Type>(name, map);
01327 }
01328
01332 template <typename Reader, typename Map>
01333 UEdgeSetReader& readEdgeMap(std::string name, Map& map,
01334 const Reader& reader = Reader()) {
01335 return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01336 (name, map, reader);
01337 }
01338
01339 template <typename Reader, typename Map>
01340 UEdgeSetReader& readEdgeMap(std::string name, const Map& map,
01341 const Reader& reader = Reader()) {
01342 return _readDirMap<Reader, Map, typename _reader_bits::Arg<Map>::Type>
01343 (name, map, reader);
01344 }
01345
01346 private:
01347
01348 template <typename Reader, typename Map, typename MapParameter>
01349 UEdgeSetReader& _readDirMap(std::string name, MapParameter map,
01350 const Reader& reader = Reader()) {
01351 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01352 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
01353 readMap("+" + name,
01354 _reader_bits::forwardComposeMap(graph, map), reader);
01355 readMap("-" + name,
01356 _reader_bits::backwardComposeMap(graph, map), reader);
01357 return *this;
01358 }
01359
01360 public:
01361
01365 template <typename Reader>
01366 UEdgeSetReader& skipEdgeMap(std::string name,
01367 const Reader& reader = Reader()) {
01368 skipMap("+" + name, reader);
01369 skipMap("-" + name, reader);
01370 return *this;
01371 }
01372
01373 protected:
01374
01380 virtual bool header(const std::string& line) {
01381 std::istringstream ls(line);
01382 std::string command;
01383 std::string id;
01384 ls >> command >> name;
01385 return command == "@uedgeset" && name == id;
01386 }
01387
01391 virtual void read(std::istream& is) {
01392 if (!nodeLabelReader->isLabelReader()) {
01393 throw DataFormatError("Cannot find nodeset or label map");
01394 }
01395 std::vector<_reader_bits::MapReaderBase<UEdge>* > index;
01396 std::string line;
01397
01398 getline(is, line);
01399 std::istringstream ls(line);
01400 std::string id;
01401 while (ls >> id) {
01402 typename MapReaders::iterator it = readers.find(id);
01403 if (it != readers.end()) {
01404 index.push_back(it->second);
01405 it->second->touch();
01406 } else {
01407 index.push_back(&skipper);
01408 }
01409 if (id == "label" || (id =="id" && inverter.get() == 0)) {
01410 inverter.reset(index.back()->getInverter());
01411 index.back() = inverter.get();
01412 }
01413 }
01414 for (typename MapReaders::iterator it = readers.begin();
01415 it != readers.end(); ++it) {
01416 if (!it->second->touched()) {
01417 ErrorMessage msg;
01418 msg << "Map not found in file: " << it->first;
01419 throw IOParameterError(msg.message());
01420 }
01421 }
01422 while (getline(is, line)) {
01423 std::istringstream ls(line);
01424 Node from = nodeLabelReader->read(ls);
01425 Node to = nodeLabelReader->read(ls);
01426 UEdge edge = graph.addEdge(from, to);
01427 for (int i = 0; i < (int)index.size(); ++i) {
01428 index[i]->read(ls, edge);
01429 }
01430 }
01431 }
01432
01433 public:
01434
01439 bool isLabelReader() const {
01440 return inverter.get() != 0;
01441 }
01442
01447 void readLabel(std::istream& is, UEdge& uEdge) const {
01448 uEdge = inverter->read(is);
01449 }
01450
01457 void readLabel(std::istream& is, Edge& edge) const {
01458 char c;
01459 is >> c;
01460 UEdge uEdge = inverter->read(is);
01461 if (c == '+') {
01462 edge = graph.direct(uEdge, true);
01463 } else if (c == '-') {
01464 edge = graph.direct(uEdge, false);
01465 } else {
01466 throw DataFormatError("Wrong id format for edge "
01467 "in undirected edgeset");
01468 }
01469 }
01470
01471 private:
01472
01473 typedef std::map<std::string,
01474 _reader_bits::MapReaderBase<UEdge>*> MapReaders;
01475 MapReaders readers;
01476
01477 Graph& graph;
01478 std::string name;
01479 _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper;
01480
01481 std::auto_ptr<_reader_bits::MapInverterBase<UEdge> > inverter;
01482 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01483 };
01484
01495 template <typename _Graph>
01496 class NodeReader : public LemonReader::SectionReader {
01497 typedef LemonReader::SectionReader Parent;
01498 typedef _Graph Graph;
01499 typedef typename Graph::Node Node;
01500 public:
01501
01508 template <typename _LabelReader>
01509 NodeReader(LemonReader& _reader, const _LabelReader& _labelReader,
01510 const std::string& _name = std::string())
01511 : Parent(_reader), name(_name) {
01512 checkConcept<_reader_bits::ItemLabelReader<Node>, _LabelReader>();
01513 nodeLabelReader.reset(new _reader_bits::
01514 LabelReader<Node, _LabelReader>(_labelReader));
01515 }
01516
01520 virtual ~NodeReader() {}
01521
01522 private:
01523 NodeReader(const NodeReader&);
01524 void operator=(const NodeReader&);
01525
01526 public:
01527
01531 void readNode(const std::string& name, Node& item) {
01532 if (readers.find(name) != readers.end()) {
01533 ErrorMessage msg;
01534 msg << "Multiple read rule for node: " << name;
01535 throw IOParameterError(msg.message());
01536 }
01537 readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item)));
01538 }
01539
01540 protected:
01541
01547 virtual bool header(const std::string& line) {
01548 std::istringstream ls(line);
01549 std::string command;
01550 std::string id;
01551 ls >> command >> name;
01552 return command == "@nodes" && name == id;
01553 }
01554
01558 virtual void read(std::istream& is) {
01559 if (!nodeLabelReader->isLabelReader()) {
01560 throw DataFormatError("Cannot find nodeset or label map");
01561 }
01562 std::string line;
01563 while (getline(is, line)) {
01564 std::istringstream ls(line);
01565 std::string id;
01566 ls >> id;
01567 typename NodeReaders::iterator it = readers.find(id);
01568 if (it != readers.end()) {
01569 it->second.read(nodeLabelReader->read(ls));
01570 it->second.touch();
01571 }
01572 }
01573 for (typename NodeReaders::iterator it = readers.begin();
01574 it != readers.end(); ++it) {
01575 if (!it->second.touched()) {
01576 ErrorMessage msg;
01577 msg << "Node not found in file: " << it->first;
01578 throw IOParameterError(msg.message());
01579 }
01580 }
01581 }
01582
01583 private:
01584
01585 std::string name;
01586
01587 typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders;
01588 NodeReaders readers;
01589 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > nodeLabelReader;
01590 };
01591
01602 template <typename _Graph>
01603 class EdgeReader : public LemonReader::SectionReader {
01604 typedef LemonReader::SectionReader Parent;
01605 typedef _Graph Graph;
01606 typedef typename Graph::Edge Edge;
01607 public:
01608
01615 template <typename _LabelReader>
01616 EdgeReader(LemonReader& _reader, const _LabelReader& _labelReader,
01617 const std::string& _name = std::string())
01618 : Parent(_reader), name(_name) {
01619 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
01620 edgeLabelReader.reset(new _reader_bits::
01621 LabelReader<Edge, _LabelReader>(_labelReader));
01622 }
01623
01627 virtual ~EdgeReader() {}
01628 private:
01629 EdgeReader(const EdgeReader&);
01630 void operator=(const EdgeReader&);
01631
01632 public:
01633
01637 void readEdge(const std::string& name, Edge& item) {
01638 if (readers.find(name) != readers.end()) {
01639 ErrorMessage msg;
01640 msg << "Multiple read rule for edge: " << name;
01641 throw IOParameterError(msg.message());
01642 }
01643 readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
01644 }
01645
01646 protected:
01647
01653 virtual bool header(const std::string& line) {
01654 std::istringstream ls(line);
01655 std::string command;
01656 std::string id;
01657 ls >> command >> name;
01658 return command == "@edges" && name == id;
01659 }
01660
01664 virtual void read(std::istream& is) {
01665 if (!edgeLabelReader->isLabelReader()) {
01666 throw DataFormatError("Cannot find edgeset or label map");
01667 }
01668 std::string line;
01669 while (getline(is, line)) {
01670 std::istringstream ls(line);
01671 std::string id;
01672 ls >> id;
01673 typename EdgeReaders::iterator it = readers.find(id);
01674 if (it != readers.end()) {
01675 it->second.read(edgeLabelReader->read(ls));
01676 it->second.touch();
01677 }
01678 }
01679 for (typename EdgeReaders::iterator it = readers.begin();
01680 it != readers.end(); ++it) {
01681 if (!it->second.touched()) {
01682 ErrorMessage msg;
01683 msg << "Edge not found in file: " << it->first;
01684 throw IOParameterError(msg.message());
01685 }
01686 }
01687 }
01688
01689 private:
01690
01691 std::string name;
01692
01693 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
01694 EdgeReaders readers;
01695 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
01696 };
01697
01708 template <typename _Graph>
01709 class UEdgeReader : public LemonReader::SectionReader {
01710 typedef LemonReader::SectionReader Parent;
01711 typedef _Graph Graph;
01712 typedef typename Graph::Edge Edge;
01713 typedef typename Graph::UEdge UEdge;
01714 public:
01715
01723 template <typename _LabelReader>
01724 UEdgeReader(LemonReader& _reader, const _LabelReader& _labelReader,
01725 const std::string& _name = std::string())
01726 : Parent(_reader), name(_name) {
01727 checkConcept<_reader_bits::ItemLabelReader<UEdge>, _LabelReader>();
01728 checkConcept<_reader_bits::ItemLabelReader<Edge>, _LabelReader>();
01729 uEdgeLabelReader.reset(new _reader_bits::
01730 LabelReader<UEdge, _LabelReader>(_labelReader));
01731 edgeLabelReader.reset(new _reader_bits::
01732 LabelReader<Edge, _LabelReader>(_labelReader));
01733 }
01734
01738 virtual ~UEdgeReader() {}
01739 private:
01740 UEdgeReader(const UEdgeReader&);
01741 void operator=(const UEdgeReader&);
01742
01743 public:
01744
01748 void readUEdge(const std::string& name, UEdge& item) {
01749 if (uEdgeReaders.find(name) != uEdgeReaders.end()) {
01750 ErrorMessage msg;
01751 msg << "Multiple read rule for undirected edge: " << name;
01752 throw IOParameterError(msg.message());
01753 }
01754 uEdgeReaders.insert(make_pair(name, _reader_bits::
01755 ItemStore<UEdge>(item)));
01756 }
01757
01761 void readEdge(const std::string& name, Edge& item) {
01762 if (edgeReaders.find(name) != edgeReaders.end()) {
01763 ErrorMessage msg;
01764 msg << "Multiple read rule for edge: " << name;
01765 throw IOParameterError(msg.message());
01766 }
01767 edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item)));
01768 }
01769
01770 protected:
01771
01777 virtual bool header(const std::string& line) {
01778 std::istringstream ls(line);
01779 std::string command;
01780 std::string id;
01781 ls >> command >> name;
01782 return command == "@uedges" && name == id;
01783 }
01784
01788 virtual void read(std::istream& is) {
01789 if (!edgeLabelReader->isLabelReader()) {
01790 throw DataFormatError("Cannot find undirected edgeset or label map");
01791 }
01792 if (!uEdgeLabelReader->isLabelReader()) {
01793 throw DataFormatError("Cannot find undirected edgeset or label map");
01794 }
01795 std::string line;
01796 while (getline(is, line)) {
01797 std::istringstream ls(line);
01798 std::string id;
01799 ls >> id;
01800 {
01801 typename UEdgeReaders::iterator it = uEdgeReaders.find(id);
01802 if (it != uEdgeReaders.end()) {
01803 it->second.read(uEdgeLabelReader->read(ls));
01804 it->second.touch();
01805 continue;
01806 }
01807 } {
01808 typename EdgeReaders::iterator it = edgeReaders.find(id);
01809 if (it != edgeReaders.end()) {
01810 it->second.read(edgeLabelReader->read(ls));
01811 it->second.touch();
01812 continue;
01813 }
01814 }
01815 }
01816 for (typename EdgeReaders::iterator it = edgeReaders.begin();
01817 it != edgeReaders.end(); ++it) {
01818 if (!it->second.touched()) {
01819 ErrorMessage msg;
01820 msg << "Edge not found in file: " << it->first;
01821 throw IOParameterError(msg.message());
01822 }
01823 }
01824 for (typename UEdgeReaders::iterator it = uEdgeReaders.begin();
01825 it != uEdgeReaders.end(); ++it) {
01826 if (!it->second.touched()) {
01827 ErrorMessage msg;
01828 msg << "UEdge not found in file: " << it->first;
01829 throw IOParameterError(msg.message());
01830 }
01831 }
01832 }
01833
01834 private:
01835
01836 std::string name;
01837
01838 typedef std::map<std::string,
01839 _reader_bits::ItemStore<UEdge> > UEdgeReaders;
01840 UEdgeReaders uEdgeReaders;
01841 std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > uEdgeLabelReader;
01842
01843 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders;
01844 EdgeReaders edgeReaders;
01845 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > edgeLabelReader;
01846 };
01847
01859 template <typename _Traits = DefaultReaderTraits>
01860 class AttributeReader : public LemonReader::SectionReader {
01861 typedef LemonReader::SectionReader Parent;
01862 typedef _Traits Traits;
01863 public:
01869 AttributeReader(LemonReader& _reader,
01870 const std::string& _name = std::string())
01871 : Parent(_reader), name(_name) {}
01872
01876 virtual ~AttributeReader() {
01877 for (typename Readers::iterator it = readers.begin();
01878 it != readers.end(); ++it) {
01879 delete it->second;
01880 }
01881 }
01882
01883 private:
01884 AttributeReader(const AttributeReader&);
01885 void operator=(AttributeReader&);
01886
01887 public:
01891 template <typename Value>
01892 AttributeReader& readAttribute(const std::string& id, Value& value) {
01893 return readAttribute<typename Traits::template Reader<Value> >
01894 (id, value);
01895 }
01896
01900 template <typename Reader, typename Value>
01901 AttributeReader& readAttribute(const std::string& name, Value& value,
01902 const Reader& reader = Reader()) {
01903 checkConcept<_reader_bits::ItemReader<Value>, Reader>();
01904 if (readers.find(name) != readers.end()) {
01905 ErrorMessage msg;
01906 msg << "Multiple read rule for attribute: " << name;
01907 throw IOParameterError(msg.message());
01908 }
01909 readers.insert(make_pair(name, new _reader_bits::
01910 ValueReader<Value, Reader>(value, reader)));
01911 return *this;
01912 }
01913
01914 protected:
01915
01921 bool header(const std::string& line) {
01922 std::istringstream ls(line);
01923 std::string command;
01924 std::string id;
01925 ls >> command >> name;
01926 return command == "@attributes" && name == id;
01927 }
01928
01932 void read(std::istream& is) {
01933 std::string line;
01934 while (getline(is, line)) {
01935 std::istringstream ls(line);
01936 std::string id;
01937 ls >> id;
01938 typename Readers::iterator it = readers.find(id);
01939 if (it != readers.end()) {
01940 it->second->read(ls);
01941 it->second->touch();
01942 }
01943 }
01944 for (typename Readers::iterator it = readers.begin();
01945 it != readers.end(); ++it) {
01946 if (!it->second->touched()) {
01947 ErrorMessage msg;
01948 msg << "Attribute not found in file: " << it->first;
01949 throw IOParameterError(msg.message());
01950 }
01951 }
01952 }
01953
01954 private:
01955 std::string name;
01956
01957 typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers;
01958 Readers readers;
01959 };
01960
01972 class ContentReader : public LemonReader::SectionReader {
01973 typedef LemonReader::SectionReader Parent;
01974 public:
01978 ContentReader(LemonReader& _reader) : Parent(_reader) {}
01979
01983 virtual ~ContentReader() {}
01984
01988 int nodeSetNum() const {
01989 return nodesets.size();
01990 }
01991
01995 std::string nodeSetName(int index) const {
01996 return nodesets[index].name;
01997 }
01998
02002 const std::vector<std::string>& nodeSetMaps(int index) const {
02003 return nodesets[index].items;
02004 }
02005
02009 int edgeSetNum() const {
02010 return edgesets.size();
02011 }
02012
02016 std::string edgeSetName(int index) const {
02017 return edgesets[index].name;
02018 }
02019
02023 const std::vector<std::string>& edgeSetMaps(int index) const {
02024 return edgesets[index].items;
02025 }
02026
02030 int uEdgeSetNum() const {
02031 return uedgesets.size();
02032 }
02033
02038 std::string uEdgeSetName(int index) const {
02039 return uedgesets[index].name;
02040 }
02041
02046 const std::vector<std::string>& uEdgeSetMaps(int index) const {
02047 return uedgesets[index].items;
02048 }
02049
02053 int nodesNum() const {
02054 return nodes.size();
02055 }
02056
02061 std::string nodesName(int index) const {
02062 return nodes[index].name;
02063 }
02064
02069 const std::vector<std::string>& nodesItems(int index) const {
02070 return nodes[index].items;
02071 }
02072
02076 int edgesNum() const {
02077 return edges.size();
02078 }
02079
02084 std::string edgesName(int index) const {
02085 return edges[index].name;
02086 }
02087
02092 const std::vector<std::string>& edgesItems(int index) const {
02093 return edges[index].items;
02094 }
02095
02100 int uEdgesNum() const {
02101 return uedges.size();
02102 }
02103
02109 std::string uEdgesName(int index) const {
02110 return uedges[index].name;
02111 }
02112
02118 const std::vector<std::string>& uEdgesItems(int index) const {
02119 return uedges[index].items;
02120 }
02121
02122
02126 int attributesNum() const {
02127 return attributes.size();
02128 }
02129
02134 std::string attributesName(int index) const {
02135 return attributes[index].name;
02136 }
02137
02141 const std::vector<std::string>& attributesItems(int index) const {
02142 return attributes[index].items;
02143 }
02144
02145 const std::vector<std::string>& otherSections() const {
02146 return sections;
02147 }
02148
02149 protected:
02150
02155 bool header(const std::string& line) {
02156 std::istringstream ls(line);
02157 std::string command, name;
02158 ls >> command >> name;
02159 if (command == "@nodeset") {
02160 current = command;
02161 nodesets.push_back(SectionInfo(name));
02162 } else if (command == "@edgeset") {
02163 current = command;
02164 edgesets.push_back(SectionInfo(name));
02165 } else if (command == "@uedgeset") {
02166 current = command;
02167 uedgesets.push_back(SectionInfo(name));
02168 } else if (command == "@nodes") {
02169 current = command;
02170 nodes.push_back(SectionInfo(name));
02171 } else if (command == "@edges") {
02172 current = command;
02173 edges.push_back(SectionInfo(name));
02174 } else if (command == "@uedges") {
02175 current = command;
02176 uedges.push_back(SectionInfo(name));
02177 } else if (command == "@attributes") {
02178 current = command;
02179 attributes.push_back(SectionInfo(name));
02180 } else {
02181 sections.push_back(line);
02182 return false;
02183 }
02184 return true;
02185 }
02186
02190 void read(std::istream& is) {
02191 if (current == "@nodeset") {
02192 readMapNames(is, nodesets.back().items);
02193 } else if (current == "@edgeset") {
02194 readMapNames(is, edgesets.back().items);
02195 } else if (current == "@uedgeset") {
02196 readMapNames(is, uedgesets.back().items);
02197 } else if (current == "@nodes") {
02198 readItemNames(is, nodes.back().items);
02199 } else if (current == "@edges") {
02200 readItemNames(is, edges.back().items);
02201 } else if (current == "@uedges") {
02202 readItemNames(is, uedges.back().items);
02203 } else if (current == "@attributes") {
02204 readItemNames(is, attributes.back().items);
02205 }
02206 }
02207
02208 private:
02209
02210 void readMapNames(std::istream& is, std::vector<std::string>& maps) {
02211 std::string line, name;
02212 std::getline(is, line);
02213 std::istringstream ls(line);
02214 while (ls >> name) {
02215 maps.push_back(name);
02216 }
02217 while (getline(is, line));
02218 }
02219
02220 void readItemNames(std::istream& is, std::vector<std::string>& maps) {
02221 std::string line, name;
02222 while (std::getline(is, line)) {
02223 std::istringstream ls(line);
02224 ls >> name;
02225 maps.push_back(name);
02226 }
02227 }
02228
02229 struct SectionInfo {
02230 std::string name;
02231 std::vector<std::string> items;
02232
02233 SectionInfo(const std::string& _name) : name(_name) {}
02234 };
02235
02236 std::vector<SectionInfo> nodesets;
02237 std::vector<SectionInfo> edgesets;
02238 std::vector<SectionInfo> uedgesets;
02239
02240 std::vector<SectionInfo> nodes;
02241 std::vector<SectionInfo> edges;
02242 std::vector<SectionInfo> uedges;
02243
02244 std::vector<SectionInfo> attributes;
02245
02246 std::vector<std::string> sections;
02247
02248 std::string current;
02249
02250 };
02251
02252 }
02253 #endif