lemon/lgf_reader.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 24 Apr 2008 20:26:14 +0100
changeset 151 4d79daa40e9b
child 139 701c529ba737
permissions -rw-r--r--
Turn on built in Doxygen STL support
deba@127
     1
/* -*- C++ -*-
deba@127
     2
 *
deba@127
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@127
     4
 *
deba@127
     5
 * Copyright (C) 2003-2008
deba@127
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@127
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@127
     8
 *
deba@127
     9
 * Permission to use, modify and distribute this software is granted
deba@127
    10
 * provided that this copyright notice appears in all copies. For
deba@127
    11
 * precise terms see the accompanying LICENSE file.
deba@127
    12
 *
deba@127
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@127
    14
 * express or implied, and with no claim as to its suitability for any
deba@127
    15
 * purpose.
deba@127
    16
 *
deba@127
    17
 */
deba@127
    18
deba@127
    19
///\ingroup lemon_io
deba@127
    20
///\file
deba@127
    21
///\brief Lemon Graph Format reader.
deba@127
    22
deba@127
    23
deba@127
    24
#ifndef LEMON_LGF_READER_H
deba@127
    25
#define LEMON_LGF_READER_H
deba@127
    26
deba@127
    27
#include <iostream>
deba@127
    28
#include <fstream>
deba@127
    29
#include <sstream>
deba@127
    30
deba@127
    31
#include <set>
deba@127
    32
#include <map>
deba@127
    33
deba@127
    34
#include <lemon/assert.h>
deba@127
    35
#include <lemon/graph_utils.h>
deba@127
    36
deba@127
    37
#include <lemon/lgf_writer.h>
deba@127
    38
deba@127
    39
#include <lemon/concept_check.h>
deba@127
    40
#include <lemon/concepts/maps.h>
deba@127
    41
deba@127
    42
