src/lemon/graph_reader.h
author athos
Thu, 07 Apr 2005 15:22:03 +0000
changeset 1319 6e277ba3fc76
parent 1287 984723507b86
child 1333 2640cf6547ff
permissions -rw-r--r--
Cplex interface has improved a lot.
deba@1137
     1
/* -*- C++ -*-
deba@1137
     2
 * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
deba@1137
     3
 *
alpar@1164
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1137
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
deba@1137
     6
 *
deba@1137
     7
 * Permission to use, modify and distribute this software is granted
deba@1137
     8
 * provided that this copyright notice appears in all copies. For
deba@1137
     9
 * precise terms see the accompanying LICENSE file.
deba@1137
    10
 *
deba@1137
    11
 * This software is provided "AS IS" with no warranty of any kind,
deba@1137
    12
 * express or implied, and with no claim as to its suitability for any
deba@1137
    13
 * purpose.
deba@1137
    14
 *
deba@1137
    15
 */
deba@1137
    16
alpar@1287
    17
///\ingroup io_group
deba@1137
    18
///\file
alpar@1287
    19
///\brief Lemon Graph Format reader.
deba@1137
    20
deba@1214
    21
#ifndef LEMON_GRAPH_READER_H
deba@1214
    22
#define LEMON_GRAPH_READER_H
deba@1214
    23
deba@1137
    24
#include <iostream>
deba@1137
    25
#include <sstream>
deba@1137
    26
deba@1137
    27
#include <map>
deba@1137
    28
#include <vector>
deba@1137
    29
deba@1137
    30
#include <memory>
deba@1137
    31
deba@1137
    32
#include <lemon/error.h>
deba@1137
    33
deba@1137
    34
deba@1137
    35
