src/lemon/lemon_reader.h
author deba
Mon, 09 May 2005 11:24:26 +0000
changeset 1408 892c29484414
child 1409 d2d1f8fa187b
permissions -rw-r--r--
New graph reader interface.
deba@1408
     1
/* -*- C++ -*-
deba@1408
     2
 * src/lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
deba@1408
     3
 *
deba@1408
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1408
     5
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1408
     6
 *
deba@1408
     7
 * Permission to use, modify and distribute this software is granted
deba@1408
     8
 * provided that this copyright notice appears in all copies. For
deba@1408
     9
 * precise terms see the accompanying LICENSE file.
deba@1408
    10
 *
deba@1408
    11
 * This software is provided "AS IS" with no warranty of any kind,
deba@1408
    12
 * express or implied, and with no claim as to its suitability for any
deba@1408
    13
 * purpose.
deba@1408
    14
 *
deba@1408
    15
 */
deba@1408
    16
deba@1408
    17
///\ingroup io_group
deba@1408
    18
///\file
deba@1408
    19
///\brief Lemon Format reader.
deba@1408
    20
deba@1408
    21
#ifndef LEMON_LEMON_READER_H
deba@1408
    22
#define LEMON_LEMON_READER_H
deba@1408
    23
deba@1408
    24
#include <iostream>
deba@1408
    25
#include <fstream>
deba@1408
    26
#include <string>
deba@1408
    27
#include <vector>
deba@1408
    28
#include <algorithm>
deba@1408
    29
#include <map>
deba@1408
    30
#include <memory>
deba@1408
    31
deba@1408
    32
#include <lemon/error.h>
deba@1408
    33
#include "item_reader.h"
deba@1408
    34
deba@1408
    35
deba@1408
    36