namespace lemon {
deba@127
    43
deba@127
    44
  namespace _reader_bits {
deba@127
    45
deba@127
    46
    template <typename Value>
deba@127
    47
    struct DefaultConverter {
deba@127
    48
      Value operator()(const std::string& str) {
deba@127
    49
	std::istringstream is(str);
deba@127
    50
	Value value;
deba@127
    51
	is >> value;
deba@127
    52
deba@127
    53
	char c;
deba@127
    54
	if (is >> std::ws >> c) {
deba@127
    55
	  throw DataFormatError("Remaining characters in token");
deba@127
    56
	}
deba@127
    57
	return value;
deba@127
    58
      }
deba@127
    59
    };
deba@127
    60
deba@127
    61
    template <>
deba@127
    62
    struct DefaultConverter<std::string> {
deba@127
    63
      std::string operator()(const std::string& str) {
deba@127
    64
	return str;
deba@127
    65
      }
deba@127
    66
    };
deba@127
    67
deba@127
    68
    template <typename _Item>    
deba@127
    69
    class MapStorageBase {
deba@127
    70
    public:
deba@127
    71
      typedef _Item Item;
deba@127
    72
deba@127
    73
    public:
deba@127
    74
      MapStorageBase() {}
deba@127
    75
      virtual ~MapStorageBase() {}
deba@127
    76
deba@127
    77
      virtual void set(const Item& item, const std::string& value) = 0;
deba@127
    78
deba@127
    79
    };
deba@127
    80
deba@127
    81
    template <typename _Item, typename _Map, 
deba@127
    82
	      typename _Converter = DefaultConverter<typename _Map::Value> >
deba@127
    83
    class MapStorage : public MapStorageBase<_Item> {
deba@127
    84
    public:
deba@127
    85
      typedef _Map Map;
deba@127
    86
      typedef _Converter Converter;
deba@127
    87
      typedef _Item Item;
deba@127
    88
      
deba@127
    89
    private:
deba@127
    90
      Map& _map;
deba@127
    91
      Converter _converter;
deba@127
    92
deba@127
    93
    public:
deba@127
    94
      MapStorage(Map& map, const Converter& converter = Converter()) 
deba@127
    95
	: _map(map), _converter(converter) {}
deba@127
    96
      virtual ~MapStorage() {}
deba@127
    97
deba@127
    98
      virtual void set(const Item& item ,const std::string& value) {
deba@127
    99
	_map.set(item, _converter(value));
deba@127
   100
      }
deba@127
   101
    };
deba@127
   102
deba@127
   103
    class ValueStorageBase {
deba@127
   104
    public:
deba@127
   105
      ValueStorageBase() {}
deba@127
   106
      virtual ~ValueStorageBase() {}
deba@127
   107
deba@127
   108
      virtual void set(const std::string&) = 0;
deba@127
   109
    };
deba@127
   110
deba@127
   111
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
deba@127
   112
    class ValueStorage : public ValueStorageBase {
deba@127
   113
    public:
deba@127
   114
      typedef _Value Value;
deba@127
   115
      typedef _Converter Converter;
deba@127
   116
deba@127
   117
    private:
deba@127
   118
      Value& _value;
deba@127
   119
      Converter _converter;
deba@127
   120
deba@127
   121
    public:
deba@127
   122
      ValueStorage(Value& value, const Converter& converter = Converter())
deba@127
   123
 	: _value(value), _converter(converter) {}
deba@127
   124
deba@127
   125
      virtual void set(const std::string& value) {
deba@127
   126
	_value = _converter(value);
deba@127
   127
      }
deba@127
   128
    };
deba@127
   129
deba@127
   130
    template <typename Value>
deba@127
   131
    struct MapLookUpConverter {
deba@127
   132
      const std::map<std::string, Value>& _map;
deba@127
   133
deba@127
   134
      MapLookUpConverter(const std::map<std::string, Value>& map)
deba@127
   135
        : _map(map) {}
deba@127
   136
deba@127
   137
      Value operator()(const std::string& str) {
deba@127
   138
        typename std::map<std::string, Value>::const_iterator it =
deba@127
   139
          _map.find(str);
deba@127
   140
        if (it == _map.end()) {
deba@127
   141
          std::ostringstream msg;
deba@127
   142
          msg << "Item not found: " << str;
deba@127
   143
          throw DataFormatError(msg.str().c_str());
deba@127
   144
        }
deba@127
   145
        return it->second;
deba@127
   146
      }
deba@127
   147
    };
deba@127
   148
deba@127
   149
    bool isWhiteSpace(char c) {
deba@127
   150
      return c == ' ' || c == '\t' || c == '\v' || 
deba@127
   151
        c == '\n' || c == '\r' || c == '\f'; 
deba@127
   152
    }
deba@127
   153
    
deba@127
   154
    bool isOct(char c) {
deba@127
   155
      return '0' <= c && c <='7'; 
deba@127
   156
    }
deba@127
   157
    
deba@127
   158
    int valueOct(char c) {
deba@127
   159
      LEMON_ASSERT(isOct(c), "The character is not octal.");
deba@127
   160
      return c - '0';
deba@127
   161
    }
deba@127
   162
deba@127
   163
    bool isHex(char c) {
deba@127
   164
      return ('0' <= c && c <= '9') || 
deba@127
   165
	('a' <= c && c <= 'z') || 
deba@127
   166
	('A' <= c && c <= 'Z'); 
deba@127
   167
    }
deba@127
   168
    
deba@127
   169
    int valueHex(char c) {
deba@127
   170
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
deba@127
   171
      if ('0' <= c && c <= '9') return c - '0';
deba@127
   172
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
deba@127
   173
      return c - 'A' + 10;
deba@127
   174
    }
deba@127
   175
deba@127
   176
    bool isIdentifierFirstChar(char c) {
deba@127
   177
      return ('a' <= c && c <= 'z') ||
deba@127
   178
	('A' <= c && c <= 'Z') || c == '_';
deba@127
   179
    }
deba@127
   180
deba@127
   181
    bool isIdentifierChar(char c) {
deba@127
   182
      return isIdentifierFirstChar(c) ||
deba@127
   183
	('0' <= c && c <= '9');
deba@127
   184
    }
deba@127
   185
deba@127
   186
    char readEscape(std::istream& is) {
deba@127
   187
      char c;
deba@127
   188
      if (!is.get(c))
deba@127
   189
	throw DataFormatError("Escape format error");
deba@127
   190
deba@127
   191
      switch (c) {
deba@127
   192
      case '\\':
deba@127
   193
	return '\\';
deba@127
   194
      case '\"':
deba@127
   195
	return '\"';
deba@127
   196
      case '\'':
deba@127
   197
	return '\'';
deba@127
   198
      case '\?':
deba@127
   199
	return '\?';
deba@127
   200
      case 'a':
deba@127
   201
	return '\a';
deba@127
   202
      case 'b':
deba@127
   203
	return '\b';
deba@127
   204
      case 'f':
deba@127
   205
	return '\f';
deba@127
   206
      case 'n':
deba@127
   207
	return '\n';
deba@127
   208
      case 'r':
deba@127
   209
	return '\r';
deba@127
   210
      case 't':
deba@127
   211
	return '\t';
deba@127
   212
      case 'v':
deba@127
   213
	return '\v';
deba@127
   214
      case 'x':
deba@127
   215
	{
deba@127
   216
	  int code;
deba@127
   217
	  if (!is.get(c) || !isHex(c)) 
deba@127
   218
	    throw DataFormatError("Escape format error");
deba@127
   219
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
deba@127
   220
	  else code = code * 16 + valueHex(c);
deba@127
   221
	  return code;
deba@127
   222
	}
deba@127
   223
      default:
deba@127
   224
	{
deba@127
   225
	  int code;
deba@127
   226
	  if (!isOct(c)) 
deba@127
   227
	    throw DataFormatError("Escape format error");
deba@127
   228
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
deba@127
   229
	    is.putback(c);
deba@127
   230
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
deba@127
   231
	    is.putback(c);
deba@127
   232
	  else code = code * 8 + valueOct(c);
deba@127
   233
	  return code;
deba@127
   234
	}	      
deba@127
   235
      } 
deba@127
   236
    }
deba@127
   237
    
deba@127
   238
    std::istream& readToken(std::istream& is, std::string& str) {
deba@127
   239
      std::ostringstream os;
deba@127
   240
deba@127
   241
      char c;
deba@127
   242
      is >> std::ws;
deba@127
   243
      
deba@127
   244
      if (!is.get(c)) 
deba@127
   245
	return is;
deba@127
   246
deba@127
   247
      if (c == '\"') {
deba@127
   248
	while (is.get(c) && c != '\"') {
deba@127
   249
	  if (c == '\\') 
deba@127
   250
	    c = readEscape(is);
deba@127
   251
	  os << c;
deba@127
   252
	}
deba@127
   253
	if (!is) 
deba@127
   254
	  throw DataFormatError("Quoted format error");
deba@127
   255
      } else {
deba@127
   256
	is.putback(c);
deba@127
   257
	while (is.get(c) && !isWhiteSpace(c)) {
deba@127
   258
	  if (c == '\\') 
deba@127
   259
	    c = readEscape(is);
deba@127
   260
	  os << c;
deba@127
   261
	}
deba@127
   262
	if (!is) {
deba@127
   263
	  is.clear();
deba@127
   264
	} else {
deba@127
   265
	  is.putback(c);
deba@127
   266
	}
deba@127
   267
      }
deba@127
   268
      str = os.str();
deba@127
   269
      return is;
deba@127
   270
    }
deba@127
   271
deba@127
   272
    std::istream& readIdentifier(std::istream& is, std::string& str) {
deba@127
   273
      std::ostringstream os;
deba@127
   274
deba@127
   275
      char c;
deba@127
   276
      is >> std::ws;
deba@127
   277
      
deba@127
   278
      if (!is.get(c))
deba@127
   279
	return is;
deba@127
   280
deba@127
   281
      if (!isIdentifierFirstChar(c))
deba@127
   282
	throw DataFormatError("Wrong char in identifier");
deba@127
   283
      
deba@127
   284
      os << c;
deba@127
   285
      
deba@127
   286
      while (is.get(c) && !isWhiteSpace(c)) {
deba@127
   287
	if (!isIdentifierChar(c)) 
deba@127
   288
	  throw DataFormatError("Wrong char in identifier");	  
deba@127
   289
	os << c;
deba@127
   290
      }
deba@127
   291
      if (!is) is.clear();
deba@127
   292
     
deba@127
   293
      str = os.str();
deba@127
   294
      return is;
deba@127
   295
    }
deba@127
   296
    
deba@127
   297
  }
deba@127
   298
  
deba@127
   299
  /// \e
deba@127
   300
  template <typename _Digraph>
deba@127
   301
  class DigraphReader {
deba@127
   302
  public:
deba@127
   303
deba@127
   304
    typedef _Digraph Digraph;
deba@127
   305
    GRAPH_TYPEDEFS(typename Digraph);
deba@127
   306
    
deba@127
   307
  private:
deba@127
   308
deba@127
   309
deba@127
   310
    std::istream* _is;
deba@127
   311
    bool local_is;
deba@127
   312
deba@127
   313
    Digraph& _digraph;
deba@127
   314
deba@127
   315
    std::string _nodes_caption;
deba@127
   316
    std::string _arcs_caption;
deba@127
   317
    std::string _attributes_caption;
deba@127
   318
deba@127
   319
    typedef std::map<std::string, Node> NodeIndex;
deba@127
   320
    NodeIndex _node_index;
deba@127
   321
    typedef std::map<std::string, Arc> ArcIndex;
deba@127
   322
    ArcIndex _arc_index;
deba@127
   323
    
deba@127
   324
    typedef std::vector<std::pair<std::string, 
deba@127
   325
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
deba@127
   326
    NodeMaps _node_maps; 
deba@127
   327
deba@127
   328
    typedef std::vector<std::pair<std::string,
deba@127
   329
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
deba@127
   330
    ArcMaps _arc_maps;
deba@127
   331
deba@127
   332
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
deba@127
   333
      Attributes;
deba@127
   334
    Attributes _attributes;
deba@127
   335
deba@127
   336
    bool _use_nodes;
deba@127
   337
    bool _use_arcs;
deba@127
   338
deba@127
   339
    int line_num;
deba@127
   340
    std::istringstream line;
deba@127
   341
deba@127
   342
  public:
deba@127
   343
deba@127
   344
    /// \e
deba@127
   345
    DigraphReader(std::istream& is, Digraph& digraph) 
deba@127
   346
      : _is(&is), local_is(false), _digraph(digraph),
deba@127
   347
	_use_nodes(false), _use_arcs(false) {}
deba@127
   348
deba@127
   349
    /// \e
deba@127
   350
    DigraphReader(const std::string& fn, Digraph& digraph) 
deba@127
   351
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
deba@127
   352
    	_use_nodes(false), _use_arcs(false) {}
deba@127
   353
deba@127
   354
deba@127
   355
    /// \e
deba@127
   356
    DigraphReader(const char* fn, Digraph& digraph) 
deba@127
   357
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
deba@127
   358
    	_use_nodes(false), _use_arcs(false) {}
deba@127
   359
deba@127
   360
    /// \e
deba@127
   361
    DigraphReader(DigraphReader& other) 
deba@127
   362
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
deba@127
   363
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
deba@127
   364
deba@127
   365
      other.is = 0;
deba@127
   366
      other.local_is = false;
deba@127
   367
      
deba@127
   368
      _node_index.swap(other._node_index);
deba@127
   369
      _arc_index.swap(other._arc_index);
deba@127
   370
deba@127
   371
      _node_maps.swap(other._node_maps);
deba@127
   372
      _arc_maps.swap(other._arc_maps);
deba@127
   373
      _attributes.swap(other._attributes);
deba@127
   374
deba@127
   375
      _nodes_caption = other._nodes_caption;
deba@127
   376
      _arcs_caption = other._arcs_caption;
deba@127
   377
      _attributes_caption = other._attributes_caption;
deba@127
   378
    }
deba@127
   379
deba@127
   380
    /// \e
deba@127
   381
    ~DigraphReader() {
deba@127
   382
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
deba@127
   383
	   it != _node_maps.end(); ++it) {
deba@127
   384
	delete it->second;
deba@127
   385
      }
deba@127
   386
deba@127
   387
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
deba@127
   388
	   it != _arc_maps.end(); ++it) {
deba@127
   389
	delete it->second;
deba@127
   390
      }