namespace lemon {
deba@1137
    36
deba@1137
    37
deba@1137
    38
  /// \brief Standard ReaderTraits for the GraphReader class.
deba@1137
    39
  ///
deba@1137
    40
  /// Standard ReaderTraits for the GraphReader class.
deba@1137
    41
  /// It defines standard reading method for all type of value. 
deba@1137
    42
  struct DefaultReaderTraits {
deba@1137
    43
alpar@1287
    44
   /// \brief Template class for reading an value.
deba@1137
    45
    ///
deba@1137
    46
    /// Template class for reading an value.
deba@1137
    47
    template <typename _Value>
deba@1137
    48
    struct Reader {
deba@1137
    49
      /// The value type.
deba@1137
    50
      typedef _Value Value;
deba@1137
    51
      /// \brief Reads a value from the given stream.
deba@1137
    52
      ///
deba@1137
    53
      /// Reads a value from the given stream.
deba@1137
    54
      void read(std::istream& is, Value& value) {
deba@1137
    55
	if (!(is >> value)) 
deba@1208
    56
	  throw DataFormatError("Default reader format exception");
deba@1137
    57
      }
deba@1137
    58
    };
deba@1137
    59
deba@1137
    60
    /// The reader class for the not needed maps.
deba@1137
    61
    typedef Reader<std::string> DefaultReader;
deba@1137
    62
deba@1137
    63
  };
deba@1137
    64
deba@1137
    65
  /// \brief Reader class for quoted strings.
deba@1137
    66
  ///
deba@1137
    67
  /// Reader class for quoted strings. It can process the escape
deba@1137
    68
  /// sequences in the string.
deba@1137
    69
  class QuotedStringReader {
deba@1137
    70
  public:
deba@1137
    71
    typedef std::string Value;
deba@1137
    72
    
deba@1137
    73
    /// \brief Constructor for the reader.
deba@1137
    74
    ///
deba@1137
    75
    /// Constructor for the reader. If the given parameter is true
deba@1137
    76
    /// the reader processes the escape sequences.
deba@1137
    77
    QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
deba@1137
    78
    
deba@1137
    79
    /// \brief Reads a quoted string from the given stream.
deba@1137
    80
    ///
deba@1137
    81
    /// Reads a quoted string from the given stream.
deba@1137
    82
    void read(std::istream& is, std::string& value) {
deba@1137
    83
      char c;
deba@1137
    84
      value.clear();
deba@1311
    85
      is >> std::ws;
deba@1137
    86
      if (!is.get(c) || c != '\"') 
deba@1208
    87
	throw DataFormatError("Quoted string format error");
deba@1137
    88
      while (is.get(c) && c != '\"') {
deba@1137
    89
	if (escaped && c == '\\') {
deba@1137
    90
	  value += readEscape(is);
deba@1137
    91
	} else {
deba@1137
    92
	  value += c;
deba@1137
    93
	}
deba@1137
    94
      }
deba@1208
    95
      if (!is) throw DataFormatError("Quoted string format error");
deba@1137
    96
    }
deba@1137
    97
deba@1137
    98
  private:
deba@1137
    99
    
deba@1137
   100
    static char readEscape(std::istream& is) {
deba@1137
   101
      char c;
deba@1137
   102
      switch (is.get(c), c) {
deba@1137
   103
      case '\\':
deba@1137
   104
	return '\\';
deba@1137
   105
      case '\"':
deba@1137
   106
	return '\"';
deba@1137
   107
      case '\'':
deba@1137
   108
	return '\'';
deba@1137
   109
      case '\?':
deba@1137
   110
	return '\?';
deba@1137
   111
      case 'a':
deba@1137
   112
	return '\a';
deba@1137
   113
      case 'b':
deba@1137
   114
	return '\b';
deba@1137
   115
      case 'f':
deba@1137
   116
	return '\f';
deba@1137
   117
      case 'n':
deba@1137
   118
	return '\n';
deba@1137
   119
      case 'r':
deba@1137
   120
	return '\r';
deba@1137
   121
      case 't':
deba@1137
   122
	return '\t';
deba@1137
   123
      case 'v':
deba@1137
   124
	return '\v';
deba@1137
   125
      case 'x':
deba@1137
   126
	{
deba@1137
   127
	  int code;
deba@1137
   128
	  if (!is.get(c) || !isHex(c)) 
deba@1208
   129
	    throw DataFormatError("Escape format error");
deba@1137
   130
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
deba@1137
   131
	  else code = code * 16 + valueHex(c);
deba@1137
   132
	  return code;
deba@1137
   133
	}
deba@1137
   134
      default:
deba@1137
   135
	{
deba@1137
   136
	  int code;
deba@1137
   137
	  if (!isOct(c)) 
deba@1208
   138
	    throw DataFormatError("Escape format error");
deba@1137
   139
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
deba@1137
   140
	    is.putback(c);
deba@1137
   141
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
deba@1137
   142
	    is.putback(c);
deba@1137
   143
	  else code = code * 8 + valueOct(c);
deba@1137
   144
	  return code;
deba@1137
   145
	}	      
deba@1137
   146
      } 
deba@1137
   147
    }
deba@1137
   148
deba@1137
   149
    static bool isOct(char c) {
deba@1137
   150
      return '0' <= c && c <='7'; 
deba@1137
   151
    }
deba@1137
   152
    
deba@1137
   153
    static int valueOct(char c) {
deba@1137
   154
      return c - '0';
deba@1137
   155
    }
deba@1137
   156
deba@1137
   157
   static bool isHex(char c) {
deba@1137
   158
      return ('0' <= c && c <= '9') || 
deba@1137
   159
	('a' <= c && c <= 'z') || 
deba@1137
   160
	('A' <= c && c <= 'Z'); 
deba@1137
   161
    }
deba@1137
   162
    
deba@1137
   163
    static int valueHex(char c) {
deba@1137
   164
      if ('0' <= c && c <= '9') return c - '0';
deba@1137
   165
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
deba@1137
   166
      return c - 'A' + 10;
deba@1137
   167
    }
deba@1137
   168
deba@1137
   169
    bool escaped;
deba@1137
   170
  };
deba@1137
   171
deba@1137
   172
  /// \brief The graph reader class.
deba@1137
   173
  ///
alpar@1287
   174
  /// \ingroup io_group
deba@1137
   175
  /// The reader class for the graph input.
alpar@1287
   176
  /// \see DefaultReaderTraits
alpar@1287
   177
  /// \see QuotedStringReader
alpar@1138
   178
  /// \see \ref GraphWriter
alpar@1138
   179
  /// \see \ref graph-io-page
deba@1137
   180
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1137
   181
  class GraphReader {
deba@1137
   182
  public:
deba@1137
   183
    
deba@1137
   184
    typedef _Graph Graph;
deba@1137
   185
    typedef typename Graph::Node Node;
deba@1137
   186
    typedef typename Graph::Edge Edge;
deba@1137
   187
deba@1137
   188
    typedef _ReaderTraits ReaderTraits;
deba@1137
   189
    typedef typename ReaderTraits::DefaultReader DefaultReader;
deba@1137
   190
deba@1137
   191
    /// \brief Construct a new GraphReader.
deba@1137
   192
    ///
deba@1208
   193
    /// Construct a new GraphReader. It reads into the given graph
deba@1208
   194
    /// and it use the given reader as the default skipper.
deba@1137
   195
    GraphReader(std::istream& _is, Graph& _graph, 
deba@1137
   196
		const DefaultReader& _reader = DefaultReader()) 
deba@1137
   197
      : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {}
deba@1137
   198
deba@1137
   199
    /// \brief Destruct the graph reader.
deba@1137
   200
    ///
deba@1137
   201
    /// Destruct the graph reader.
deba@1137
   202
    ~GraphReader() {
deba@1137
   203
deba@1137
   204
      for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
deba@1137
   205
	   it != node_map_readers.end(); ++it) {
deba@1137
   206
	delete it->second;
deba@1137
   207
      }
deba@1137
   208
deba@1137
   209
      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); 
deba@1137
   210
	   it != edge_map_readers.end(); ++it) {
deba@1137
   211
	delete it->second;
deba@1137
   212
      }