namespace lemon {
deba@1408
    37
deba@1408
    38
  /// \addtogroup io_group
deba@1408
    39
  /// @{
deba@1408
    40
deba@1408
    41
  /// \brief Lemon Format reader class.
deba@1408
    42
  /// 
deba@1408
    43
  class LemonReader {
deba@1408
    44
  private:
deba@1408
    45
    
deba@1408
    46
    class FilterStreamBuf : public std::streambuf {
deba@1408
    47
    public:
deba@1408
    48
deba@1408
    49
      typedef std::streambuf Parent;
deba@1408
    50
      typedef Parent::char_type char_type;
deba@1408
    51
      FilterStreamBuf(std::istream& is, int& num) 
deba@1408
    52
	: _is(is), _base(0), _eptr(0), 
deba@1408
    53
	  _num(num), skip_state(after_endl) {}
deba@1408
    54
deba@1408
    55
    protected:
deba@1408
    56
deba@1408
    57
      enum skip_state_type {
deba@1408
    58
	no_skip,
deba@1408
    59
	after_comment,
deba@1408
    60
	after_endl,
deba@1408
    61
	empty_line
deba@1408
    62
      };
deba@1408
    63
deba@1408
    64
      char_type small_buf[1];
deba@1408
    65
deba@1408
    66
deba@1408
    67
      std::istream& _is;
deba@1408
    68
deba@1408
    69
      char_type* _base;
deba@1408
    70
      char_type* _eptr;
deba@1408
    71
deba@1408
    72
      int& _num;
deba@1408
    73
deba@1408
    74
      skip_state_type skip_state;
deba@1408
    75
deba@1408
    76
deba@1408
    77
      char_type* base() { return _base; }
deba@1408
    78
deba@1408
    79
      char_type* eptr() { return _eptr; }
deba@1408
    80
deba@1408
    81
      int blen() { return _eptr - _base; }
deba@1408
    82
deba@1408
    83
      void setb(char_type* buf, int len) {
deba@1408
    84
	_base = buf;
deba@1408
    85
	_eptr = buf + len;
deba@1408
    86
      }
deba@1408
    87
  
deba@1408
    88
      virtual std::streambuf* setbuf(char *buf, int len) {
deba@1408
    89
	if (base()) return 0;
deba@1408
    90
	if (buf != 0 && len >= (int)sizeof(small_buf)) {
deba@1408
    91
	  setb(buf, len);
deba@1408
    92
	} else {
deba@1408
    93
	  setb(small_buf, sizeof(small_buf));
deba@1408
    94
	}
deba@1408
    95
	setg(0, 0, 0);
deba@1408
    96
	return this;
deba@1408
    97
      }
deba@1408
    98
deba@1408
    99
      bool put_char(char c) {
deba@1408
   100
	switch (skip_state) {
deba@1408
   101
	case no_skip:
deba@1408
   102
	  switch (c) {
deba@1408
   103
	  case '\n': 
deba@1408
   104
	    skip_state = after_endl;
deba@1408
   105
	    return true;
deba@1408
   106
	  case '#':
deba@1408
   107
	    skip_state = after_comment;
deba@1408
   108
	    return false;
deba@1408
   109
	  default:
deba@1408
   110
	    return true;
deba@1408
   111
	  }
deba@1408
   112
	case after_comment:
deba@1408
   113
	  switch (c) {
deba@1408
   114
	  case '\n': 
deba@1408
   115
	    skip_state = after_endl;
deba@1408
   116
	    return true;
deba@1408
   117
	  default:
deba@1408
   118
	    return false;
deba@1408
   119
	  }        
deba@1408
   120
	case after_endl:
deba@1408
   121
	  switch (c) {
deba@1408
   122
	  case '@':
deba@1408
   123
	    return false;
deba@1408
   124
	  case '\n': 
deba@1408
   125
	    return false;
deba@1408
   126
	  case '#':
deba@1408
   127
	    skip_state = empty_line;
deba@1408
   128
	    return false;
deba@1408
   129
	  default:
deba@1408
   130
	    if (!isspace(c)) {
deba@1408
   131
	      skip_state = no_skip;
deba@1408
   132
	      return true;
deba@1408
   133
	    } else {
deba@1408
   134
	      return false;
deba@1408
   135
	    }
deba@1408
   136
	  }
deba@1408
   137
	  break;
deba@1408
   138
	case empty_line:
deba@1408
   139
	  switch (c) {
deba@1408
   140
	  case '\n': 
deba@1408
   141
	    skip_state = after_endl;
deba@1408
   142
	    return false;
deba@1408
   143
	  default:
deba@1408
   144
	    return false;
deba@1408
   145
	  }
deba@1408
   146
	}
deba@1408
   147
	return false;
deba@1408
   148
      }
deba@1408
   149
deba@1408
   150
      virtual int underflow() {
deba@1408
   151
	char c;
deba@1408
   152
	if (_is.read(&c, 1)) {
deba@1408
   153
	  _is.putback(c);
deba@1408
   154
	  if (c == '@') {
deba@1408
   155
	    return EOF;
deba@1408
   156
	  }
deba@1408
   157
	} else {
deba@1408
   158
	  return EOF;
deba@1408
   159
	}
deba@1408
   160
	char_type *ptr;
deba@1408
   161
	for (ptr = base(); ptr != eptr(); ++ptr) {
deba@1408
   162
	  if (_is.read(&c, 1)) {
deba@1408
   163
	    if (c == '\n') ++_num;
deba@1408
   164
	    if (put_char(c)) {
deba@1408
   165
	      *ptr = c;
deba@1408
   166
	    } else {
deba@1408
   167
	      if (skip_state == after_endl && c == '@') {
deba@1408
   168
		_is.putback('@');
deba@1408
   169
		break;
deba@1408
   170
	      }
deba@1408
   171
	      --ptr;
deba@1408
   172
	    }
deba@1408
   173
	  } else {
deba@1408
   174
	    break;
deba@1408
   175
	  }
deba@1408
   176
	}
deba@1408
   177
	setg(base(), base(), ptr);
deba@1408
   178
	return *base();
deba@1408
   179
      }
deba@1408
   180
deba@1408
   181
      virtual int sync() {
deba@1408
   182
	return EOF;
deba@1408
   183
      }
deba@1408
   184
    };
deba@1408
   185
deba@1408
   186
  public:
deba@1408
   187
deba@1408
   188
    class SectionReader {
deba@1408
   189
    public:
deba@1408
   190
      /// \e
deba@1408
   191
      virtual bool header(const std::string& line) = 0;
deba@1408
   192
      /// \e
deba@1408
   193
      virtual void read(std::istream& is) = 0;
deba@1408
   194
    };
deba@1408
   195
deba@1408
   196
    /// \e
deba@1408
   197
    LemonReader(std::istream& _is) 
deba@1408
   198
      : is(&_is), own_is(false) {}
deba@1408
   199
deba@1408
   200
    LemonReader(const std::string& filename) 
deba@1408
   201
      : is(0), own_is(true) {
deba@1408
   202
      is = new std::ifstream(filename.c_str());
deba@1408
   203
    }
deba@1408
   204
deba@1408
   205
deba@1408
   206
    ~LemonReader() {
deba@1408
   207
      if (own_is) {
deba@1408
   208
	delete is;
deba@1408
   209
      }
deba@1408
   210
    }
deba@1408
   211
deba@1408
   212
  private:
deba@1408
   213
    LemonReader(const LemonReader&);
deba@1408
   214
    void operator=(const LemonReader&);
deba@1408
   215
deba@1408
   216
  public:
deba@1408
   217
    
deba@1408
   218
    /// \e
deba@1408
   219
    void attach(SectionReader& reader) {
deba@1408
   220
      readers.push_back(&reader);
deba@1408
   221
    }
deba@1408
   222
deba@1408
   223
    /// \e
deba@1408
   224
    void detach(SectionReader& reader) {
deba@1408
   225
      std::vector<SectionReader*>::iterator it = 
deba@1408
   226
	std::find(readers.begin(), readers.end(), &reader);
deba@1408
   227
      if (it != readers.end()) {
deba@1408
   228
	readers.erase(it);
deba@1408
   229
      }
deba@1408
   230
    }
deba@1408
   231
deba@1408
   232
    /// \e
deba@1408
   233
    void run() {
deba@1408
   234
      int line_num = 0;
deba@1408
   235
      std::string line;
deba@1408
   236
      try {
deba@1408
   237
	while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
deba@1408
   238
	  SectionReaders::iterator it;
deba@1408
   239
	  for (it = readers.begin(); it != readers.end(); ++it) {
deba@1408
   240
	    if ((*it)->header(line)) {
deba@1408
   241
	      char buf[2048];
deba@1408
   242
	      FilterStreamBuf buffer(*is, line_num);
deba@1408
   243
	      buffer.pubsetbuf(buf, sizeof(buf));
deba@1408
   244
	      std::istream is(&buffer);
deba@1408
   245
	      (*it)->read(is);
deba@1408
   246
	      break;
deba@1408
   247
	    }
deba@1408
   248
	  }
deba@1408
   249
	}
deba@1408
   250
      } catch (DataFormatError& error) {
deba@1408
   251
	error.line(line_num);
deba@1408
   252
	throw error;
deba@1408
   253
      }	
deba@1408
   254
    }
deba@1408
   255
deba@1408
   256
deba@1408
   257
  private:
deba@1408
   258
deba@1408
   259
    std::istream* is;
deba@1408
   260
    bool own_is;
deba@1408
   261
deba@1408
   262
    typedef std::vector<SectionReader*> SectionReaders;
deba@1408
   263
    SectionReaders readers;
deba@1408
   264
deba@1408
   265
  };
deba@1408
   266