deba@127
   391
deba@127
   392
      for (typename Attributes::iterator it = _attributes.begin(); 
deba@127
   393
	   it != _attributes.end(); ++it) {
deba@127
   394
	delete it->second;
deba@127
   395
      }
deba@127
   396
deba@127
   397
      if (local_is) {
deba@127
   398
	delete _is;
deba@127
   399
      }
deba@127
   400
deba@127
   401
    }
deba@127
   402
deba@127
   403
  private:
deba@127
   404
    
deba@127
   405
    DigraphReader& operator=(const DigraphReader&);
deba@127
   406
deba@127
   407
  public:
deba@127
   408
deba@127
   409
    /// \e
deba@127
   410
    template <typename Map>
deba@127
   411
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
deba@127
   412
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
deba@127
   413
      _reader_bits::MapStorageBase<Node>* storage = 
deba@127
   414
	new _reader_bits::MapStorage<Node, Map>(map);
deba@127
   415
      _node_maps.push_back(std::make_pair(caption, storage));
deba@127
   416
      return *this;
deba@127
   417
    }
deba@127
   418
deba@127
   419
    /// \e
deba@127
   420
    template <typename Map, typename Converter>
deba@127
   421
    DigraphReader& nodeMap(const std::string& caption, Map& map, 
deba@127
   422
			   const Converter& converter = Converter()) {
deba@127
   423
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
deba@127
   424
      _reader_bits::MapStorageBase<Node>* storage = 
deba@127
   425
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
deba@127
   426
      _node_maps.push_back(std::make_pair(caption, storage));
deba@127
   427
      return *this;
deba@127
   428
    }