deba@1137
   213
deba@1137
   214
    }
deba@1137
   215
deba@1137
   216
    /// \brief Add a new node map reader command for the reader.
deba@1137
   217
    ///
deba@1137
   218
    /// Add a new node map reader command for the reader.
deba@1137
   219
    template <typename Map>
deba@1137
   220
    GraphReader& addNodeMap(std::string name, Map& map) {
deba@1137
   221
      return addNodeMap<typename ReaderTraits::template 
deba@1137
   222
	Reader<typename Map::Value>, Map>(name, map);
deba@1137
   223
    }
deba@1137
   224
deba@1137
   225
    /// \brief Add a new node map reader command for the reader.
deba@1137
   226
    ///
deba@1137
   227
    /// Add a new node map reader command for the reader.
deba@1137
   228
    template <typename Reader, typename Map>
deba@1137
   229
    GraphReader& addNodeMap(std::string name, Map& map, 
deba@1137
   230
			     const Reader& reader = Reader()) {
deba@1137
   231
      if (node_map_readers.find(name) != node_map_readers.end()) {
deba@1208
   232
	ErrorMessage msg;
deba@1208
   233
	msg << "Multiple read rule for node map: " << name;
deba@1214
   234
	throw IOParameterError(msg.message());
deba@1137
   235
      }
deba@1137
   236
      node_map_readers.insert(
deba@1137
   237
        make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
deba@1137
   238
      return *this;
deba@1137
   239
    }
deba@1137
   240
deba@1137
   241
    /// \brief Add a new node map skipper command for the reader.
deba@1137
   242
    ///
deba@1137
   243
    /// Add a new node map skipper command for the reader.
deba@1137
   244
    template <typename Reader>
deba@1137
   245
    GraphReader& skipNodeMap(std::string name, 
deba@1137
   246
			     const Reader& reader = Reader()) {
deba@1137
   247
      if (node_map_readers.find(name) != node_map_readers.end()) {
deba@1208
   248
	ErrorMessage msg;
deba@1208
   249
	msg << "Multiple read rule for node map: " << name;
deba@1214
   250
	throw IOParameterError(msg.message());
deba@1137
   251
      }
deba@1137
   252
      node_map_readers.insert(
deba@1137
   253
        make_pair(name, new SkipReader<Node, Reader>(reader)));
deba@1137
   254
      return *this;
deba@1137
   255
    }
deba@1137
   256
deba@1137
   257
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   258
    ///
deba@1137
   259
    /// Add a new edge map reader command for the reader.
deba@1137
   260
    template <typename Map>
deba@1137
   261
    GraphReader& addEdgeMap(std::string name, Map& map) { 
deba@1137
   262
      return addEdgeMap<typename ReaderTraits::template
deba@1137
   263
	Reader<typename Map::Value>, Map>(name, map);
deba@1137
   264
    }
deba@1137
   265
deba@1137
   266
deba@1137
   267
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   268
    ///
deba@1137
   269
    /// Add a new edge map reader command for the reader.
deba@1137
   270
    template <typename Reader, typename Map>
deba@1137
   271
    GraphReader& addEdgeMap(std::string name, Map& map,
deba@1137
   272
			     const Reader& reader = Reader()) {
deba@1137
   273
      if (edge_map_readers.find(name) != edge_map_readers.end()) {
deba@1208
   274
	ErrorMessage msg;
deba@1208
   275
	msg << "Multiple read rule for edge map: " << name;
deba@1214
   276
	throw IOParameterError(msg.message());
deba@1137
   277
      }
deba@1137
   278
      edge_map_readers.insert(
deba@1137
   279
        make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
deba@1137
   280
      return *this;
deba@1137
   281
    }
deba@1137
   282
deba@1137
   283
    /// \brief Add a new edge map skipper command for the reader.
deba@1137
   284
    ///
deba@1137
   285
    /// Add a new edge map skipper command for the reader.
deba@1137
   286
    template <typename Reader>
deba@1137
   287
    GraphReader& skipEdgeMap(std::string name,
deba@1137
   288
			     const Reader& reader = Reader()) {
deba@1137
   289
      if (edge_map_readers.find(name) != edge_map_readers.end()) {
deba@1208
   290
	ErrorMessage msg;
deba@1208
   291
	msg << "Multiple read rule for edge map: " << name;
deba@1214
   292
	throw IOParameterError(msg.message());
deba@1137
   293
      }
deba@1137
   294
      edge_map_readers.insert(
deba@1137
   295
        make_pair(name, new SkipReader<Edge, Reader>(reader)));
deba@1137
   296
      return *this;
deba@1137
   297
    }
deba@1137
   298
deba@1137
   299
    /// \brief Add a new labeled node reader for the reader.
deba@1137
   300
    ///
deba@1137
   301
    /// Add a new labeled node reader for the reader.
deba@1137
   302
    GraphReader& addNode(std::string name, Node& node) {
deba@1137
   303
      if (node_readers.find(name) != node_readers.end()) {
deba@1208
   304
	ErrorMessage msg;
deba@1208
   305
	msg << "Multiple read rule for node: " << name;
deba@1214
   306
	throw IOParameterError(msg.message());
deba@1137
   307
      }
deba@1137
   308
      node_readers.insert(make_pair(name, &node));
deba@1137
   309
      return *this;
deba@1137
   310
    }
deba@1137
   311
deba@1137
   312
    /// \brief Add a new labeled edge reader for the reader.
deba@1137
   313
    ///
deba@1137
   314
    /// Add a new labeled edge reader for the reader.
deba@1137
   315
    GraphReader& addEdge(std::string name, Edge& edge) {
deba@1137
   316
      if (edge_readers.find(name) != edge_readers.end()) {
deba@1208
   317
	ErrorMessage msg;
deba@1208
   318
	msg << "Multiple read rule for edge: " << name;
deba@1214
   319
	throw IOParameterError(msg.message());
deba@1137
   320
      }
deba@1137
   321
      edge_readers.insert(make_pair(name, &edge));
deba@1137
   322
      return *this;
deba@1137
   323
    }
deba@1137
   324
deba@1137
   325
    /// \brief Executes the reader commands.
deba@1137
   326
    ///
deba@1137
   327
    /// Executes the reader commands.
deba@1137
   328
    void run() {
deba@1137
   329
      int line_num = 0;
deba@1137
   330
      std::auto_ptr<InverterBase<Node> > nodeInverter;
deba@1137
   331
      std::auto_ptr<InverterBase<Edge> > edgeInverter;
deba@1137
   332
      try {
deba@1137
   333
	std::string line = readNotEmptyLine(is, line_num);
deba@1137
   334
	if (line.find("@nodeset") == 0) {
deba@1137
   335
	  line = readNodeSet(line_num, nodeInverter);
deba@1137
   336
	} 
deba@1137
   337
	if (line.find("@edgeset") == 0) {
deba@1137
   338
	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
deba@1137
   339
	}
deba@1137
   340
	if (line.find("@nodes") == 0) {
deba@1137
   341
	  line = readNodes(line_num, nodeInverter);
deba@1137
   342
	}
deba@1137
   343
	if (line.find("@edges") == 0) {
deba@1137
   344
	  line = readEdges(line_num, edgeInverter);
deba@1137
   345
	}
deba@1137
   346
	if (line.find("@end") != 0) {
deba@1208
   347
	  throw DataFormatError("Invalid control sequence error");
deba@1137
   348
	}
deba@1208
   349
      } catch (DataFormatError e) {
deba@1208
   350
	e.line(line_num);
deba@1208
   351
	throw e;
deba@1137
   352
      }
deba@1137
   353
    }
deba@1137
   354
deba@1137
   355
  private:
deba@1137
   356
deba@1137
   357
    template <typename Item> class InverterBase;
deba@1137
   358
deba@1137
   359
    std::string readNodeSet(int& line_num, 
deba@1311
   360
			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   361
      std::vector<ReaderBase<Node>* > index;
deba@1137
   362
      {
deba@1137
   363
	std::string line = readNotEmptyLine(is, line_num);    
deba@1137
   364
	std::string id;
deba@1137
   365
	std::istringstream ls(line);	
deba@1137
   366
	while (ls >> id) {
deba@1137
   367
	  if (id[0] == '#') break;
deba@1137
   368
	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
deba@1137
   369
	  if (it != node_map_readers.end()) {
deba@1137
   370
	    index.push_back(it->second);
deba@1137
   371
	    node_map_readers.erase(it);
deba@1137
   372
	  } else {
deba@1137
   373
	    index.push_back(&nodeSkipper);
deba@1137
   374
	  }
deba@1137
   375
	}
deba@1137
   376
      }
deba@1137
   377
deba@1137
   378
      if (index.size() == 0) {
deba@1208
   379
	throw DataFormatError("Cannot find node id map");
deba@1137
   380
      }
deba@1137
   381
deba@1311
   382
      nodeInverter = 
deba@1311
   383
	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
deba@1137
   384
      std::string line;
deba@1137
   385
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   386
	Node node = graph.addNode();
deba@1137
   387
	std::istringstream ls(line);
deba@1137
   388
	nodeInverter->read(ls, node);
deba@1137
   389
	for (int i = 1; i < (int)index.size(); ++i) {
deba@1137
   390
	  index[i]->read(ls, node);
deba@1137
   391
	}
deba@1137
   392
      }
deba@1137
   393
      return line;
deba@1137
   394
    }
deba@1137
   395
deba@1137
   396
    std::string readEdgeSet(int& line_num, 
deba@1311
   397
			    std::auto_ptr<InverterBase<Edge> >& edgeInverter, 
deba@1311
   398
			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   399
      std::vector<ReaderBase<Edge>*> index;
deba@1137
   400
      {
deba@1137
   401
	std::string line = readNotEmptyLine(is, line_num);    
deba@1137
   402
	std::string id;
deba@1137
   403
	std::istringstream ls(line);	
deba@1137
   404
	while (ls >> id) {
deba@1137
   405
	  if (id[0] == '#') break;
deba@1137
   406
	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
deba@1137
   407
	  if (it != edge_map_readers.end()) {
deba@1137
   408
	    index.push_back(it->second);
deba@1137
   409
	    edge_map_readers.erase(it);
deba@1137
   410
	  } else {
deba@1137
   411
	    index.push_back(&edgeSkipper);
deba@1137
   412
	  }
deba@1137
   413
	}
deba@1137
   414
      }
deba@1137
   415
deba@1137
   416
      if (index.size() == 0) {
deba@1208
   417
	throw DataFormatError("Cannot find edge id map");
deba@1137
   418
      }
deba@1137
   419
deba@1311
   420
      edgeInverter = 
deba@1311
   421
	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
deba@1137
   422
      std::string line;
deba@1137
   423
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
deba@1137
   424
	std::istringstream ls(line);
deba@1137
   425
	Node source = nodeInverter->read(ls);
deba@1137
   426
	Node target = nodeInverter->read(ls);
deba@1137
   427
	Edge edge = graph.addEdge(source, target);
deba@1137
   428
	edgeInverter->read(ls, edge);
deba@1137
   429
	for (int i = 1; i < (int)index.size(); ++i) {
deba@1137
   430
	  index[i]->read(ls, edge);
deba@1137
   431
	}
deba@1137
   432
      }      
deba@1137
   433
      return line;
deba@1137
   434
    }
