Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

lemon_reader.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00020 
00021 
00022 #ifndef LEMON_LEMON_READER_H
00023 #define LEMON_LEMON_READER_H
00024 
00025 
00026 #include <iostream>
00027 #include <fstream>
00028 #include <string>
00029 #include <vector>
00030 #include <algorithm>
00031 #include <map>
00032 #include <memory>
00033 
00034 #include <lemon/error.h>
00035 #include <lemon/graph_utils.h>
00036 #include <lemon/utility.h>
00037 #include <lemon/bits/item_reader.h>
00038 
00039 #include <lemon/concept_check.h>
00040 #include <lemon/concept/maps.h>
00041 
00042 namespace lemon {
00043 
00044   namespace _reader_bits {
00045 
00046     template <typename Item>
00047     class ItemIdReader {
00048     public:
00049 
00050       bool isIdReader() { return true; }
00051 
00052       void readId(std::istream&, Item&) {}
00053       
00054       template <class _ItemIdReader>
00055       struct Constraints {
00056         void constraints() {
00057           bool b = reader.isIdReader();
00058           ignore_unused_variable_warning(b);
00059           Item item;
00060           reader.readId(is, item);
00061         }
00062         _ItemIdReader& reader;
00063         std::istream& is;
00064       };
00065 
00066     };
00067 
00068     template <typename Item>
00069     class ItemReader {
00070     public:
00071       void read(std::istream&, Item&) {}
00072       
00073       template <class _ItemReader>
00074       struct Constraints {
00075         void constraints() {
00076           Item item;
00077           reader.read(is, item);
00078         }
00079         _ItemReader& reader;
00080         std::istream& is;
00081       };
00082 
00083     };
00084   
00085     template <typename T>
00086     bool operator<(T, T) {
00087       throw DataFormatError("Id is not comparable");
00088     }
00089 
00090     template <typename T>
00091     struct Less {
00092       bool operator()(const T& p, const T& q) const {
00093         return p < q;
00094       }
00095     };
00096 
00097     template <typename M1, typename M2>
00098     class WriteComposeMap {
00099     public:
00100       typedef True NeedCopy;
00101       
00102       typedef typename M2::Key Key;
00103       typedef typename M1::Value Value;
00104 
00105       WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2) 
00106         : m1(_m1), m2(_m2) {}
00107       
00108       void set(const Key& key, const Value& value) {
00109         m1.set(m2[key], value);
00110       }
00111 
00112     private:
00113       
00114       typename SmartReference<M1>::Type m1;
00115       typename SmartConstReference<M2>::Type m2;
00116       
00117     };
00118 
00119     template <typename M1, typename M2>
00120     WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
00121       return WriteComposeMap<M1, M2>(m1, m2);
00122     }
00123 
00124     template <typename M1, typename M2>
00125     WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
00126       return WriteComposeMap<M1, M2>(m1, m2);
00127     }
00128   
00129   }
00130 
00161   class LemonReader {
00162   private:
00163     
00164     class FilterStreamBuf : public std::streambuf {
00165     public:
00166 
00167       typedef std::streambuf Parent;
00168       typedef Parent::char_type char_type;
00169       FilterStreamBuf(std::istream& is, int& num) 
00170         : _is(is), _base(0), _eptr(0), 
00171           _num(num), skip_state(after_endl) {}
00172 
00173     protected:
00174 
00175       enum skip_state_type {
00176         no_skip,
00177         after_endl,
00178         comment_line
00179       };
00180 
00181       char_type small_buf[1];
00182 
00183 
00184       std::istream& _is;
00185 
00186       char_type* _base;
00187       char_type* _eptr;
00188 
00189       int& _num;
00190 
00191       skip_state_type skip_state;
00192 
00193 
00194       char_type* base() { return _base; }
00195 
00196       char_type* eptr() { return _eptr; }
00197 
00198       int blen() { return _eptr - _base; }
00199 
00200       void setb(char_type* buf, int len) {
00201         _base = buf;
00202         _eptr = buf + len;
00203       }
00204   
00205       virtual std::streambuf* setbuf(char *buf, int len) {
00206         if (base()) return 0;
00207         if (buf != 0 && len >= (int)sizeof(small_buf)) {
00208           setb(buf, len);
00209         } else {
00210           setb(small_buf, sizeof(small_buf));
00211         }
00212         setg(0, 0, 0);
00213         return this;
00214       }
00215 
00216       bool put_char(char c) {
00217         switch (skip_state) {
00218         case no_skip:
00219           switch (c) {
00220           case '\n': 
00221             skip_state = after_endl;
00222             return true;
00223           default:
00224             return true;
00225           }
00226         case after_endl:
00227           switch (c) {
00228           case '@':
00229             return false;
00230           case '\n': 
00231             return false;
00232           case '#':
00233             skip_state = comment_line;
00234             return false;
00235           default:
00236             if (!isspace(c)) {
00237               skip_state = no_skip;
00238               return true;
00239             } else {
00240               return false;
00241             }
00242           }
00243           break;
00244         case comment_line:
00245           switch (c) {
00246           case '\n': 
00247             skip_state = after_endl;
00248             return false;
00249           default:
00250             return false;
00251           }
00252         }
00253         return false;
00254       }
00255 
00256       virtual int underflow() {
00257         char c;
00258         if (_is.read(&c, 1)) {
00259           _is.putback(c);
00260           if (c == '@') {
00261             return EOF;
00262           }
00263         } else {
00264           return EOF;
00265         }
00266         char_type *ptr;
00267         for (ptr = base(); ptr != eptr(); ++ptr) {
00268           if (_is.read(&c, 1)) {
00269             if (c == '\n') ++_num;
00270             if (put_char(c)) {
00271               *ptr = c;
00272             } else {
00273               if (skip_state == after_endl && c == '@') {
00274                 _is.putback('@');
00275                 break;
00276               }
00277               --ptr;
00278             }
00279           } else {
00280             break;
00281           }
00282         }
00283         setg(base(), base(), ptr);
00284         return *base();
00285       }
00286 
00287       virtual int sync() {
00288         return EOF;
00289       }
00290     };
00291 
00292   public:
00293 
00302     class SectionReader {
00303       friend class LemonReader;
00304     protected:
00309       SectionReader(LemonReader& reader) {
00310         reader.attach(*this);
00311       }
00312 
00313       virtual ~SectionReader() {}
00314 
00320       virtual bool header(const std::string& line) = 0;
00321 
00325       virtual void read(std::istream& is) = 0;
00326     };
00327 
00331     LemonReader(std::istream& _is) 
00332       : is(&_is), own_is(false) {}
00333 
00337     LemonReader(const std::string& filename) 
00338       : is(0), own_is(true) {
00339       is = new std::ifstream(filename.c_str());
00340     }
00341 
00345     ~LemonReader() {
00346       if (own_is) {
00347         delete is;
00348       }
00349     }
00350 
00351   private:
00352     LemonReader(const LemonReader&);
00353     void operator=(const LemonReader&);
00354 
00355     void attach(SectionReader& reader) {
00356       readers.push_back(&reader);
00357     }
00358 
00359   public:
00363     void run() {
00364       int line_num = 0;
00365       std::string line;
00366       try {
00367         while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
00368           SectionReaders::iterator it;
00369           for (it = readers.begin(); it != readers.end(); ++it) {
00370             if ((*it)->header(line)) {
00371               char buf[2048];
00372               FilterStreamBuf buffer(*is, line_num);
00373               buffer.pubsetbuf(buf, sizeof(buf));
00374               std::istream is(&buffer);
00375               (*it)->read(is);
00376               break;
00377             }
00378           }
00379         }
00380       } catch (DataFormatError& error) {
00381         error.line(line_num);
00382         throw error;
00383       } 
00384     }
00385 
00386 
00387   private:
00388 
00389     std::istream* is;
00390     bool own_is;
00391 
00392     typedef std::vector<SectionReader*> SectionReaders;
00393     SectionReaders readers;
00394 
00395   };
00396 
00400   class CommonSectionReaderBase : public LemonReader::SectionReader {
00401     typedef LemonReader::SectionReader Parent;
00402   protected:
00403     
00408     CommonSectionReaderBase(LemonReader& _reader) 
00409       : Parent(_reader) {}
00410 
00411     template <typename _Item>
00412     class ReaderBase;
00413     
00414     template <typename _Item>
00415     class InverterBase : public ReaderBase<_Item> {
00416     public:
00417       typedef _Item Item;
00418       virtual void read(std::istream&, const Item&) = 0;
00419       virtual Item read(std::istream&) const = 0;
00420 
00421       virtual InverterBase<_Item>* getInverter() {
00422         return this;
00423       }
00424     };
00425 
00426     template <typename _Item, typename _Map, typename _Reader>
00427     class MapReaderInverter : public InverterBase<_Item> {
00428     public:
00429       typedef _Item Item;
00430       typedef _Reader Reader;
00431       typedef typename Reader::Value Value;
00432       typedef _Map Map;
00433       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00434 
00435       typename SmartReference<Map>::Type map;
00436       Reader reader;
00437       Inverse inverse;
00438 
00439       MapReaderInverter(typename SmartParameter<Map>::Type _map,
00440                         const Reader& _reader) 
00441         : map(_map), reader(_reader) {}
00442 
00443       virtual ~MapReaderInverter() {}
00444 
00445       virtual void read(std::istream& is, const Item& item) {
00446         Value value;
00447         reader.read(is, value);
00448         map.set(item, value);
00449         typename Inverse::iterator it = inverse.find(value);
00450         if (it == inverse.end()) {
00451           inverse.insert(std::make_pair(value, item));
00452         } else {
00453           throw DataFormatError("Multiple ID occurence");
00454         }
00455       }
00456 
00457       virtual Item read(std::istream& is) const {
00458         Value value;
00459         reader.read(is, value); 
00460         typename Inverse::const_iterator it = inverse.find(value);
00461         if (it != inverse.end()) {
00462           return it->second;
00463         } else {
00464           throw DataFormatError("Invalid ID error");
00465         }
00466       }      
00467     };
00468 
00469     template <typename _Item, typename _Reader>
00470     class SkipReaderInverter : public InverterBase<_Item> {
00471     public:
00472       typedef _Item Item;
00473       typedef _Reader Reader;
00474       typedef typename Reader::Value Value;
00475       typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
00476 
00477       Reader reader;
00478 
00479       SkipReaderInverter(const Reader& _reader) 
00480         : reader(_reader) {}
00481 
00482       virtual ~SkipReaderInverter() {}
00483 
00484       virtual void read(std::istream& is, const Item& item) {
00485         Value value;
00486         reader.read(is, value);
00487         typename Inverse::iterator it = inverse.find(value);
00488         if (it == inverse.end()) {
00489           inverse.insert(std::make_pair(value, item));
00490         } else {
00491           throw DataFormatError("Multiple ID occurence error");
00492         }
00493       }
00494 
00495       virtual Item read(std::istream& is) const {
00496         Value value;
00497         reader.read(is, value); 
00498         typename Inverse::const_iterator it = inverse.find(value);
00499         if (it != inverse.end()) {
00500           return it->second;
00501         } else {
00502           throw DataFormatError("Invalid ID error");
00503         }
00504       }
00505 
00506     private:
00507       Inverse inverse;
00508     };
00509 
00510     template <typename _Item>    
00511     class ReaderBase {
00512     public:
00513       typedef _Item Item;
00514 
00515       virtual ~ReaderBase() {}
00516 
00517       virtual void read(std::istream& is, const Item& item) = 0;
00518       virtual InverterBase<_Item>* getInverter() = 0;
00519     };
00520 
00521     template <typename _Item, typename _Map, typename _Reader>
00522     class MapReader : public ReaderBase<_Item> {
00523     public:
00524       typedef _Map Map;
00525       typedef _Reader Reader;
00526       typedef typename Reader::Value Value;
00527       typedef _Item Item;
00528       
00529       typename SmartReference<Map>::Type map;
00530       Reader reader;
00531 
00532       MapReader(typename SmartParameter<Map>::Type _map, 
00533                 const Reader& _reader) 
00534         : map(_map), reader(_reader) {}
00535 
00536       virtual ~MapReader() {}
00537 
00538       virtual void read(std::istream& is, const Item& item) {
00539         Value value;
00540         reader.read(is, value);
00541         map.set(item, value);
00542       }
00543 
00544       virtual InverterBase<_Item>* getInverter() {
00545         return new MapReaderInverter<Item, Map, Reader>(map, reader);
00546       }
00547     };
00548 
00549 
00550     template <typename _Item, typename _Reader>
00551     class SkipReader : public ReaderBase<_Item> {
00552     public:
00553       typedef _Reader Reader;
00554       typedef typename Reader::Value Value;
00555       typedef _Item Item;
00556 
00557       Reader reader;
00558       SkipReader(const Reader& _reader) : reader(_reader) {}
00559 
00560       virtual ~SkipReader() {}
00561 
00562       virtual void read(std::istream& is, const Item&) {
00563         Value value;
00564         reader.read(is, value);
00565       }      
00566 
00567       virtual InverterBase<Item>* getInverter() {
00568         return new SkipReaderInverter<Item, Reader>(reader);
00569       }
00570     };
00571 
00572     template <typename _Item>
00573     class IdReaderBase {
00574     public:
00575       typedef _Item Item;
00576       virtual ~IdReaderBase() {}
00577       virtual Item read(std::istream& is) const = 0;
00578       virtual bool isIdReader() const = 0;
00579     };
00580 
00581     template <typename _Item, typename _BoxedIdReader>
00582     class IdReader : public IdReaderBase<_Item> {
00583     public:
00584       typedef _Item Item;
00585       typedef _BoxedIdReader BoxedIdReader;
00586       
00587       const BoxedIdReader& boxedIdReader;
00588 
00589       IdReader(const BoxedIdReader& _boxedIdReader) 
00590         : boxedIdReader(_boxedIdReader) {}
00591 
00592       virtual Item read(std::istream& is) const {
00593         Item item;
00594         boxedIdReader.readId(is, item);
00595         return item;
00596       }
00597 
00598       virtual bool isIdReader() const {
00599         return boxedIdReader.isIdReader();
00600       }
00601     };
00602 
00603     class ValueReaderBase {
00604     public:
00605       virtual void read(std::istream&) {};
00606       virtual ~ValueReaderBase() {}
00607     };
00608 
00609     template <typename _Value, typename _Reader>
00610     class ValueReader : public ValueReaderBase {
00611     public:
00612       typedef _Value Value;
00613       typedef _Reader Reader;
00614 
00615       ValueReader(Value& _value, const Reader& _reader)
00616         : value(_value), reader(_reader) {}
00617 
00618       virtual void read(std::istream& is) {
00619         reader.read(is, value);
00620       }
00621     private:
00622       Value& value;
00623       Reader reader;
00624     };
00625     
00626   };
00627 
00645   template <typename _Graph, typename _Traits = DefaultReaderTraits>
00646   class NodeSetReader : public CommonSectionReaderBase {
00647     typedef CommonSectionReaderBase Parent;
00648   public:
00649 
00650     typedef _Graph Graph;
00651     typedef _Traits Traits;
00652     typedef typename Graph::Node Node;
00653     typedef typename Traits::Skipper DefaultSkipper;
00654 
00661     NodeSetReader(LemonReader& _reader, 
00662                   typename SmartParameter<Graph>::Type _graph, 
00663                   const std::string& _id = std::string(),
00664                   const DefaultSkipper& _skipper = DefaultSkipper()) 
00665       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {} 
00666 
00667 
00671     virtual ~NodeSetReader() {
00672       for (typename MapReaders::iterator it = readers.begin(); 
00673            it != readers.end(); ++it) {
00674         delete it->second;
00675       }
00676     }
00677 
00678   private:
00679     NodeSetReader(const NodeSetReader&);
00680     void operator=(const NodeSetReader&);
00681   
00682   public:
00683 
00687     template <typename Map>
00688     NodeSetReader& readNodeMap(std::string name, Map& map) {
00689       return _readMap<
00690         typename Traits::template Reader<typename Map::Value>, Map,
00691         typename SmartParameter<Map>::Type>(name, map);
00692     }
00693 
00694     template <typename Map>
00695     NodeSetReader& readNodeMap(std::string name, const Map& map) {
00696       return _readMap<
00697         typename Traits::template Reader<typename Map::Value>, Map,
00698         typename SmartParameter<Map>::Type>(name, map);
00699     }
00700 
00704     template <typename Reader, typename Map>
00705     NodeSetReader& readNodeMap(std::string name, Map& map, 
00706                                const Reader& reader = Reader()) {
00707       return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
00708         (name, map, reader);
00709     }
00710 
00711     template <typename Reader, typename Map>
00712     NodeSetReader& readNodeMap(std::string name, const Map& map, 
00713                                const Reader& reader = Reader()) {
00714       return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
00715         (name, map, reader);
00716     }
00717 
00718   private:
00719 
00720     template <typename Reader, typename Map, typename MapParameter>
00721     NodeSetReader& _readMap(std::string name, MapParameter map, 
00722                             const Reader& reader = Reader()) {
00723       checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
00724       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
00725       if (readers.find(name) != readers.end()) {
00726         ErrorMessage msg;
00727         msg << "Multiple read rule for node map: " << name;
00728         throw IOParameterError(msg.message());
00729       }
00730       readers.insert(
00731         make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
00732       return *this;
00733     }
00734 
00735   public:
00736 
00740     template <typename Reader>
00741     NodeSetReader& skipNodeMap(std::string name, 
00742                            const Reader& reader = Reader()) {
00743       if (readers.find(name) != readers.end()) {
00744         ErrorMessage msg;
00745         msg << "Multiple read rule for node map: " << name;
00746         throw IOParameterError(msg.message());
00747       }
00748       readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
00749       return *this;
00750     }
00751 
00752   protected:
00753 
00759     virtual bool header(const std::string& line) {
00760       std::istringstream ls(line);
00761       std::string command;
00762       std::string name;
00763       ls >> command >> name;
00764       return command == "@nodeset" && name == id;
00765     }
00766 
00770     virtual void read(std::istream& is) {
00771       std::vector<ReaderBase<Node>* > index;
00772       std::string line;
00773 
00774       getline(is, line);
00775       std::istringstream ls(line);      
00776       while (ls >> id) {
00777         typename MapReaders::iterator it = readers.find(id);
00778         if (it != readers.end()) {
00779           index.push_back(it->second);
00780         } else {
00781           index.push_back(&skipper);
00782         }
00783         if (id == "id" && inverter.get() == 0) {
00784           inverter.reset(index.back()->getInverter());
00785           index.back() = inverter.get();
00786         }
00787       }
00788       while (getline(is, line)) {       
00789         Node node = graph.addNode();
00790         std::istringstream ls(line);
00791         for (int i = 0; i < (int)index.size(); ++i) {
00792           index[i]->read(ls, node);
00793         }
00794       }
00795     }
00796 
00797   public:
00798 
00803     bool isIdReader() const {
00804       return inverter.get() != 0;
00805     }
00806 
00811     void readId(std::istream& is, Node& node) const {
00812       node = inverter->read(is);
00813     } 
00814 
00815   private:
00816 
00817     typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
00818     MapReaders readers;
00819    
00820     typename SmartReference<Graph>::Type graph;   
00821     std::string id;
00822     SkipReader<Node, DefaultSkipper> skipper;
00823 
00824     std::auto_ptr<InverterBase<Node> > inverter;
00825   };
00826 
00849   template <typename _Graph, typename _Traits = DefaultReaderTraits>
00850   class EdgeSetReader : public CommonSectionReaderBase {
00851     typedef CommonSectionReaderBase Parent;
00852   public:
00853 
00854     typedef _Graph Graph;
00855     typedef _Traits Traits;
00856     typedef typename Graph::Node Node;
00857     typedef typename Graph::Edge Edge;
00858     typedef typename Traits::Skipper DefaultSkipper;
00859 
00868     template <typename NodeIdReader>
00869     EdgeSetReader(LemonReader& _reader, 
00870                   typename SmartParameter<Graph>::Type _graph, 
00871                   const NodeIdReader& _nodeIdReader, 
00872                   const std::string& _id = std::string(),
00873                   const DefaultSkipper& _skipper = DefaultSkipper()) 
00874       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
00875       checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
00876       nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
00877     }
00881     virtual ~EdgeSetReader() {
00882       for (typename MapReaders::iterator it = readers.begin(); 
00883            it != readers.end(); ++it) {
00884         delete it->second;
00885       }
00886     }
00887 
00888   private:
00889     EdgeSetReader(const EdgeSetReader&);
00890     void operator=(const EdgeSetReader&);
00891 
00892   public:
00893 
00897     template <typename Map>
00898     EdgeSetReader& readEdgeMap(std::string name, Map& map) {
00899       return _readMap<
00900         typename Traits::template Reader<typename Map::Value>, Map,
00901         typename SmartParameter<Map>::Type>(name, map);
00902     }
00903 
00904     template <typename Map>
00905     EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
00906       return _readMap<
00907         typename Traits::template Reader<typename Map::Value>, Map,
00908         typename SmartParameter<Map>::Type>(name, map);
00909     }
00910 
00914     template <typename Reader, typename Map>
00915     EdgeSetReader& readEdgeMap(std::string name, Map& map, 
00916                            const Reader& reader = Reader()) {
00917       return _readMap<Reader, Map,
00918         typename SmartParameter<Map>::Type>(name, map, reader);
00919     }
00920 
00921     template <typename Reader, typename Map>
00922     EdgeSetReader& readEdgeMap(std::string name, const Map& map, 
00923                                const Reader& reader = Reader()) {
00924       return _readMap<Reader, Map,
00925         typename SmartParameter<Map>::Type>(name, map, reader);
00926     }
00927 
00928   private:
00929 
00930     template <typename Reader, typename Map, typename MapParameter>
00931     EdgeSetReader& _readMap(std::string name, MapParameter map, 
00932                             const Reader& reader = Reader()) {
00933       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
00934       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
00935       if (readers.find(name) != readers.end()) {
00936         ErrorMessage msg;
00937         msg << "Multiple read rule for edge map: " << name;
00938         throw IOParameterError(msg.message());
00939       }
00940       readers.insert(
00941         make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
00942       return *this;
00943     }
00944 
00945   public:
00946 
00950     template <typename Reader>
00951     EdgeSetReader& skipEdgeMap(std::string name, 
00952                                const Reader& reader = Reader()) {
00953       if (readers.find(name) != readers.end()) {
00954         ErrorMessage msg;
00955         msg << "Multiple read rule for edge map: " << name;
00956         throw IOParameterError(msg.message());
00957       }
00958       readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
00959       return *this;
00960     }
00961 
00962   protected:
00963 
00969     virtual bool header(const std::string& line) {
00970       std::istringstream ls(line);
00971       std::string command;
00972       std::string name;
00973       ls >> command >> name;
00974       return command == "@edgeset" && name == id;
00975     }
00976 
00980     virtual void read(std::istream& is) {
00981       if (!nodeIdReader->isIdReader()) {
00982         throw DataFormatError("Cannot find nodeset or ID map");
00983       }
00984       std::vector<ReaderBase<Edge>* > index;
00985       std::string line;
00986 
00987       getline(is, line);
00988       std::istringstream ls(line);      
00989       while (ls >> id) {
00990         typename MapReaders::iterator it = readers.find(id);
00991         if (it != readers.end()) {
00992           index.push_back(it->second);
00993         } else {
00994           index.push_back(&skipper);
00995         }
00996         if (id == "id" && inverter.get() == 0) {
00997           inverter.reset(index.back()->getInverter());
00998           index.back() = inverter.get();
00999         }
01000       }
01001       while (getline(is, line)) {       
01002         std::istringstream ls(line);
01003         Node from = nodeIdReader->read(ls);
01004         Node to = nodeIdReader->read(ls);
01005         Edge edge = graph.addEdge(from, to);
01006         for (int i = 0; i < (int)index.size(); ++i) {
01007           index[i]->read(ls, edge);
01008         }
01009       }
01010     }
01011 
01012   public:
01013 
01018     bool isIdReader() const {
01019       return inverter.get() != 0;
01020     }
01021 
01026     void readId(std::istream& is, Edge& edge) const {
01027       edge = inverter->read(is);
01028     } 
01029 
01030   private:
01031 
01032     typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
01033     MapReaders readers;
01034    
01035     typename SmartReference<Graph>::Type graph;   
01036     std::string id;
01037     SkipReader<Edge, DefaultSkipper> skipper;
01038 
01039     std::auto_ptr<InverterBase<Edge> > inverter;
01040     std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
01041   };
01042 
01070   template <typename _Graph, typename _Traits = DefaultReaderTraits>
01071   class UndirEdgeSetReader : public CommonSectionReaderBase {
01072     typedef CommonSectionReaderBase Parent;
01073   public:
01074 
01075     typedef _Graph Graph;
01076     typedef _Traits Traits;
01077     typedef typename Graph::Node Node;
01078     typedef typename Graph::Edge Edge;
01079     typedef typename Graph::UndirEdge UndirEdge;
01080     typedef typename Traits::Skipper DefaultSkipper;
01081 
01090     template <typename NodeIdReader>
01091     UndirEdgeSetReader(LemonReader& _reader, 
01092                        typename SmartParameter<Graph>::Type _graph, 
01093                        const NodeIdReader& _nodeIdReader, 
01094                        const std::string& _id = std::string(),
01095                        const DefaultSkipper& _skipper = DefaultSkipper()) 
01096       : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
01097       checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
01098       nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
01099     }
01103     virtual ~UndirEdgeSetReader() {
01104       for (typename MapReaders::iterator it = readers.begin(); 
01105            it != readers.end(); ++it) {
01106         delete it->second;
01107       }
01108     }
01109 
01110   private:
01111     UndirEdgeSetReader(const UndirEdgeSetReader&);
01112     void operator=(const UndirEdgeSetReader&);
01113 
01114   public:
01115 
01119     template <typename Map>
01120     UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
01121       return _readMap<
01122         typename Traits::template Reader<typename Map::Value>, Map, 
01123         typename SmartParameter<Map>::Type>(name, map);
01124     }
01125 
01126     template <typename Map>
01127     UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
01128       return _readMap<
01129         typename Traits::template Reader<typename Map::Value>, Map, 
01130         typename SmartParameter<Map>::Type>(name, map);
01131     }
01132 
01136     template <typename Reader, typename Map>
01137     UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map, 
01138                                          const Reader& reader = Reader()) {
01139       return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
01140         (name, map, reader);
01141     }
01142 
01143     template <typename Reader, typename Map>
01144     UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map, 
01145                                          const Reader& reader = Reader()) {
01146       return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
01147         (name, map, reader);
01148     }
01149 
01150   private:
01151 
01152     template <typename Reader, typename Map, typename MapParameter>
01153     UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
01154                                  const Reader& reader = Reader()) {
01155       checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>();
01156       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01157       if (readers.find(name) != readers.end()) {
01158         ErrorMessage msg;
01159         msg << "Multiple read rule for edge map: " << name;
01160         throw IOParameterError(msg.message());
01161       }
01162       readers.insert(
01163         make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
01164       return *this;
01165     }
01166 
01167   public:
01168 
01172     template <typename Reader>
01173     UndirEdgeSetReader& skipUndirEdgeMap(std::string name, 
01174                                          const Reader& reader = Reader()) {
01175       if (readers.find(name) != readers.end()) {
01176         ErrorMessage msg;
01177         msg << "Multiple read rule for node map: " << name;
01178         throw IOParameterError(msg.message());
01179       }
01180       readers.insert(make_pair(name, 
01181                                new SkipReader<UndirEdge, Reader>(reader)));
01182       return *this;
01183     }
01184 
01188     template <typename Map>
01189     UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
01190       return _readDirMap<
01191         typename Traits::template Reader<typename Map::Value>, Map,
01192         typename SmartParameter<Map>::Type>(name, map);
01193     }
01194 
01195     template <typename Map>
01196     UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
01197       return _readDirMap<
01198         typename Traits::template Reader<typename Map::Value>, Map,
01199         typename SmartParameter<Map>::Type>(name, map);
01200     }
01201 
01205     template <typename Reader, typename Map>
01206     UndirEdgeSetReader& readEdgeMap(std::string name, Map& map, 
01207                                     const Reader& reader = Reader()) {
01208       return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
01209         (name, map, reader);
01210     }
01211 
01212     template <typename Reader, typename Map>
01213     UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map, 
01214                                     const Reader& reader = Reader()) {
01215       return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
01216         (name, map, reader);
01217     }
01218 
01219   private:
01220 
01221     template <typename Reader, typename Map, typename MapParameter>
01222     UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
01223                                     const Reader& reader = Reader()) { 
01224       checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>();
01225       checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
01226       readMap("+" + name, 
01227               _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
01228       readMap("-" + name, 
01229               _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
01230       return *this;      
01231     }
01232 
01233   public:
01234 
01238     template <typename Reader>
01239     UndirEdgeSetReader& skipEdgeMap(std::string name, 
01240                                     const Reader& reader = Reader()) {
01241       skipMap("+" + name, reader);
01242       skipMap("-" + name, reader);
01243       return *this;
01244     }
01245 
01246   protected:
01247 
01253     virtual bool header(const std::string& line) {
01254       std::istringstream ls(line);
01255       std::string command;
01256       std::string name;
01257       ls >> command >> name;
01258       return command == "@undiredgeset" && name == id;
01259     }
01260 
01264     virtual void read(std::istream& is) {
01265       if (!nodeIdReader->isIdReader()) {
01266         throw DataFormatError("Cannot find nodeset or ID map");
01267       }
01268       std::vector<ReaderBase<UndirEdge>* > index;
01269       std::string line;
01270 
01271       getline(is, line);
01272       std::istringstream ls(line);      
01273       while (ls >> id) {
01274         typename MapReaders::iterator it = readers.find(id);
01275         if (it != readers.end()) {
01276           index.push_back(it->second);
01277         } else {
01278           index.push_back(&skipper);
01279         }
01280         if (id == "id" && inverter.get() == 0) {
01281           inverter.reset(index.back()->getInverter());
01282           index.back() = inverter.get();
01283         }
01284       }
01285       while (getline(is, line)) {       
01286         std::istringstream ls(line);
01287         Node from = nodeIdReader->read(ls);
01288         Node to = nodeIdReader->read(ls);
01289         UndirEdge edge = graph.addEdge(from, to);
01290         for (int i = 0; i < (int)index.size(); ++i) {
01291           index[i]->read(ls, edge);
01292         }
01293       }
01294     }
01295 
01296   public:
01297 
01302     bool isIdReader() const {
01303       return inverter.get() != 0;
01304     }
01305 
01310     void readId(std::istream& is, UndirEdge& undirEdge) const {
01311       undirEdge = inverter->read(is);
01312     } 
01313 
01320     void readId(std::istream& is, Edge& edge) const {
01321       char c;
01322       is >> c;
01323       UndirEdge undirEdge = inverter->read(is);
01324       if (c == '+') {
01325         edge = graph.direct(undirEdge, true);
01326       } else if (c == '-') {
01327         edge = graph.direct(undirEdge, false);
01328       } else {
01329         throw DataFormatError("Wrong id format for edge "
01330                               "in undirected edgeset");
01331       }
01332     } 
01333 
01334   private:
01335 
01336     typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
01337     MapReaders readers;
01338    
01339     typename SmartReference<Graph>::Type graph;   
01340     std::string id;
01341     SkipReader<UndirEdge, DefaultSkipper> skipper;
01342 
01343     std::auto_ptr<InverterBase<UndirEdge> > inverter;
01344     std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
01345   };
01346 
01357   template <typename _Graph>
01358   class NodeReader : public CommonSectionReaderBase {
01359     typedef CommonSectionReaderBase Parent;
01360     typedef _Graph Graph;
01361     typedef typename Graph::Node Node;
01362   public:
01363     
01370     template <typename _IdReader>
01371     NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
01372                const std::string& _id = std::string()) 
01373       : Parent(_reader), id(_id) {
01374       checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
01375       nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader));
01376     }
01377 
01381     virtual ~NodeReader() {}
01382 
01383   private:
01384     NodeReader(const NodeReader&);
01385     void operator=(const NodeReader&);
01386 
01387   public:
01388 
01392     void readNode(const std::string& name, Node& item) {
01393       if (readers.find(name) != readers.end()) {
01394         ErrorMessage msg;
01395         msg << "Multiple read rule for node: " << name;
01396         throw IOParameterError(msg.message());
01397       }
01398       readers.insert(make_pair(name, &item));
01399     }
01400 
01401   protected:
01402 
01408     virtual bool header(const std::string& line) {
01409       std::istringstream ls(line);
01410       std::string command;
01411       std::string name;
01412       ls >> command >> name;
01413       return command == "@nodes" && name == id;
01414     }
01415 
01419     virtual void read(std::istream& is) {
01420       if (!nodeIdReader->isIdReader()) {
01421         throw DataFormatError("Cannot find nodeset or ID map");
01422       }
01423       std::string line;
01424       while (getline(is, line)) {
01425         std::istringstream ls(line);
01426         std::string id;
01427         ls >> id;
01428         typename NodeReaders::iterator it = readers.find(id);
01429         if (it != readers.end()) {
01430           *(it->second) = nodeIdReader->read(ls); 
01431         }       
01432       }
01433     }
01434     
01435   private:
01436 
01437     std::string id;
01438 
01439     typedef std::map<std::string, Node*> NodeReaders;
01440     NodeReaders readers;
01441     std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
01442   };
01443 
01454   template <typename _Graph>
01455   class EdgeReader : public CommonSectionReaderBase {
01456     typedef CommonSectionReaderBase Parent;
01457     typedef _Graph Graph;
01458     typedef typename Graph::Edge Edge;
01459   public:
01460     
01467     template <typename _IdReader>
01468     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
01469                const std::string& _id = std::string()) 
01470       : Parent(_reader), id(_id) {
01471       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
01472       edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
01473     }
01474 
01478     virtual ~EdgeReader() {}
01479   private:
01480     EdgeReader(const EdgeReader&);
01481     void operator=(const EdgeReader&);
01482 
01483   public:
01484 
01488     void readEdge(const std::string& name, Edge& item) {
01489       if (readers.find(name) != readers.end()) {
01490         ErrorMessage msg;
01491         msg << "Multiple read rule for edge: " << name;
01492         throw IOParameterError(msg.message());
01493       }
01494       readers.insert(make_pair(name, &item));
01495     }
01496 
01497   protected:
01498 
01504     virtual bool header(const std::string& line) {
01505       std::istringstream ls(line);
01506       std::string command;
01507       std::string name;
01508       ls >> command >> name;
01509       return command == "@edges" && name == id;
01510     }
01511 
01515     virtual void read(std::istream& is) {
01516       if (!edgeIdReader->isIdReader()) {
01517         throw DataFormatError("Cannot find edgeset or ID map");
01518       }
01519       std::string line;
01520       while (getline(is, line)) {
01521         std::istringstream ls(line);
01522         std::string id;
01523         ls >> id;
01524         typename EdgeReaders::iterator it = readers.find(id);
01525         if (it != readers.end()) {
01526           *(it->second) = edgeIdReader->read(ls); 
01527         }       
01528       }
01529     }
01530     
01531   private:
01532 
01533     std::string id;
01534 
01535     typedef std::map<std::string, Edge*> EdgeReaders;
01536     EdgeReaders readers;
01537     std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
01538   };
01539 
01550   template <typename _Graph>
01551   class UndirEdgeReader : public CommonSectionReaderBase {
01552     typedef CommonSectionReaderBase Parent;
01553     typedef _Graph Graph;
01554     typedef typename Graph::Edge Edge;
01555     typedef typename Graph::UndirEdge UndirEdge;
01556   public:
01557     
01565     template <typename _IdReader>
01566     UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
01567                const std::string& _id = std::string()) 
01568       : Parent(_reader), id(_id) {
01569       checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
01570       checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
01571       undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader));
01572       edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
01573     }
01574 
01578     virtual ~UndirEdgeReader() {}
01579   private:
01580     UndirEdgeReader(const UndirEdgeReader&);
01581     void operator=(const UndirEdgeReader&);
01582 
01583   public:
01584 
01588     void readUndirEdge(const std::string& name, UndirEdge& item) {
01589       if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) {
01590         ErrorMessage msg;
01591         msg << "Multiple read rule for undirected edge: " << name;
01592         throw IOParameterError(msg.message());
01593       }
01594       undirEdgeReaders.insert(make_pair(name, &item));
01595     }
01596 
01600     void readEdge(const std::string& name, Edge& item) {
01601       if (edgeReaders.find(name) != edgeReaders.end()) {
01602         ErrorMessage msg;
01603         msg << "Multiple read rule for edge: " << name;
01604         throw IOParameterError(msg.message());
01605       }
01606       edgeReaders.insert(make_pair(name, &item));
01607     }
01608 
01609   protected:
01610 
01616     virtual bool header(const std::string& line) {
01617       std::istringstream ls(line);
01618       std::string command;
01619       std::string name;
01620       ls >> command >> name;
01621       return command == "@undiredges" && name == id;
01622     }
01623 
01627     virtual void read(std::istream& is) {
01628       if (!edgeIdReader->isIdReader()) {
01629         throw DataFormatError("Cannot find undirected edgeset or ID map");
01630       }
01631       if (!undirEdgeIdReader->isIdReader()) {
01632         throw DataFormatError("Cannot find undirected edgeset or ID map");
01633       }
01634       std::string line;
01635       while (getline(is, line)) {
01636         std::istringstream ls(line);
01637         std::string id;
01638         ls >> id;
01639         {
01640           typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
01641           if (it != undirEdgeReaders.end()) {
01642             *(it->second) = undirEdgeIdReader->read(ls); 
01643             break;
01644           }     
01645         } {
01646           typename EdgeReaders::iterator it = edgeReaders.find(id);
01647           if (it != edgeReaders.end()) {
01648             *(it->second) = edgeIdReader->read(ls); 
01649             break;
01650           }     
01651         }
01652       }
01653     }
01654     
01655   private:
01656 
01657     std::string id;
01658 
01659     typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
01660     UndirEdgeReaders undirEdgeReaders;
01661     std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
01662 
01663     typedef std::map<std::string, Edge*> EdgeReaders;
01664     EdgeReaders edgeReaders;
01665     std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
01666   };
01667 
01679   template <typename _Traits = DefaultReaderTraits>
01680   class AttributeReader : public CommonSectionReaderBase {
01681     typedef CommonSectionReaderBase Parent;
01682     typedef _Traits Traits; 
01683   public:
01689     AttributeReader(LemonReader& _reader, 
01690                     const std::string& _id = std::string()) 
01691       : Parent(_reader), id(_id) {}
01692 
01696     virtual ~AttributeReader() {
01697       for (typename Readers::iterator it = readers.begin(); 
01698            it != readers.end(); ++it) {
01699         delete it->second;
01700       }
01701     }
01702 
01703   private:
01704     AttributeReader(const AttributeReader&);
01705     void operator=(AttributeReader&);
01706 
01707   public:
01711     template <typename Value>
01712     AttributeReader& readAttribute(const std::string& id, Value& value) {
01713       return readAttribute<typename Traits::template Reader<Value> >
01714         (id, value);
01715     }
01716 
01720     template <typename Reader, typename Value>
01721     AttributeReader& readAttribute(const std::string& name, Value& value,
01722                                    const Reader& reader = Reader()) {
01723       checkConcept<_reader_bits::ItemReader<Value>, Reader>();
01724       if (readers.find(name) != readers.end()) {
01725         ErrorMessage msg;
01726         msg << "Multiple read rule for attribute: " << name;
01727         throw IOParameterError(msg.message());
01728       }
01729       readers.insert(make_pair(name, new ValueReader<Value, Reader>
01730                                (value, reader)));
01731       return *this;
01732     }
01733 
01734   protected:
01735 
01741     bool header(const std::string& line) {
01742       std::istringstream ls(line);
01743       std::string command;
01744       std::string name;
01745       ls >> command >> name;
01746       return command == "@attributes" && name == id;
01747     }
01748 
01752     void read(std::istream& is) {
01753       std::string line;
01754       while (getline(is, line)) {
01755         std::istringstream ls(line);
01756         std::string id;
01757         ls >> id;
01758         typename Readers::iterator it = readers.find(id);
01759         if (it != readers.end()) {
01760           it->second->read(ls);
01761         }
01762       }
01763     }    
01764 
01765   private:
01766     std::string id;
01767 
01768     typedef std::map<std::string, ValueReaderBase*> Readers;
01769     Readers readers;  
01770   };
01771 
01783   class ContentReader : public LemonReader::SectionReader {
01784     typedef LemonReader::SectionReader Parent;
01785   public:
01789     ContentReader(LemonReader& _reader) : Parent(_reader) {}
01790 
01794     virtual ~ContentReader() {}
01795 
01799     int nodeSetNum() const {
01800       return nodesets.size();
01801     }
01802 
01806     std::string nodeSetName(int index) const {
01807       return nodesets[index].name;
01808     }
01809 
01813     const std::vector<std::string>& nodeSetMaps(int index) const {
01814       return nodesets[index].items;
01815     }
01816 
01820     int edgeSetNum() const {
01821       return edgesets.size();
01822     }
01823 
01827     std::string edgeSetName(int index) const {
01828       return edgesets[index].name;
01829     }
01830 
01834     const std::vector<std::string>& edgeSetMaps(int index) const {
01835       return edgesets[index].items;
01836     }
01837 
01841     int undirEdgeSetNum() const {
01842       return undiredgesets.size();
01843     }
01844 
01849     std::string undirEdgeSetName(int index) const {
01850       return undiredgesets[index].name;
01851     }
01852 
01857     const std::vector<std::string>& undirEdgeSetMaps(int index) const {
01858       return undiredgesets[index].items;
01859     }
01860 
01864     int nodesNum() const {
01865       return nodes.size();
01866     }
01867 
01872     std::string nodesName(int index) const {
01873       return nodes[index].name;
01874     }
01875 
01880     const std::vector<std::string>& nodesItems(int index) const {
01881       return nodes[index].items;
01882     }
01883 
01887     int edgesNum() const {
01888       return edges.size();
01889     }
01890 
01895     std::string edgesName(int index) const {
01896       return edges[index].name;
01897     }
01898 
01903     const std::vector<std::string>& edgesItems(int index) const {
01904       return edges[index].items;
01905     }
01906  
01911     int undirEdgesNum() const {
01912       return undiredges.size();
01913     }
01914 
01920     std::string undirEdgesName(int index) const {
01921       return undiredges[index].name;
01922     }
01923 
01929     const std::vector<std::string>& undirEdgesItems(int index) const {
01930       return undiredges[index].items;
01931     }
01932 
01933  
01937     int attributesNum() const {
01938       return attributes.size();
01939     }
01940 
01945     std::string attributesName(int index) const {
01946       return attributes[index].name;
01947     }
01948 
01952     const std::vector<std::string>& attributesItems(int index) const {
01953       return attributes[index].items;
01954     }
01955 
01956     const std::vector<std::string>& otherSections() const {
01957       return sections;
01958     }
01959 
01960   protected:
01961     
01966     bool header(const std::string& line) {
01967       std::istringstream ls(line);
01968       std::string command, name;
01969       ls >> command >> name;
01970       if (command == "@nodeset") {
01971         current = command;
01972         nodesets.push_back(SectionInfo(name));
01973       } else if (command == "@edgeset") {
01974         current = command;
01975         edgesets.push_back(SectionInfo(name));
01976       } else if (command == "@undiredgeset") {
01977         current = command;
01978         undiredgesets.push_back(SectionInfo(name));
01979       } else if (command == "@nodes") {
01980         current = command;
01981         nodes.push_back(SectionInfo(name));
01982       } else if (command == "@edges") {
01983         current = command;
01984         edges.push_back(SectionInfo(name));
01985       } else if (command == "@undiredges") {
01986         current = command;
01987         undiredges.push_back(SectionInfo(name));
01988       } else if (command == "@attributes") {
01989         current = command;
01990         attributes.push_back(SectionInfo(name));
01991       } else {
01992         sections.push_back(line);
01993         return false;
01994       }
01995       return true;
01996     }
01997 
02001     void read(std::istream& is) {
02002       if (current == "@nodeset") {
02003         readMapNames(is, nodesets.back().items);
02004       } else if (current == "@edgeset") {
02005         readMapNames(is, edgesets.back().items);
02006       } else if (current == "@undiredgeset") {
02007         readMapNames(is, undiredgesets.back().items);
02008       } else if (current == "@nodes") {
02009         readItemNames(is, nodes.back().items);
02010       } else if (current == "@edges") {
02011         readItemNames(is, edges.back().items);
02012       } else if (current == "@undiredges") {
02013         readItemNames(is, undiredges.back().items);
02014       } else if (current == "@attributes") {
02015         readItemNames(is, attributes.back().items);
02016       }
02017     }    
02018 
02019   private:
02020 
02021     void readMapNames(std::istream& is, std::vector<std::string>& maps) {
02022       std::string line, id;
02023       std::getline(is, line);
02024       std::istringstream ls(line);
02025       while (ls >> id) {
02026         maps.push_back(id);
02027       }
02028       while (getline(is, line));
02029     }
02030 
02031     void readItemNames(std::istream& is, std::vector<std::string>& maps) {
02032       std::string line, id;
02033       while (std::getline(is, line)) {
02034         std::istringstream ls(line);
02035         ls >> id;
02036         maps.push_back(id);
02037       }
02038     }
02039 
02040     struct SectionInfo {
02041       std::string name;
02042       std::vector<std::string> items;
02043 
02044       SectionInfo(const std::string& _name) : name(_name) {}
02045     };
02046 
02047     std::vector<SectionInfo> nodesets;
02048     std::vector<SectionInfo> edgesets;
02049     std::vector<SectionInfo> undiredgesets;
02050 
02051     std::vector<SectionInfo> nodes;
02052     std::vector<SectionInfo> edges;
02053     std::vector<SectionInfo> undiredges;
02054 
02055     std::vector<SectionInfo> attributes;
02056 
02057     std::vector<std::string> sections;
02058 
02059     std::string current;
02060 
02061   };
02062 
02063 }
02064 #endif

Generated on Sat Aug 27 14:14:53 2005 for LEMON by  doxygen 1.4.4