deba@127
   429
deba@127
   430
    /// \e
deba@127
   431
    template <typename Map>
deba@127
   432
    DigraphReader& arcMap(const std::string& caption, Map& map) {
deba@127
   433
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
deba@127
   434
      _reader_bits::MapStorageBase<Arc>* storage = 
deba@127
   435
	new _reader_bits::MapStorage<Arc, Map>(map);
deba@127
   436
      _arc_maps.push_back(std::make_pair(caption, storage));
deba@127
   437
      return *this;
deba@127
   438
    }
deba@127
   439
deba@127
   440
    /// \e
deba@127
   441
    template <typename Map, typename Converter>
deba@127
   442
    DigraphReader& arcMap(const std::string& caption, Map& map, 
deba@127
   443
			  const Converter& converter = Converter()) {
deba@127
   444
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
deba@127
   445
      _reader_bits::MapStorageBase<Arc>* storage = 
deba@127
   446
	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
deba@127
   447
      _arc_maps.push_back(std::make_pair(caption, storage));
deba@127
   448
      return *this;
deba@127
   449
    }
deba@127
   450
deba@127
   451
    /// \e
deba@127
   452
    template <typename Value>
deba@127
   453
    DigraphReader& attribute(const std::string& caption, Value& value) {
deba@127
   454
      _reader_bits::ValueStorageBase* storage = 
deba@127
   455
	new _reader_bits::ValueStorage<Value>(value);
deba@127
   456
      _attributes.insert(std::make_pair(caption, storage));
deba@127
   457
      return *this;
deba@127
   458
    }
deba@127
   459
deba@127
   460
    /// \e
deba@127
   461
    template <typename Value, typename Converter>
deba@127
   462
    DigraphReader& attribute(const std::string& caption, Value& value, 
deba@127
   463
			     const Converter& converter = Converter()) {
deba@127
   464
      _reader_bits::ValueStorageBase* storage = 
deba@127
   465
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
deba@127
   466
      _attributes.insert(std::make_pair(caption, storage));
deba@127
   467
      return *this;
deba@127
   468
    }