deba@1137
   435
deba@1137
   436
    std::string readNodes(int& line_num, 
deba@1311
   437
			  std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   438
      std::string line;
deba@1137
   439
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   440
	std::istringstream ls(line);
deba@1137
   441
	std::string name;
deba@1137
   442
	ls >> name;
deba@1137
   443
	typename NodeReaders::iterator it = node_readers.find(name);
deba@1137
   444
	if (it != node_readers.end()) {
deba@1137
   445
	  *(it -> second) = nodeInverter->read(ls);
deba@1137
   446
	} 
deba@1137
   447
      }        
deba@1137
   448
      return line;
deba@1137
   449
    }
deba@1137
   450
deba@1137
   451
    std::string readEdges(int& line_num, 
deba@1311
   452
			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
deba@1137
   453
      std::string line;
deba@1137
   454
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   455
	std::istringstream ls(line);
deba@1137
   456
	std::string name;
deba@1137
   457
	ls >> name;
deba@1137
   458
	typename EdgeReaders::iterator it = edge_readers.find(name);
deba@1137
   459
	if (it != edge_readers.end()) {
deba@1137
   460
	  *(it -> second) = edgeInverter->read(ls);
deba@1137
   461
	} 
deba@1137
   462
      }        
deba@1137
   463
      return line;    