deba@1408
   267
deba@1408
   268
  /// \e
deba@1408
   269
  class CommonSectionReaderBase : public LemonReader::SectionReader {
deba@1408
   270
  protected:
deba@1408
   271
    template <typename _Item>
deba@1408
   272
    class ReaderBase;
deba@1408
   273
    
deba@1408
   274
    template <typename _Item>
deba@1408
   275
    class InverterBase : public ReaderBase<_Item> {
deba@1408
   276
    public:
deba@1408
   277
      typedef _Item Item;
deba@1408
   278
      virtual void read(std::istream&, const Item&) = 0;
deba@1408
   279
      virtual Item read(std::istream&) const = 0;
deba@1408
   280
deba@1408
   281
      virtual InverterBase<_Item>* getInverter() {
deba@1408
   282
	return this;
deba@1408
   283
      }
deba@1408
   284
deba@1408
   285
deba@1408
   286
    };
deba@1408
   287
deba@1408
   288
    template <typename _Item, typename _Map, typename _Reader>
deba@1408
   289
    class MapReaderInverter : public InverterBase<_Item> {
deba@1408
   290
    public:
deba@1408
   291
      typedef _Item Item;
deba@1408
   292
      typedef _Reader Reader;
deba@1408
   293
      typedef typename Reader::Value Value;
deba@1408
   294
      typedef _Map Map;
deba@1408
   295
      typedef std::map<Value, Item> Inverse;
deba@1408
   296
deba@1408
   297
      Map& map;
deba@1408
   298
      Reader reader;
deba@1408
   299
      Inverse inverse;
deba@1408
   300
deba@1408
   301
      MapReaderInverter(Map& _map, const Reader& _reader) 
deba@1408
   302
	: map(_map), reader(_reader) {}
deba@1408
   303
deba@1408
   304
      virtual ~MapReaderInverter() {}
deba@1408
   305
deba@1408
   306
      virtual void read(std::istream& is, const Item& item) {
deba@1408
   307
	Value value;
deba@1408
   308
	reader.read(is, value);
deba@1408
   309
	map.set(item, value);
deba@1408
   310
	typename Inverse::iterator it = inverse.find(value);
deba@1408
   311
	if (it == inverse.end()) {
deba@1408
   312
	  inverse.insert(std::make_pair(value, item));
deba@1408
   313
	} else {
deba@1408
   314
	  throw DataFormatError("Multiple ID occurence");
deba@1408
   315
	}
deba@1408
   316
      }
deba@1408
   317
deba@1408
   318
      virtual Item read(std::istream& is) const {
deba@1408
   319
	Value value;
deba@1408
   320
	reader.read(is, value);	
deba@1408
   321
	typename Inverse::const_iterator it = inverse.find(value);
deba@1408
   322
	if (it != inverse.end()) {
deba@1408
   323
	  return it->second;
deba@1408
   324
	} else {
deba@1408
   325
	  throw DataFormatError("Invalid ID error");
deba@1408
   326
	}
deba@1408
   327
      }      
deba@1408
   328
deba@1408
   329
    };
deba@1408
   330
deba@1408
   331
    template <typename _Item, typename _Reader>
deba@1408
   332
    class SkipReaderInverter : public InverterBase<_Item> {
deba@1408
   333
    public:
deba@1408
   334
      typedef _Item Item;
deba@1408
   335
      typedef _Reader Reader;
deba@1408
   336
      typedef typename Reader::Value Value;
deba@1408
   337
      typedef std::map<Value, Item> Inverse;
deba@1408
   338
deba@1408
   339
      Reader reader;
deba@1408
   340
deba@1408
   341
      SkipReaderInverter(const Reader& _reader) 
deba@1408
   342
	: reader(_reader) {}
deba@1408
   343
deba@1408
   344
      virtual ~SkipReaderInverter() {}
deba@1408
   345
deba@1408
   346
      virtual void read(std::istream& is, const Item& item) {
deba@1408
   347
	Value value;
deba@1408
   348
	reader.read(is, value);
deba@1408
   349
	typename Inverse::iterator it = inverse.find(value);
deba@1408
   350
	if (it == inverse.end()) {
deba@1408
   351
	  inverse.insert(std::make_pair(value, item));
deba@1408
   352
	} else {
deba@1408
   353
	  throw DataFormatError("Multiple ID occurence error");
deba@1408
   354
	}
deba@1408
   355
      }
deba@1408
   356
deba@1408
   357
      virtual Item read(std::istream& is) const {
deba@1408
   358
	Value value;
deba@1408
   359
	reader.read(is, value);	
deba@1408
   360
	typename Inverse::const_iterator it = inverse.find(value);
deba@1408
   361
	if (it != inverse.end()) {
deba@1408
   362
	  return it->second;
deba@1408
   363
	} else {
deba@1408
   364
	  throw DataFormatError("Invalid ID error");
deba@1408
   365
	}
deba@1408
   366
      }
deba@1408
   367
deba@1408
   368
    private:
deba@1408
   369
      Inverse inverse;
deba@1408
   370
    };
deba@1408
   371
deba@1408
   372
    // Readers
deba@1408
   373
deba@1408
   374
    template <typename _Item>    
deba@1408
   375
    class ReaderBase {
deba@1408
   376
    public:
deba@1408
   377
      typedef _Item Item;
deba@1408
   378
deba@1408
   379
      virtual ~ReaderBase() {}
deba@1408
   380
deba@1408
   381
      virtual void read(std::istream& is, const Item& item) = 0;
deba@1408
   382
      virtual InverterBase<_Item>* getInverter() = 0;
deba@1408
   383
    };
deba@1408
   384
deba@1408
   385
    template <typename _Item, typename _Map, typename _Reader>
deba@1408
   386
    class MapReader : public ReaderBase<_Item> {
deba@1408
   387
    public:
deba@1408
   388
      typedef _Map Map;
deba@1408
   389
      typedef _Reader Reader;
deba@1408
   390
      typedef typename Reader::Value Value;
deba@1408
   391
      typedef _Item Item;
deba@1408
   392
      
deba@1408
   393
      Map& map;
deba@1408
   394
      Reader reader;
deba@1408
   395
deba@1408
   396
      MapReader(Map& _map, const Reader& _reader) 
deba@1408
   397
	: map(_map), reader(_reader) {}
deba@1408
   398
deba@1408
   399
      virtual ~MapReader() {}
deba@1408
   400
deba@1408
   401
      virtual void read(std::istream& is, const Item& item) {
deba@1408
   402
	Value value;
deba@1408
   403
	reader.read(is, value);
deba@1408
   404
	map.set(item, value);
deba@1408
   405
      }
deba@1408
   406
deba@1408
   407
      virtual InverterBase<_Item>* getInverter() {
deba@1408
   408
	return new MapReaderInverter<Item, Map, Reader>(map, reader);
deba@1408
   409
      }
deba@1408
   410
    };
deba@1408
   411
deba@1408
   412
deba@1408
   413
    template <typename _Item, typename _Reader>
deba@1408
   414
    class SkipReader : public ReaderBase<_Item> {
deba@1408
   415
    public:
deba@1408
   416
      typedef _Reader Reader;
deba@1408
   417
      typedef typename Reader::Value Value;
deba@1408
   418
      typedef _Item Item;
deba@1408
   419
deba@1408
   420
      Reader reader;
deba@1408
   421
      SkipReader(const Reader& _reader) : reader(_reader) {}
deba@1408
   422
deba@1408
   423
      virtual ~SkipReader() {}
deba@1408
   424
deba@1408
   425
      virtual void read(std::istream& is, const Item&) {
deba@1408
   426
	Value value;
deba@1408
   427
	reader.read(is, value);
deba@1408
   428
      }      
deba@1408
   429
deba@1408
   430
      virtual InverterBase<Item>* getInverter() {
deba@1408
   431
	return new SkipReaderInverter<Item, Reader>(reader);
deba@1408
   432
      }
deba@1408
   433
    };
deba@1408
   434
deba@1408
   435
    template <typename _Item>
deba@1408
   436
    class ResolverReaderBase {
deba@1408
   437
    public:
deba@1408
   438
      typedef _Item Item;
deba@1408
   439
      virtual Item resolve(std::istream& is) const = 0;
deba@1408
   440
    };
deba@1408
   441
deba@1408
   442
    template <typename _Item, typename _Resolver>
deba@1408
   443
    class ResolverReader : public ResolverReaderBase<_Item> {
deba@1408
   444
    public:
deba@1408
   445
      typedef _Item Item;
deba@1408
   446
      typedef _Resolver Resolver;
deba@1408
   447
deba@1408
   448
      const Resolver& resolver;
deba@1408
   449
deba@1408
   450
      ResolverReader(const Resolver& _resolver) 
deba@1408
   451
	: resolver(_resolver) {}
deba@1408
   452
deba@1408
   453
      virtual Item resolve(std::istream& is) const {
deba@1408
   454
	return resolver.resolve(is);
deba@1408
   455
      }
deba@1408
   456
    };
deba@1408
   457
deba@1408
   458
    class ValueReaderBase {
deba@1408
   459
    public:
deba@1408
   460
      virtual void read(std::istream&) {};
deba@1408
   461
    };
deba@1408
   462
deba@1408
   463
    template <typename _Value, typename _Reader>
deba@1408
   464
    class ValueReader : public ValueReaderBase {
deba@1408
   465
    public:
deba@1408
   466
      typedef _Value Value;
deba@1408
   467
      typedef _Reader Reader;
deba@1408
   468
deba@1408
   469
      ValueReader(Value& _value, const Reader& _reader)
deba@1408
   470
 	: value(_value), reader(_reader) {}
deba@1408
   471
deba@1408
   472
      virtual void read(std::istream& is) {
deba@1408
   473
	reader.read(is, value);
deba@1408
   474
      }
deba@1408
   475
    private:
deba@1408
   476
      Value& value;
deba@1408
   477
      Reader reader;
deba@1408
   478
    };
deba@1408
   479
    
deba@1408
   480
  };