deba@127
   469
deba@127
   470
    /// \e
deba@127
   471
    DigraphReader& node(const std::string& caption, Node& node) {
deba@127
   472
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
deba@127
   473
      Converter converter(_node_index);
deba@127
   474
      _reader_bits::ValueStorageBase* storage = 
deba@127
   475
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
deba@127
   476
      _attributes.insert(std::make_pair(caption, storage));
deba@127
   477
      return *this;
deba@127
   478
    }
deba@127
   479
deba@127
   480
    /// \e
deba@127
   481
    DigraphReader& arc(const std::string& caption, Arc& arc) {
deba@127
   482
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
deba@127
   483
      Converter converter(_arc_index);
deba@127
   484
      _reader_bits::ValueStorageBase* storage = 
deba@127
   485
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
deba@127
   486
      _attributes.insert(std::make_pair(caption, storage));
deba@127
   487
      return *this;
deba@127
   488
    }
deba@127
   489
deba@127
   490
    /// \e
deba@127
   491
    DigraphReader& nodes(const std::string& caption) {
deba@127
   492
      _nodes_caption = caption;
deba@127
   493
      return *this;
deba@127
   494
    }
deba@127
   495
deba@127
   496
    /// \e
deba@127
   497
    DigraphReader& arcs(const std::string& caption) {
deba@127
   498
      _arcs_caption = caption;
deba@127
   499
      return *this;
deba@127
   500
    }
deba@127
   501
deba@127
   502
    /// \e
deba@127
   503
    DigraphReader& attributes(const std::string& caption) {
deba@127
   504
      _attributes_caption = caption;
deba@127
   505
      return *this;
deba@127
   506
    }
deba@127
   507
deba@127
   508
    /// \e
deba@127
   509
    template <typename Map>
deba@127
   510
    DigraphReader& useNodes(const Map& map) {
deba@127
   511
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
deba@127
   512
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
deba@127
   513
      _use_nodes = true;
deba@127
   514
      _writer_bits::DefaultConverter<typename Map::Value> converter;
deba@127
   515
      for (NodeIt n(_digraph); n != INVALID; ++n) {
deba@127
   516
	_node_index.insert(std::make_pair(converter(map[n]), n));
deba@127
   517
      }
deba@127
   518
      return *this;
deba@127
   519
    }
deba@127
   520
deba@127
   521
    /// \e
deba@127
   522
    template <typename Map, typename Converter>
deba@127
   523
    DigraphReader& useNodes(const Map& map, 
deba@127
   524
			    const Converter& converter = Converter()) {
deba@127
   525
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
deba@127
   526
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
deba@127
   527
      _use_nodes = true;
deba@127
   528
      for (NodeIt n(_digraph); n != INVALID; ++n) {
deba@127
   529
	_node_index.insert(std::make_pair(converter(map[n]), n));
deba@127
   530
      }
deba@127
   531
      return *this;
deba@127
   532
    }
deba@127
   533
deba@127
   534
    /// \e
deba@127
   535
    template <typename Map>
deba@127
   536
    DigraphReader& useArcs(const Map& map) {
deba@127
   537
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
deba@127
   538
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
deba@127
   539
      _use_arcs = true;
deba@127
   540
      _writer_bits::DefaultConverter<typename Map::Value> converter;
deba@127
   541
      for (ArcIt a(_digraph); a != INVALID; ++a) {
deba@127
   542
	_arc_index.insert(std::make_pair(converter(map[a]), a));
deba@127
   543
      }
deba@127
   544
      return *this;
deba@127
   545
    }
deba@127
   546
deba@127
   547
    /// \e
deba@127
   548
    template <typename Map, typename Converter>
deba@127
   549
    DigraphReader& useArcs(const Map& map, 
deba@127
   550
			    const Converter& converter = Converter()) {
deba@127
   551
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
deba@127
   552
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
deba@127
   553
      _use_arcs = true;
deba@127
   554
      for (ArcIt a(_digraph); a != INVALID; ++a) {
deba@127
   555
	_arc_index.insert(std::make_pair(converter(map[a]), a));
deba@127
   556
      }
deba@127
   557
      return *this;
deba@127
   558
    }
deba@127
   559
deba@127
   560
  private:
deba@127
   561
deba@127
   562
    bool readLine() {
deba@127
   563
      std::string str;
deba@127
   564
      while(++line_num, std::getline(*_is, str)) {
deba@127
   565
	line.clear(); line.str(str);
deba@127
   566
	char c;
deba@127
   567
	if (line >> std::ws >> c && c != '#') {
deba@127
   568
	  line.putback(c);
deba@127
   569
	  return true;
deba@127
   570
	}
deba@127
   571
      }
deba@127
   572
      return false;
deba@127
   573
    }
deba@127
   574
deba@127
   575
    bool readSuccess() {
deba@127
   576
      return static_cast<bool>(*_is);
deba@127
   577
    }
deba@127
   578
    