deba@1137
   464
    }
deba@1137
   465
deba@1137
   466
    std::string readNotEmptyLine(std::istream& is, int& line_num) {
deba@1137
   467
      std::string line;
deba@1137
   468
      while (++line_num, getline(is, line)) {	
deba@1137
   469
	int vi = line.find_first_not_of(" \t");
deba@1311
   470
	if (vi != (int)std::string::npos && line[vi] != '#') {
deba@1137
   471
	  return line.substr(vi);
deba@1137
   472
	}
deba@1137
   473
      }
deba@1208
   474
      throw DataFormatError("End of stream error");
deba@1137
   475
    }
deba@1137
   476
    
deba@1137
   477
    // Inverters store and give back the Item from the id,
deba@1137
   478
    // and may put the ids into a map.
deba@1137
   479
    
deba@1137
   480
    template <typename _Item>
deba@1137
   481
    class InverterBase {
deba@1137
   482
    public:
deba@1137
   483
      typedef _Item Item;
deba@1137
   484
      virtual void read(std::istream&, const Item&) = 0;
deba@1137
   485
      virtual Item read(std::istream&) = 0;
deba@1137
   486
    };
deba@1137
   487
deba@1137
   488
    template <typename _Item, typename _Map, typename _Reader>
deba@1137
   489
    class MapReaderInverter : public InverterBase<_Item> {
deba@1137
   490
    public:
deba@1137
   491
      typedef _Item Item;
deba@1137
   492
      typedef _Reader Reader;
deba@1137
   493
      typedef typename Reader::Value Value;
deba@1137
   494
      typedef _Map Map;
deba@1137
   495
      typedef std::map<Value, Item> Inverse;
deba@1137
   496
deba@1137
   497
      Map& map;
deba@1137
   498
      Reader reader;
deba@1137
   499
      Inverse inverse;
deba@1137
   500
deba@1137
   501
      MapReaderInverter(Map& _map, const Reader& _reader) 
deba@1137
   502
	: map(_map), reader(_reader) {}
deba@1137
   503
deba@1137
   504
      virtual ~MapReaderInverter() {}
deba@1137
   505
deba@1137
   506
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   507
	Value value;
deba@1137
   508
	reader.read(is, value);
deba@1137
   509
	map.set(item, value);
deba@1137
   510
	typename Inverse::iterator it = inverse.find(value);
deba@1137
   511
	if (it == inverse.end()) {
deba@1311
   512
	  inverse.insert(std::make_pair(value, item));
deba@1137
   513
	} else {
deba@1208
   514
	  throw DataFormatError("Multiple ID occurence");
deba@1137
   515
	}
deba@1137
   516
      }