deba@1408
   481
deba@1408
   482
deba@1408
   483
  template <typename _Graph, typename _Traits = DefaultReaderTraits>
deba@1408
   484
  class NodeSetReader : public CommonSectionReaderBase {
deba@1408
   485
    typedef CommonSectionReaderBase Parent;
deba@1408
   486
  public:
deba@1408
   487
deba@1408
   488
    typedef _Graph Graph;
deba@1408
   489
    typedef _Traits Traits;
deba@1408
   490
    typedef typename Graph::Node Item;
deba@1408
   491
    typedef typename Traits::Skipper DefaultSkipper;
deba@1408
   492
deba@1408
   493
    NodeSetReader(LemonReader& _reader, Graph& _graph, 
deba@1408
   494
		  const std::string& _id = std::string(),
deba@1408
   495
		  const DefaultSkipper& _defreader = DefaultSkipper()) 
deba@1408
   496
      : graph(_graph), id(_id), skipper(_defreader) {
deba@1408
   497
      _reader.attach(*this);
deba@1408
   498
    } 
deba@1408
   499
deba@1408
   500
    virtual ~NodeSetReader() {
deba@1408
   501
      for (typename MapReaders::iterator it = readers.begin(); 
deba@1408
   502
	   it != readers.end(); ++it) {
deba@1408
   503
	delete it->second;
deba@1408
   504
      }
deba@1408
   505
    }
deba@1408
   506
deba@1408
   507
  private:
deba@1408
   508
    NodeSetReader(const NodeSetReader&);
deba@1408
   509
    void operator=(const NodeSetReader&);
deba@1408
   510
  
deba@1408
   511
  public:
deba@1408
   512
deba@1408
   513
    /// \brief Add a new node map reader command for the reader.
deba@1408
   514
    ///
deba@1408
   515
    /// Add a new node map reader command for the reader.
deba@1408
   516
    template <typename Map>
deba@1408
   517
    NodeSetReader& readMap(std::string name, Map& map) {
deba@1408
   518
      return readMap<typename Traits::
deba@1408
   519
	template Reader<typename Map::Value>, Map>(name, map);
deba@1408
   520
    }
deba@1408
   521
deba@1408
   522
    /// \brief Add a new node map reader command for the reader.
deba@1408
   523
    ///
deba@1408
   524
    /// Add a new node map reader command for the reader.
deba@1408
   525
    template <typename Reader, typename Map>
deba@1408
   526
    NodeSetReader& readMap(std::string name, Map& map, 
deba@1408
   527
			     const Reader& reader = Reader()) {
deba@1408
   528
      if (readers.find(name) != readers.end()) {
deba@1408
   529
	ErrorMessage msg;
deba@1408
   530
	msg << "Multiple read rule for node map: " << name;
deba@1408
   531
	throw IOParameterError(msg.message());
deba@1408
   532
      }
deba@1408
   533
      readers.insert(
deba@1408
   534
	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
deba@1408
   535
      return *this;
deba@1408
   536
    }
deba@1408
   537
deba@1408
   538
    /// \brief Add a new node map skipper command for the reader.
deba@1408
   539
    ///
deba@1408
   540
    /// Add a new node map skipper command for the reader.
deba@1408
   541
    template <typename Reader>
deba@1408
   542
    NodeSetReader& skipMap(std::string name, 
deba@1408
   543
			   const Reader& reader = Reader()) {
deba@1408
   544
      if (readers.find(name) != readers.end()) {
deba@1408
   545
	ErrorMessage msg;
deba@1408
   546
	msg << "Multiple read rule for node map: " << name;
deba@1408
   547
	throw IOParameterError(msg.message());
deba@1408
   548
      }
deba@1408
   549
      readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
deba@1408
   550
      return *this;
deba@1408
   551
    }
deba@1408
   552
deba@1408
   553
    /// \e
deba@1408
   554
    virtual bool header(const std::string& line) {
deba@1408
   555
      std::istringstream ls(line);
deba@1408
   556
      std::string command;
deba@1408
   557
      std::string name;
deba@1408
   558
      ls >> command >> name;
deba@1408
   559
      return command == "@nodeset" && name == id;
deba@1408
   560
    }
deba@1408
   561
deba@1408
   562
    /// \e
deba@1408
   563
    virtual void read(std::istream& is) {
deba@1408
   564
      std::vector<ReaderBase<Item>* > index;
deba@1408
   565
      std::string line;
deba@1408
   566
deba@1408
   567
      getline(is, line);
deba@1408
   568
      std::istringstream ls(line);	
deba@1408
   569
      while (ls >> id) {
deba@1408
   570
	typename MapReaders::iterator it = readers.find(id);
deba@1408
   571
	if (it != readers.end()) {
deba@1408
   572
	  index.push_back(it->second);
deba@1408
   573
	} else {
deba@1408
   574
	  index.push_back(&skipper);
deba@1408
   575
	}
deba@1408
   576
	if (id == "id" && inverter.get() == 0) {
deba@1408
   577
	  inverter.reset(index.back()->getInverter());
deba@1408
   578
	  index.back() = inverter.get();
deba@1408
   579
	}
deba@1408
   580
      }
deba@1408
   581
      while (getline(is, line)) {	
deba@1408
   582
	typename Graph::Node node = graph.addNode();
deba@1408
   583
	std::istringstream ls(line);
deba@1408
   584
	for (int i = 0; i < (int)index.size(); ++i) {
deba@1408
   585
	  index[i]->read(ls, node);
deba@1408
   586
	}
deba@1408
   587
      }
deba@1408
   588
    }
deba@1408
   589
deba@1408
   590
    bool isResolver() const {
deba@1408
   591
      return inverter.get() != 0;
deba@1408
   592
    }
deba@1408
   593
deba@1408
   594
    typename Graph::Node resolve(std::istream& is) const {
deba@1408
   595
      return inverter->read(is);
deba@1408
   596
    } 
deba@1408
   597
deba@1408
   598
  private:
deba@1408
   599
deba@1408
   600
    typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
deba@1408
   601
    MapReaders readers;
deba@1408
   602
   
deba@1408
   603
    Graph& graph;   
deba@1408
   604
    std::string id;
deba@1408
   605
    SkipReader<Item, DefaultSkipper> skipper;
deba@1408
   606
deba@1408
   607
    std::auto_ptr<InverterBase<Item> > inverter;
deba@1408
   608
  };
deba@1408
   609
deba@1408
   610
deba@1408
   611
 
deba@1408
   612
  /// \e
deba@1408
   613
  template <typename _Graph, typename _Traits = DefaultReaderTraits>
deba@1408
   614
  class EdgeSetReader : public CommonSectionReaderBase {
deba@1408
   615
    typedef CommonSectionReaderBase Parent;
deba@1408
   616
  public:
deba@1408
   617
deba@1408
   618
    typedef _Graph Graph;
deba@1408
   619
    typedef _Traits Traits;
deba@1408
   620
    typedef typename Graph::Edge Item;
deba@1408
   621
    typedef typename Traits::Skipper DefaultSkipper;
deba@1408
   622
deba@1408
   623
    template <typename Resolver>
deba@1408
   624
    EdgeSetReader(LemonReader& _reader, Graph& _graph, 
deba@1408
   625
		  const Resolver& _nodeResolver, 
deba@1408
   626
		  const std::string& _id = std::string(),
deba@1408
   627
		  const DefaultSkipper& _defreader = DefaultSkipper()) 
deba@1408
   628
      : graph(_graph), id(_id), skipper(_defreader),
deba@1408
   629
      nodeResolver(new ResolverReader<typename Graph::Node, Resolver>
deba@1408
   630
		   (_nodeResolver)) {
deba@1408
   631
      _reader.attach(*this);
deba@1408
   632
    } 
deba@1408
   633
deba@1408
   634
    virtual ~EdgeSetReader() {
deba@1408
   635
      for (typename MapReaders::iterator it = readers.begin(); 
deba@1408
   636
	   it != readers.end(); ++it) {
deba@1408
   637
	delete it->second;
deba@1408
   638
      }
deba@1408
   639
    }
deba@1408
   640
deba@1408
   641
  private:
deba@1408
   642
    EdgeSetReader(const EdgeSetReader&);
deba@1408
   643
    void operator=(const EdgeSetReader&);
deba@1408
   644
deba@1408
   645
  public:
deba@1408
   646
deba@1408
   647
    /// \brief Add a new node map reader command for the reader.
deba@1408
   648
    ///
deba@1408
   649
    /// Add a new node map reader command for the reader.
deba@1408
   650
    template <typename Map>
deba@1408
   651
    EdgeSetReader& readMap(std::string name, Map& map) {
deba@1408
   652
      return readMap<typename Traits::
deba@1408
   653
	template Reader<typename Map::Value>, Map>(name, map);
deba@1408
   654
    }
deba@1408
   655
deba@1408
   656
    /// \brief Add a new node map reader command for the reader.
deba@1408
   657
    ///
deba@1408
   658
    /// Add a new node map reader command for the reader.
deba@1408
   659
    template <typename Reader, typename Map>
deba@1408
   660
    EdgeSetReader& readMap(std::string name, Map& map, 
deba@1408
   661
			     const Reader& reader = Reader()) {
deba@1408
   662
      if (readers.find(name) != readers.end()) {
deba@1408
   663
	ErrorMessage msg;
deba@1408
   664
	msg << "Multiple read rule for edge map: " << name;
deba@1408
   665
	throw IOParameterError(msg.message());
deba@1408
   666
      }
deba@1408
   667
      readers.insert(
deba@1408
   668
	make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
deba@1408
   669
      return *this;
deba@1408
   670
    }
deba@1408
   671
deba@1408
   672
    /// \brief Add a new node map skipper command for the reader.
deba@1408
   673
    ///
deba@1408
   674
    /// Add a new node map skipper command for the reader.
deba@1408
   675
    template <typename Reader>
deba@1408
   676
    EdgeSetReader& skipMap(std::string name, 
deba@1408
   677
			   const Reader& reader = Reader()) {
deba@1408
   678
      if (readers.find(name) != readers.end()) {
deba@1408
   679
	ErrorMessage msg;
deba@1408
   680
	msg << "Multiple read rule for node map: " << name;
deba@1408
   681
	throw IOParameterError(msg.message());
deba@1408
   682
      }
deba@1408
   683
      readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
deba@1408
   684
      return *this;
deba@1408
   685
    }
deba@1408
   686
deba@1408
   687
    /// \e
deba@1408
   688
    virtual bool header(const std::string& line) {
deba@1408
   689
      std::istringstream ls(line);
deba@1408
   690
      std::string command;
deba@1408
   691
      std::string name;
deba@1408
   692
      ls >> command >> name;
deba@1408
   693
      return command == "@edgeset" && name == id;
deba@1408
   694
    }
deba@1408
   695
deba@1408
   696
    /// \e
deba@1408
   697
    virtual void read(std::istream& is) {
deba@1408
   698
      std::vector<ReaderBase<Item>* > index;
deba@1408
   699
      std::string line;
deba@1408
   700
deba@1408
   701
      getline(is, line);
deba@1408
   702
      std::istringstream ls(line);	
deba@1408
   703
      while (ls >> id) {
deba@1408
   704
	typename MapReaders::iterator it = readers.find(id);
deba@1408
   705
	if (it != readers.end()) {
deba@1408
   706
	  index.push_back(it->second);
deba@1408
   707
	} else {
deba@1408
   708
	  index.push_back(&skipper);
deba@1408
   709
	}
deba@1408
   710
	if (id == "id" && inverter.get() == 0) {
deba@1408
   711
	  inverter.reset(index.back()->getInverter());
deba@1408
   712
	  index.back() = inverter.get();
deba@1408
   713
	}
deba@1408
   714
      }
deba@1408
   715
      while (getline(is, line)) {	
deba@1408
   716
	std::istringstream ls(line);
deba@1408
   717
	typename Graph::Node from = nodeResolver->resolve(ls);
deba@1408
   718
	typename Graph::Node to = nodeResolver->resolve(ls);
deba@1408
   719
	typename Graph::Edge edge = graph.addEdge(from, to);
deba@1408
   720
	for (int i = 0; i < (int)index.size(); ++i) {
deba@1408
   721
	  index[i]->read(ls, edge);
deba@1408
   722
	}
deba@1408
   723
      }
deba@1408
   724
    }
deba@1408
   725
deba@1408
   726
    bool isResolver() const {
deba@1408
   727
      return inverter.get() != 0;
deba@1408
   728
    }
deba@1408
   729
deba@1408
   730
    typename Graph::Edge resolve(std::istream& is) {
deba@1408
   731
      return inverter->read(is);
deba@1408
   732
    } 
deba@1408
   733
deba@1408
   734
  private:
deba@1408
   735
deba@1408
   736
    typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
deba@1408
   737
    MapReaders readers;
deba@1408
   738
   
deba@1408
   739
    Graph& graph;   
deba@1408
   740
    std::string id;
deba@1408
   741
    SkipReader<Item, DefaultSkipper> skipper;
deba@1408
   742
deba@1408
   743
    std::auto_ptr<InverterBase<Item> > inverter;
deba@1408
   744
    std::auto_ptr<ResolverReaderBase<typename Graph::Node> > nodeResolver;
deba@1408
   745
  };
deba@1408
   746
deba@1408
   747
deba@1408
   748
  /// \e
deba@1408
   749
  template <typename _Traits = DefaultReaderTraits>
deba@1408
   750
  class AttributeReader : public CommonSectionReaderBase {
deba@1408
   751
    typedef CommonSectionReaderBase Parent;
deba@1408
   752
    typedef _Traits Traits; 
deba@1408
   753
  public:
deba@1408
   754
    /// \e
deba@1408
   755
    AttributeReader(LemonReader& _reader, 
deba@1408
   756
		    const std::string& _id = std::string()) : id(_id) {
deba@1408
   757
      _reader.attach(*this);
deba@1408
   758
    }
deba@1408
   759
deba@1408
   760
    /// \e
deba@1408
   761
    virtual ~AttributeReader() {
deba@1408
   762
      for (typename Readers::iterator it = readers.begin(); 
deba@1408
   763
	   it != readers.end(); ++it) {
deba@1408
   764
	delete it->second;
deba@1408
   765
      }
deba@1408
   766
    }
deba@1408
   767
deba@1408
   768
  private:
deba@1408
   769
    AttributeReader(const AttributeReader&);
deba@1408
   770
    void operator=(AttributeReader&);
deba@1408
   771
deba@1408
   772
  public:
deba@1408
   773
    /// \e
deba@1408
   774
    template <typename Value>
deba@1408
   775
    AttributeReader& readAttribute(const std::string& id, Value& value) {
deba@1408
   776
      return readAttribute<typename Traits::template Reader<Value> >
deba@1408
   777
	(id, value);
deba@1408
   778
    }
deba@1408
   779
deba@1408
   780
    /// \e
deba@1408
   781
    template <typename Reader, typename Value>
deba@1408
   782
    AttributeReader& readAttribute(const std::string& name, Value& value,
deba@1408
   783
				   const Reader& reader = Reader()) {
deba@1408
   784
      if (readers.find(name) != readers.end()) {
deba@1408
   785
	ErrorMessage msg;
deba@1408
   786
	msg << "Multiple read rule for attribute: " << name;
deba@1408
   787
	throw IOParameterError(msg.message());
deba@1408
   788
      }
deba@1408
   789
      readers.insert(make_pair(name, new ValueReader<Value, Reader>
deba@1408
   790
      			       (value, reader)));
deba@1408
   791
      return *this;
deba@1408
   792
    }
deba@1408
   793
deba@1408
   794
    /// \e
deba@1408
   795
    bool header(const std::string& line) {
deba@1408
   796
      std::istringstream ls(line);
deba@1408
   797
      std::string command;
deba@1408
   798
      std::string name;
deba@1408
   799
      ls >> command >> name;
deba@1408
   800
      return command == "@attributes" && name == id;
deba@1408
   801
    }
deba@1408
   802
deba@1408
   803
    /// \e
deba@1408
   804
    void read(std::istream& is) {
deba@1408
   805
      std::string line;
deba@1408
   806
      while (getline(is, line)) {
deba@1408
   807
	std::istringstream ls(line);
deba@1408
   808
	std::string id;
deba@1408
   809
	ls >> id;
deba@1408
   810
	typename Readers::iterator it = readers.find(id);
deba@1408
   811
	if (it != readers.end()) {
deba@1408
   812
	  it->second->read(ls);
deba@1408
   813
	}
deba@1408
   814
      }
deba@1408
   815
    }    
deba@1408
   816
deba@1408
   817
  private:
deba@1408
   818
    std::string id;
deba@1408
   819
deba@1408
   820
    typedef std::map<std::string, ValueReaderBase*> Readers;
deba@1408
   821
    Readers readers;
deba@1408
   822
  
deba@1408
   823
  };
deba@1408
   824
deba@1408
   825
  template <typename _Graph>
deba@1408
   826
  class NodeReader : public CommonSectionReaderBase {
deba@1408
   827
    typedef CommonSectionReaderBase Parent;
deba@1408
   828
    typedef _Graph Graph;
deba@1408
   829
    typedef typename Graph::Node Item;
deba@1408
   830
  public:
deba@1408
   831
    
deba@1408
   832
    template <typename Resolver>
deba@1408
   833
    NodeReader(LemonReader& _reader, const Resolver& _resolver, 
deba@1408
   834
	       const std::string& _id = std::string()) 
deba@1408
   835
      : id(_id), resolver(new ResolverReader<typename Graph::Node, Resolver>
deba@1408
   836
		     (_resolver)) {
deba@1408
   837
      _reader.attach(*this);
deba@1408
   838
    } 
deba@1408
   839
deba@1408
   840
    virtual ~NodeReader() {}
deba@1408
   841
deba@1408
   842
  private:
deba@1408
   843
    NodeReader(const NodeReader&);
deba@1408
   844
    void operator=(const NodeReader&);
deba@1408
   845
deba@1408
   846
  public:
deba@1408
   847
deba@1408
   848
    void readNode(const std::string& name, Item& item) {
deba@1408
   849
      if (readers.find(name) != readers.end()) {
deba@1408
   850
	ErrorMessage msg;
deba@1408
   851
	msg << "Multiple read rule for node: " << name;
deba@1408
   852
	throw IOParameterError(msg.message());
deba@1408
   853
      }
deba@1408
   854
      readers.insert(make_pair(name, &item));
deba@1408
   855
    }
deba@1408
   856
deba@1408
   857
    virtual bool header(const std::string& line) {
deba@1408
   858
      std::istringstream ls(line);
deba@1408
   859
      std::string command;
deba@1408
   860
      std::string name;
deba@1408
   861
      ls >> command >> name;
deba@1408
   862
      return command == "@nodes" && name == id;
deba@1408
   863
    }
deba@1408
   864
deba@1408
   865
    virtual void read(std::istream& is) {
deba@1408
   866
      std::string line;
deba@1408
   867
      while (getline(is, line)) {
deba@1408
   868
	std::istringstream ls(line);
deba@1408
   869
	std::string id;
deba@1408
   870
	ls >> id;
deba@1408
   871
	typename ItemReaders::iterator it = readers.find(id);
deba@1408
   872
	if (it != readers.end()) {
deba@1408
   873
	  *(it->second) = resolver->resolve(ls); 
deba@1408
   874
	}	
deba@1408
   875
      }
deba@1408
   876
    }
deba@1408
   877
    
deba@1408
   878
  private:
deba@1408
   879
deba@1408
   880
    std::string id;
deba@1408
   881
deba@1408
   882
    typedef std::map<std::string, Item*> ItemReaders;
deba@1408
   883
    ItemReaders readers;
deba@1408
   884
    std::auto_ptr<ResolverReaderBase<Item> > resolver;
deba@1408
   885
  };
deba@1408
   886
deba@1408
   887
  template <typename _Graph>
deba@1408
   888
  class EdgeReader : public CommonSectionReaderBase {
deba@1408
   889
    typedef CommonSectionReaderBase Parent;
deba@1408
   890
    typedef _Graph Graph;
deba@1408
   891
    typedef typename Graph::Edge Item;
deba@1408
   892
  public:
deba@1408
   893
    
deba@1408
   894
    template <typename Resolver>
deba@1408
   895
    EdgeReader(LemonReader& _reader, const Resolver& _resolver, 
deba@1408
   896
	       const std::string& _id = std::string()) 
deba@1408
   897
      : id(_id), resolver(new ResolverReader<typename Graph::Node, Resolver>
deba@1408
   898
		     (_resolver)) {
deba@1408
   899
      _reader.attach(*this);
deba@1408
   900
    } 
deba@1408
   901
deba@1408
   902
    virtual ~EdgeReader() {}
deba@1408
   903
  private:
deba@1408
   904
    EdgeReader(const EdgeReader&);
deba@1408
   905
    void operator=(const EdgeReader&);
deba@1408
   906
deba@1408
   907
  public:
deba@1408
   908
deba@1408
   909
    void readEdge(const std::string& name, Item& item) {
deba@1408
   910
      if (readers.find(name) != readers.end()) {
deba@1408
   911
	ErrorMessage msg;
deba@1408
   912
	msg << "Multiple read rule for edge: " << name;
deba@1408
   913
	throw IOParameterError(msg.message());
deba@1408
   914
      }
deba@1408
   915
      readers.insert(make_pair(name, &item));
deba@1408
   916
    }
deba@1408
   917
deba@1408
   918
deba@1408
   919
    virtual bool header(const std::string& line) {
deba@1408
   920
      std::istringstream ls(line);
deba@1408
   921
      std::string command;
deba@1408
   922
      std::string name;
deba@1408
   923
      ls >> command >> name;
deba@1408
   924
      return command == "@nodes" && name == id;
deba@1408
   925
    }
deba@1408
   926
deba@1408
   927
    virtual void read(std::istream& is) {
deba@1408
   928
      std::string line;
deba@1408
   929
      while (getline(is, line)) {
deba@1408
   930
	std::istringstream ls(line);
deba@1408
   931
	std::string id;
deba@1408
   932
	ls >> id;
deba@1408
   933
	typename ItemReaders::iterator it = readers.find(id);
deba@1408
   934
	if (it != readers.end()) {
deba@1408
   935
	  *(it->second) = resolver->resolve(ls); 
deba@1408
   936
	}	
deba@1408
   937
      }
deba@1408
   938
    }
deba@1408
   939
    
deba@1408
   940
  private:
deba@1408
   941
deba@1408
   942
    std::string id;
deba@1408
   943
deba@1408
   944
    typedef std::map<std::string, Item*> ItemReaders;
deba@1408
   945
    ItemReaders readers;
deba@1408
   946
    std::auto_ptr<ResolverReaderBase<Item> > resolver;
deba@1408
   947
  };
deba@1408
   948
deba@1408
   949
  /// \e
deba@1408
   950
  class PrintReader : public LemonReader::SectionReader {
deba@1408
   951
    typedef LemonReader::SectionReader Parent;
deba@1408
   952
  public:
deba@1408
   953
deba@1408
   954
    /// \e
deba@1408
   955
    PrintReader(LemonReader& reader) {
deba@1408
   956
      reader.attach(*this);
deba@1408
   957
    }
deba@1408
   958
deba@1408
   959
    /// \e
deba@1408
   960
    bool header(const std::string& line) {
deba@1408
   961
      std::cout << "Asked header: " << line << std::endl; 
deba@1408
   962
      return true;
deba@1408
   963
    }
deba@1408
   964
deba@1408
   965
    /// \e
deba@1408
   966
    void read(std::istream& is) {
deba@1408
   967
      std::string line;
deba@1408
   968
      while (std::getline(is, line)) {
deba@1408
   969
	std::cout << line << std::endl;
deba@1408
   970
      }
deba@1408
   971
    }
deba@1408
   972
  
deba@1408
   973
  };
deba@1408
   974
deba@1408
   975
  /// @}
deba@1408
   976
}
deba@1408
   977
#endif