deba@127
   579
    void skipSection() {
deba@127
   580
      char c;
deba@127
   581
      while (readSuccess() && line >> c && c != '@') {
deba@127
   582
	readLine();
deba@127
   583
      }
deba@127
   584
      line.putback(c);
deba@127
   585
    }
deba@127
   586
deba@127
   587
    void readNodes() {
deba@127
   588
deba@127
   589
      std::vector<int> map_index(_node_maps.size());
deba@127
   590
      int map_num, label_index;
deba@127
   591
deba@127
   592
      if (!readLine()) 
deba@127
   593
	throw DataFormatError("Cannot find map captions");
deba@127
   594
      
deba@127
   595
      {
deba@127
   596
	std::map<std::string, int> maps;
deba@127
   597
	
deba@127
   598
	std::string map;
deba@127
   599
	int index = 0;
deba@127
   600
	while (_reader_bits::readIdentifier(line, map)) {
deba@127
   601
	  if (maps.find(map) != maps.end()) {
deba@127
   602
	    std::ostringstream msg;
deba@127
   603
	    msg << "Multiple occurence of node map: " << map;
deba@127
   604
	    throw DataFormatError(msg.str().c_str());
deba@127
   605
	  }
deba@127
   606
	  maps.insert(std::make_pair(map, index));
deba@127
   607
	  ++index;
deba@127
   608
	}
deba@127
   609
	
deba@127
   610
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
deba@127
   611
	  std::map<std::string, int>::iterator jt = 
deba@127
   612
	    maps.find(_node_maps[i].first);
deba@127
   613
	  if (jt == maps.end()) {
deba@127
   614
	    std::ostringstream msg;
deba@127
   615
	    msg << "Map not found in file: " << _node_maps[i].first;
deba@127
   616
	    throw DataFormatError(msg.str().c_str());
deba@127
   617
	  }
deba@127
   618
	  map_index[i] = jt->second;
deba@127
   619
	}
deba@127
   620
deba@127
   621
	{
deba@127
   622
	  std::map<std::string, int>::iterator jt = maps.find("label");
deba@127
   623
	  if (jt == maps.end())
deba@127
   624
	    throw DataFormatError("Label map not found in file");
deba@127
   625
	  label_index = jt->second;
deba@127
   626
	}
deba@127
   627
	map_num = maps.size();
deba@127
   628
      }
deba@127
   629
deba@127
   630
      char c;
deba@127
   631
      while (readLine() && line >> c && c != '@') {
deba@127
   632
	line.putback(c);
deba@127
   633
deba@127
   634
	std::vector<std::string> tokens(map_num);
deba@127
   635
	for (int i = 0; i < map_num; ++i) {
deba@127
   636
	  if (!_reader_bits::readToken(line, tokens[i])) {
deba@127
   637
	    std::ostringstream msg;
deba@127
   638
	    msg << "Column not found (" << i + 1 << ")";
deba@127
   639
	    throw DataFormatError(msg.str().c_str());
deba@127
   640
	  }
deba@127
   641
	}
deba@127
   642
	if (line >> std::ws >> c)
deba@127
   643
	  throw DataFormatError("Extra character on the end of line");
deba@127
   644
	
deba@127
   645
	Node n;
deba@127
   646
	if (!_use_nodes) {
deba@127
   647
	  n = _digraph.addNode();
deba@127
   648
	  _node_index.insert(std::make_pair(tokens[label_index], n));
deba@127
   649
	} else {
deba@127
   650
	  typename std::map<std::string, Node>::iterator it =
deba@127
   651
	    _node_index.find(tokens[label_index]);
deba@127
   652
	  if (it == _node_index.end()) {
deba@127
   653
	    std::ostringstream msg;
deba@127
   654
	    msg << "Node with label not found: " << tokens[label_index];
deba@127
   655
	    throw DataFormatError(msg.str().c_str());	    
deba@127
   656
	  }
deba@127
   657
	  n = it->second;
deba@127
   658
	}
deba@127
   659
deba@127
   660
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
deba@127
   661
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
deba@127
   662
	}
deba@127
   663
deba@127
   664
      }
deba@127
   665
      if (readSuccess()) {
deba@127
   666
	line.putback(c);
deba@127
   667
      }
deba@127
   668
    }
deba@127
   669