deba@1137
   517
deba@1137
   518
      virtual Item read(std::istream& is) {
deba@1137
   519
	Value value;
deba@1137
   520
	reader.read(is, value);	
deba@1137
   521
	typename Inverse::const_iterator it = inverse.find(value);
deba@1137
   522
	if (it != inverse.end()) {
deba@1137
   523
	  return it->second;
deba@1137
   524
	} else {
deba@1208
   525
	  throw DataFormatError("Invalid ID error");
deba@1137
   526
	}
deba@1137
   527
      }      
deba@1137
   528
    };
deba@1137
   529
deba@1137
   530
    template <typename _Item, typename _Reader>
deba@1137
   531
    class SkipReaderInverter : public InverterBase<_Item> {
deba@1137
   532
    public:
deba@1137
   533
      typedef _Item Item;
deba@1137
   534
      typedef _Reader Reader;
deba@1137
   535
      typedef typename Reader::Value Value;
deba@1137
   536
      typedef std::map<Value, Item> Inverse;
deba@1137
   537
deba@1137
   538
      Reader reader;
deba@1137
   539
deba@1137
   540
      SkipReaderInverter(const Reader& _reader) 
deba@1137
   541
	: reader(_reader) {}
deba@1137
   542
deba@1137
   543
      virtual ~SkipReaderInverter() {}
deba@1137
   544
deba@1137
   545
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   546
	Value value;
deba@1137
   547
	reader.read(is, value);
deba@1137
   548
	typename Inverse::iterator it = inverse.find(value);
deba@1137
   549
	if (it == inverse.end()) {
deba@1311
   550
	  inverse.insert(std::make_pair(value, item));
deba@1137
   551
	} else {
deba@1208
   552
	  throw DataFormatError("Multiple ID occurence error");
deba@1137
   553
	}
deba@1137
   554
      }
deba@1137
   555
deba@1137
   556
      virtual Item read(std::istream& is) {
deba@1137
   557
	Value value;
deba@1137
   558
	reader.read(is, value);	
deba@1137
   559
	typename Inverse::const_iterator it = inverse.find(value);
deba@1137
   560
	if (it != inverse.end()) {
deba@1137
   561
	  return it->second;
deba@1137
   562
	} else {
deba@1208
   563
	  throw DataFormatError("Invalid ID error");
deba@1137
   564
	}
deba@1137
   565
      }      
deba@1137
   566
    private:
deba@1137
   567
      Inverse inverse;
deba@1137
   568
    };
deba@1137
   569
deba@1137
   570
    // Readers
deba@1137
   571
deba@1137
   572
    template <typename _Item>    
deba@1137
   573
    class ReaderBase {
deba@1137
   574
    public:
deba@1137
   575
      typedef _Item Item;
deba@1137
   576
deba@1137
   577
      //      virtual ~ReaderBase() {}
deba@1137
   578
deba@1137
   579
      virtual void read(std::istream& is, const Item& item) = 0;
deba@1137
   580
      virtual InverterBase<_Item>* getInverter() = 0;
deba@1137
   581
    };
deba@1137
   582
deba@1137
   583
    template <typename _Item, typename _Map, typename _Reader>
deba@1137
   584
    class MapReader : public ReaderBase<_Item> {
deba@1137
   585
    public:
deba@1137
   586
      typedef _Map Map;
deba@1137
   587
      typedef _Reader Reader;
deba@1137
   588
      typedef typename Reader::Value Value;
deba@1137
   589
      typedef _Item Item;
deba@1137
   590
      
deba@1137
   591
      Map& map;
deba@1137
   592
      Reader reader;
deba@1137
   593
deba@1137
   594
      MapReader(Map& _map, const Reader& _reader) 
deba@1137
   595
	: map(_map), reader(_reader) {}
deba@1137
   596
deba@1137
   597
      virtual ~MapReader() {}
deba@1137
   598
deba@1137
   599
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   600
	Value value;
deba@1137
   601
	reader.read(is, value);
deba@1137
   602
	map.set(item, value);
deba@1137
   603
      }
deba@1137
   604
deba@1137
   605
      virtual InverterBase<_Item>* getInverter() {
deba@1137
   606
	return new MapReaderInverter<Item, Map, Reader>(map, reader);
deba@1137
   607
      }
deba@1137
   608
    };
deba@1137
   609
deba@1137
   610
deba@1137
   611
    template <typename _Item, typename _Reader>