deba@127
   670
    void readArcs() {
deba@127
   671
deba@127
   672
      std::vector<int> map_index(_arc_maps.size());
deba@127
   673
      int map_num, label_index;
deba@127
   674
deba@127
   675
      if (!readLine()) 
deba@127
   676
	throw DataFormatError("Cannot find map captions");
deba@127
   677
      
deba@127
   678
      {
deba@127
   679
	std::map<std::string, int> maps;
deba@127
   680
	
deba@127
   681
	std::string map;
deba@127
   682
	int index = 0;
deba@127
   683
	while (_reader_bits::readIdentifier(line, map)) {
deba@127
   684
	  if (maps.find(map) != maps.end()) {
deba@127
   685
	    std::ostringstream msg;
deba@127
   686
	    msg << "Multiple occurence of arc map: " << map;
deba@127
   687
	    throw DataFormatError(msg.str().c_str());
deba@127
   688
	  }
deba@127
   689
	  maps.insert(std::make_pair(map, index));
deba@127
   690
	  ++index;
deba@127
   691
	}
deba@127
   692
	
deba@127
   693
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
deba@127
   694
	  std::map<std::string, int>::iterator jt = 
deba@127
   695
	    maps.find(_arc_maps[i].first);
deba@127
   696
	  if (jt == maps.end()) {
deba@127
   697
	    std::ostringstream msg;
deba@127
   698
	    msg << "Map not found in file: " << _arc_maps[i].first;
deba@127
   699
	    throw DataFormatError(msg.str().c_str());
deba@127
   700
	  }
deba@127
   701
	  map_index[i] = jt->second;
deba@127
   702
	}
deba@127
   703
deba@127
   704
	{
deba@127
   705
	  std::map<std::string, int>::iterator jt = maps.find("label");
deba@127
   706
	  if (jt == maps.end())
deba@127
   707
	    throw DataFormatError("Label map not found in file");
deba@127
   708
	  label_index = jt->second;
deba@127
   709
	}
deba@127
   710
	map_num = maps.size();
deba@127
   711
      }
deba@127
   712
deba@127
   713
      char c;
deba@127
   714
      while (readLine() && line >> c && c != '@') {
deba@127
   715
	line.putback(c);
deba@127
   716
deba@127
   717
	std::string source_token;
deba@127
   718
	std::string target_token;
deba@127
   719
deba@127
   720
	if (!_reader_bits::readToken(line, source_token))
deba@127
   721
	  throw DataFormatError("Source not found");
deba@127
   722
deba@127
   723
	if (!_reader_bits::readToken(line, target_token))
deba@127
   724
	  throw DataFormatError("Source not found");
deba@127
   725
	
deba@127
   726
	std::vector<std::string> tokens(map_num);
deba@127
   727
	for (int i = 0; i < map_num; ++i) {
deba@127
   728
	  if (!_reader_bits::readToken(line, tokens[i])) {
deba@127
   729
	    std::ostringstream msg;
deba@127
   730
	    msg << "Column not found (" << i + 1 << ")";
deba@127
   731
	    throw DataFormatError(msg.str().c_str());
deba@127
   732
	  }
deba@127
   733
	}
deba@127
   734
	if (line >> std::ws >> c)
deba@127
   735
	  throw DataFormatError("Extra character on the end of line");
deba@127
   736
	
deba@127
   737
	Arc a;
deba@127
   738
	if (!_use_arcs) {
deba@127
   739
deba@127
   740
          typename NodeIndex::iterator it;
deba@127
   741
 
deba@127
   742
          it = _node_index.find(source_token);
deba@127
   743
          if (it == _node_index.end()) {
deba@127
   744
            std::ostringstream msg;
deba@127
   745
            msg << "Item not found: " << source_token;
deba@127
   746
            throw DataFormatError(msg.str().c_str());
deba@127
   747
          }
deba@127
   748
          Node source = it->second;
deba@127
   749
deba@127
   750
          it = _node_index.find(target_token);
deba@127
   751
          if (it == _node_index.end()) {       
deba@127
   752
            std::ostringstream msg;            
deba@127
   753
            msg << "Item not found: " << target_token;
deba@127
   754
            throw DataFormatError(msg.str().c_str());
deba@127
   755
          }                                          
deba@127
   756
          Node target = it->second;                            
deba@127
   757
deba@127
   758
	  a = _digraph.addArc(source, target);
deba@127
   759
	  _arc_index.insert(std::make_pair(tokens[label_index], a));
deba@127
   760
	} else {
deba@127
   761
	  typename std::map<std::string, Arc>::iterator it =
deba@127
   762
	    _arc_index.find(tokens[label_index]);
deba@127
   763
	  if (it == _arc_index.end()) {
deba@127
   764
	    std::ostringstream msg;
deba@127
   765
	    msg << "Arc with label not found: " << tokens[label_index];
deba@127
   766
	    throw DataFormatError(msg.str().c_str());	    
deba@127
   767
	  }
deba@127
   768
	  a = it->second;
deba@127
   769
	}
deba@127
   770
deba@127
   771
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
deba@127
   772
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
deba@127
   773
	}
deba@127
   774
deba@127
   775
      }
deba@127
   776
      if (readSuccess()) {
deba@127
   777
	line.putback(c);
deba@127
   778
      }
deba@127
   779
    }
deba@127
   780