deba@1137
   612
    class SkipReader : public ReaderBase<_Item> {
deba@1137
   613
    public:
deba@1137
   614
      typedef _Reader Reader;
deba@1137
   615
      typedef typename Reader::Value Value;
deba@1137
   616
      typedef _Item Item;
deba@1137
   617
deba@1137
   618
      Reader reader;
deba@1137
   619
      SkipReader(const Reader& _reader) : reader(_reader) {}
deba@1137
   620
deba@1137
   621
      virtual ~SkipReader() {}
deba@1137
   622
alpar@1250
   623
      virtual void read(std::istream& is, const Item&) {
deba@1137
   624
	Value value;
deba@1137
   625
	reader.read(is, value);
deba@1137
   626
      }      
deba@1137
   627
deba@1137
   628
      virtual InverterBase<Item>* getInverter() {
deba@1137
   629
	return new SkipReaderInverter<Item, Reader>(reader);
deba@1137
   630
      }
deba@1137
   631
    };
deba@1137
   632
deba@1137
   633
deba@1137
   634
    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
deba@1137
   635
    NodeMapReaders node_map_readers;
deba@1137
   636
deba@1137
   637
    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
deba@1137
   638
    EdgeMapReaders edge_map_readers;
deba@1137
   639
deba@1137
   640
    typedef std::map<std::string, Node*> NodeReaders;
deba@1137
   641
    NodeReaders node_readers;
deba@1137
   642
deba@1137
   643
    typedef std::map<std::string, Edge*> EdgeReaders;
deba@1137
   644
    EdgeReaders edge_readers;
deba@1137
   645
deba@1137
   646
    std::istream& is;
deba@1137
   647
    Graph& graph;
deba@1137
   648
deba@1137
   649
    SkipReader<Node, DefaultReader> nodeSkipper;
deba@1137
   650
    SkipReader<Edge, DefaultReader> edgeSkipper;
deba@1137
   651
deba@1137
   652
  };
deba@1137
   653
deba@1208
   654
  /// Ready to use reader function.  
deba@1208
   655
  template<typename Graph, typename CapacityMap, typename CostMap>
deba@1208
   656
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   657
		  typename Graph::Node &s, typename Graph::Node &t, 
deba@1208
   658
		  CostMap& cost) {
deba@1208
   659
    GraphReader<Graph> reader(is, g);
deba@1208
   660
    reader.addEdgeMap("capacity", capacity);
deba@1208
   661
    reader.addEdgeMap("cost", cost);
deba@1208
   662
    reader.addNode("source", s);
deba@1208
   663
    reader.addNode("target", t);
deba@1208
   664
    reader.run();
deba@1208
   665
  }
deba@1208
   666
deba@1208
   667
  template<typename Graph, typename CapacityMap>
deba@1208
   668
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   669
		  typename Graph::Node &s, typename Graph::Node &t) {
deba@1208
   670
    GraphReader<Graph> reader(is, g);
deba@1208
   671
    reader.addEdgeMap("capacity", capacity);
deba@1208
   672
    reader.addNode("source", s);
deba@1208
   673
    reader.addNode("target", t);
deba@1208
   674
    reader.run();
deba@1208
   675
  }
deba@1208
   676
deba@1208
   677
  template<typename Graph, typename CapacityMap>
deba@1208
   678
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   679
		  typename Graph::Node &s) {
deba@1208
   680
    GraphReader<Graph> reader(is, g);
deba@1208
   681
    reader.addEdgeMap("capacity", capacity);
deba@1208
   682
    reader.addNode("source", s);
deba@1208
   683
    reader.run();
deba@1208
   684
  }
deba@1208
   685
deba@1208
   686
  template<typename Graph, typename CapacityMap>
deba@1208
   687
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
deba@1208
   688
    GraphReader<Graph> reader(is, g);
deba@1208
   689
    reader.addEdgeMap("capacity", capacity);
deba@1208
   690
    reader.run();
deba@1208
   691
  }
deba@1208
   692
deba@1208
   693
  template<typename Graph>
deba@1208
   694
  void readGraph(std::istream& is, Graph &g) {
deba@1208
   695
    GraphReader<Graph> reader(is, g);
deba@1208
   696
    reader.run();
deba@1208
   697
  }
deba@1208
   698
deba@1137
   699
}
deba@1214
   700
deba@1214
   701
#endif