deba@127
   781
    void readAttributes() {
deba@127
   782
deba@127
   783
      std::set<std::string> read_attr;
deba@127
   784
deba@127
   785
      char c;
deba@127
   786
      while (readLine() && line >> c && c != '@') {
deba@127
   787
	line.putback(c);
deba@127
   788
	
deba@127
   789
	std::string attr, token;
deba@127
   790
	if (!_reader_bits::readIdentifier(line, attr))
deba@127
   791
	  throw DataFormatError("Attribute name not found");
deba@127
   792
	if (!_reader_bits::readToken(line, token))
deba@127
   793
	  throw DataFormatError("Attribute value not found");
deba@127
   794
	if (line >> c)
deba@127
   795
	  throw DataFormatError("Extra character on the end of line");	  
deba@127
   796
deba@127
   797
	{
deba@127
   798
	  std::set<std::string>::iterator it = read_attr.find(attr);
deba@127
   799
	  if (it != read_attr.end()) {
deba@127
   800
	    std::ostringstream msg;
deba@127
   801
	    msg << "Multiple occurence of attribute " << attr;
deba@127
   802
	    throw DataFormatError(msg.str().c_str());
deba@127
   803
	  }
deba@127
   804
	  read_attr.insert(attr);
deba@127
   805
	}
deba@127
   806
	
deba@127
   807
	{
deba@127
   808
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
deba@127
   809
	  while (it != _attributes.end() && it->first == attr) {
deba@127
   810
	    it->second->set(token);
deba@127
   811
	    ++it;
deba@127
   812
	  }
deba@127
   813
	}
deba@127
   814
deba@127
   815
      }
deba@127
   816
      if (readSuccess()) {
deba@127
   817
	line.putback(c);
deba@127
   818
      }
deba@127
   819
      for (typename Attributes::iterator it = _attributes.begin();
deba@127
   820
	   it != _attributes.end(); ++it) {
deba@127
   821
	if (read_attr.find(it->first) == read_attr.end()) {
deba@127
   822
	  std::ostringstream msg;
deba@127
   823
	  msg << "Attribute not found in file: " << it->first;
deba@127
   824
	  throw DataFormatError(msg.str().c_str());
deba@127
   825
	}	
deba@127
   826
      }
deba@127
   827
    }
deba@127
   828
deba@127
   829
  public:
deba@127
   830
    
deba@127
   831
    /// \e
deba@127
   832
    void run() {
deba@127
   833
      
deba@127
   834
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
deba@127
   835
      
deba@127
   836
      bool nodes_done = false;
deba@127
   837
      bool arcs_done = false;
deba@127
   838
      bool attributes_done = false;
deba@127
   839
deba@127
   840
      line_num = 0;      
deba@127
   841
      readLine();
deba@127
   842
deba@127
   843
      while (readSuccess()) {
deba@127
   844
	skipSection();
deba@127
   845
	try {
deba@127
   846
	  char c;
deba@127
   847
	  std::string section, caption;
deba@127
   848
	  line >> c;
deba@127
   849
	  _reader_bits::readIdentifier(line, section);
deba@127
   850
	  _reader_bits::readIdentifier(line, caption);
deba@127
   851
deba@127
   852
	  if (line >> c) 
deba@127
   853
	    throw DataFormatError("Extra character on the end of line");
deba@127
   854
deba@127
   855
	  if (section == "nodes" && !nodes_done) {
deba@127
   856
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
deba@127
   857
	      readNodes();
deba@127
   858
	      nodes_done = true;
deba@127
   859
	    }
deba@127
   860
	  } else if ((section == "arcs" || section == "edges") && 
deba@127
   861
		     !arcs_done) {
deba@127
   862
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
deba@127
   863
	      readArcs();
deba@127
   864
	      arcs_done = true;
deba@127
   865
	    }
deba@127
   866
	  } else if (section == "attributes" && !attributes_done) {
deba@127
   867
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
deba@127
   868
	      readAttributes();
deba@127
   869
	      attributes_done = true;
deba@127
   870
	    }
deba@127
   871
	  } else {
deba@127
   872
	    readLine();
deba@127
   873
	    skipSection();
deba@127
   874
	  }
deba@127
   875
	} catch (DataFormatError& error) {
deba@127
   876
	  error.line(line_num);
deba@127
   877
	  throw;
deba@127
   878
	}	
deba@127
   879
      }
deba@127
   880
deba@127
   881
      if (!nodes_done) {
deba@127
   882
	throw DataFormatError("Section @nodes not found");
deba@127
   883
      }
deba@127
   884
deba@127
   885
      if (!arcs_done) {
deba@127
   886
	throw DataFormatError("Section @arcs not found");
deba@127
   887
      }
deba@127
   888
deba@127
   889
      if (!attributes_done && !_attributes.empty()) {
deba@127
   890
	throw DataFormatError("Section @attributes not found");
deba@127
   891
      }
deba@127
   892
deba@127
   893
    }
deba@127
   894
    
deba@127
   895
  };
deba@127
   896
deba@127
   897
  template <typename Digraph>
deba@127
   898
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
deba@127
   899
    return DigraphReader<Digraph>(is, digraph);
deba@127
   900
  }
deba@127
   901
deba@127
   902
  template <typename Digraph>
deba@127
   903
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
deba@127
   904
				       Digraph& digraph) {
deba@127
   905
    return DigraphReader<Digraph>(fn, digraph);
deba@127
   906
  }
deba@127
   907
deba@127
   908
  template <typename Digraph>
deba@127
   909
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
deba@127
   910
    return DigraphReader<Digraph>(fn, digraph);
deba@127
   911
  }
deba@127
   912
}
deba@127
   913
deba@127
   914
#endif