src/lemon/graph_reader.h
author alpar
Fri, 29 Apr 2005 11:04:17 +0000
changeset 1398 2f21cc34a245
parent 1394 f0c48d7fa73d
child 1408 892c29484414
permissions -rw-r--r--
Docfix
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
alpar@1359
     5
 * (Egervary Research Group on Combinatorial Optimization, 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@1333
    37
  /// \addtogroup io_group
deba@1333
    38
  /// @{
deba@1137
    39
deba@1137
    40
  /// \brief Standard ReaderTraits for the GraphReader class.
deba@1137
    41
  ///
deba@1137
    42
  /// Standard ReaderTraits for the GraphReader class.
deba@1137
    43
  /// It defines standard reading method for all type of value. 
deba@1333
    44
  /// \author Balazs Dezso
deba@1137
    45
  struct DefaultReaderTraits {
deba@1137
    46
deba@1333
    47
    /// \brief Template class for reading an value.
deba@1137
    48
    ///
deba@1137
    49
    /// Template class for reading an value.
deba@1333
    50
    /// \author Balazs Dezso
deba@1137
    51
    template <typename _Value>
deba@1137
    52
    struct Reader {
deba@1137
    53
      /// The value type.
deba@1137
    54
      typedef _Value Value;
deba@1137
    55
      /// \brief Reads a value from the given stream.
deba@1137
    56
      ///
deba@1137
    57
      /// Reads a value from the given stream.
deba@1137
    58
      void read(std::istream& is, Value& value) {
deba@1137
    59
	if (!(is >> value)) 
deba@1208
    60
	  throw DataFormatError("Default reader format exception");
deba@1137
    61
      }
deba@1137
    62
    };
deba@1137
    63
deba@1333
    64
    /// \brief Returns wheter this name is an ID map name.
deba@1333
    65
    ///
deba@1333
    66
    /// Returns wheter this name is an ID map name.
deba@1333
    67
    static bool idMapName(const std::string& name) {
deba@1333
    68
      return name == "id";
deba@1333
    69
    }
deba@1333
    70
deba@1137
    71
    /// The reader class for the not needed maps.
deba@1137
    72
    typedef Reader<std::string> DefaultReader;
deba@1137
    73
deba@1137
    74
  };
deba@1137
    75
deba@1137
    76
  /// \brief Reader class for quoted strings.
deba@1137
    77
  ///
deba@1137
    78
  /// Reader class for quoted strings. It can process the escape
deba@1137
    79
  /// sequences in the string.
deba@1333
    80
  /// \author Balazs Dezso
deba@1137
    81
  class QuotedStringReader {
deba@1137
    82
  public:
deba@1137
    83
    typedef std::string Value;
deba@1137
    84
    
deba@1137
    85
    /// \brief Constructor for the reader.
deba@1137
    86
    ///
deba@1137
    87
    /// Constructor for the reader. If the given parameter is true
deba@1137
    88
    /// the reader processes the escape sequences.
deba@1137
    89
    QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
deba@1137
    90
    
deba@1137
    91
    /// \brief Reads a quoted string from the given stream.
deba@1137
    92
    ///
deba@1137
    93
    /// Reads a quoted string from the given stream.
deba@1137
    94
    void read(std::istream& is, std::string& value) {
deba@1137
    95
      char c;
deba@1137
    96
      value.clear();
deba@1311
    97
      is >> std::ws;
deba@1137
    98
      if (!is.get(c) || c != '\"') 
deba@1208
    99
	throw DataFormatError("Quoted string format error");
deba@1137
   100
      while (is.get(c) && c != '\"') {
deba@1137
   101
	if (escaped && c == '\\') {
deba@1137
   102
	  value += readEscape(is);
deba@1137
   103
	} else {
deba@1137
   104
	  value += c;
deba@1137
   105
	}
deba@1137
   106
      }
deba@1208
   107
      if (!is) throw DataFormatError("Quoted string format error");
deba@1137
   108
    }
deba@1137
   109
deba@1137
   110
  private:
deba@1137
   111
    
deba@1137
   112
    static char readEscape(std::istream& is) {
deba@1137
   113
      char c;
deba@1137
   114
      switch (is.get(c), c) {
deba@1137
   115
      case '\\':
deba@1137
   116
	return '\\';
deba@1137
   117
      case '\"':
deba@1137
   118
	return '\"';
deba@1137
   119
      case '\'':
deba@1137
   120
	return '\'';
deba@1137
   121
      case '\?':
deba@1137
   122
	return '\?';
deba@1137
   123
      case 'a':
deba@1137
   124
	return '\a';
deba@1137
   125
      case 'b':
deba@1137
   126
	return '\b';
deba@1137
   127
      case 'f':
deba@1137
   128
	return '\f';
deba@1137
   129
      case 'n':
deba@1137
   130
	return '\n';
deba@1137
   131
      case 'r':
deba@1137
   132
	return '\r';
deba@1137
   133
      case 't':
deba@1137
   134
	return '\t';
deba@1137
   135
      case 'v':
deba@1137
   136
	return '\v';
deba@1137
   137
      case 'x':
deba@1137
   138
	{
deba@1137
   139
	  int code;
deba@1137
   140
	  if (!is.get(c) || !isHex(c)) 
deba@1208
   141
	    throw DataFormatError("Escape format error");
deba@1137
   142
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
deba@1137
   143
	  else code = code * 16 + valueHex(c);
deba@1137
   144
	  return code;
deba@1137
   145
	}
deba@1137
   146
      default:
deba@1137
   147
	{
deba@1137
   148
	  int code;
deba@1137
   149
	  if (!isOct(c)) 
deba@1208
   150
	    throw DataFormatError("Escape format error");
deba@1137
   151
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
deba@1137
   152
	    is.putback(c);
deba@1137
   153
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
deba@1137
   154
	    is.putback(c);
deba@1137
   155
	  else code = code * 8 + valueOct(c);
deba@1137
   156
	  return code;
deba@1137
   157
	}	      
deba@1137
   158
      } 
deba@1137
   159
    }
deba@1137
   160
deba@1137
   161
    static bool isOct(char c) {
deba@1137
   162
      return '0' <= c && c <='7'; 
deba@1137
   163
    }
deba@1137
   164
    
deba@1137
   165
    static int valueOct(char c) {
deba@1137
   166
      return c - '0';
deba@1137
   167
    }
deba@1137
   168
deba@1137
   169
   static bool isHex(char c) {
deba@1137
   170
      return ('0' <= c && c <= '9') || 
deba@1137
   171
	('a' <= c && c <= 'z') || 
deba@1137
   172
	('A' <= c && c <= 'Z'); 
deba@1137
   173
    }
deba@1137
   174
    
deba@1137
   175
    static int valueHex(char c) {
deba@1137
   176
      if ('0' <= c && c <= '9') return c - '0';
deba@1137
   177
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
deba@1137
   178
      return c - 'A' + 10;
deba@1137
   179
    }
deba@1137
   180
deba@1137
   181
    bool escaped;
deba@1137
   182
  };
deba@1137
   183
deba@1396
   184
  class GUIReader {
deba@1396
   185
  public:
deba@1396
   186
    virtual void read(std::istream& is) = 0;
deba@1396
   187
  };
deba@1396
   188
deba@1137
   189
  /// \brief The graph reader class.
deba@1137
   190
  ///
deba@1333
   191
  ///
deba@1333
   192
  /// The given file format may contain several maps and labeled nodes or 
deba@1333
   193
  /// edges.
deba@1333
   194
  ///
deba@1333
   195
  /// If you read a graph you need not read all the maps and items just those
deba@1333
   196
  /// that you need. The interface of the \c GraphReader is very similar to
deba@1333
   197
  /// the GraphWriter but the reading method does not depend on the order the
deba@1333
   198
  /// given commands.
deba@1333
   199
  ///
deba@1333
   200
  /// The reader object suppose that each not readed value does not contain 
deba@1333
   201
  /// whitespaces, therefore it has some extra possibilities to control how
deba@1333
   202
  /// it should skip the values when the string representation contains spaces.
deba@1333
   203
  ///
deba@1333
   204
  /// \code
deba@1333
   205
  /// GraphReader<ListGraph> reader(std::cin, graph);
deba@1333
   206
  /// \endcode
deba@1333
   207
  ///
deba@1394
   208
  /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
deba@1333
   209
  /// If there is a map that you do not want to read from the file and there is
deba@1333
   210
  /// whitespace in the string represenation of the values then you should
deba@1333
   211
  /// call the \c skipNodeMap() template member function with proper 
deba@1333
   212
  /// parameters.
deba@1333
   213
  ///
deba@1333
   214
  /// \code
deba@1394
   215
  /// reader.readNodeMap("x-coord", xCoordMap);
deba@1394
   216
  /// reader.readNodeMap("y-coord", yCoordMap);
deba@1333
   217
  ///
deba@1394
   218
  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
deba@1333
   219
  /// reader.skipNodeMap<QuotedStringReader>("description");
deba@1333
   220
  ///
deba@1394
   221
  /// reader.readNodeMap("color", colorMap);
deba@1333
   222
  /// \endcode
deba@1333
   223
  ///
deba@1394
   224
  /// With the \c readEdgeMap() member function you can give an edge map
deba@1333
   225
  /// reading command similar to the NodeMaps. 
deba@1333
   226
  ///
deba@1333
   227
  /// \code
deba@1394
   228
  /// reader.readEdgeMap("weight", weightMap);
deba@1394
   229
  /// reader.readEdgeMap("label", labelMap);
deba@1333
   230
  /// \endcode
deba@1333
   231
  ///
deba@1394
   232
  /// With \c readNode() and \c readEdge() functions you can read labeled Nodes 
deba@1333
   233
  /// and Edges.
deba@1333
   234
  ///
deba@1333
   235
  /// \code
deba@1394
   236
  /// reader.readNode("source", sourceNode);
deba@1394
   237
  /// reader.readNode("target", targetNode);
deba@1333
   238
  ///
deba@1394
   239
  /// reader.readEdge("observed", edge);
deba@1333
   240
  /// \endcode
deba@1333
   241
  ///
deba@1333
   242
  /// After you give all read commands you must call the \c run() member
deba@1333
   243
  /// function, which execute all the commands.
deba@1333
   244
  ///
deba@1333
   245
  /// \code
deba@1333
   246
  /// reader.run();
deba@1333
   247
  /// \endcode
deba@1333
   248
  ///
alpar@1287
   249
  /// \see DefaultReaderTraits
alpar@1287
   250
  /// \see QuotedStringReader
alpar@1138
   251
  /// \see \ref GraphWriter
alpar@1138
   252
  /// \see \ref graph-io-page
deba@1333
   253
  /// \author Balazs Dezso
deba@1137
   254
  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
deba@1137
   255
  class GraphReader {
deba@1137
   256
  public:
deba@1137
   257
    
deba@1137
   258
    typedef _Graph Graph;
deba@1137
   259
    typedef typename Graph::Node Node;
deba@1137
   260
    typedef typename Graph::Edge Edge;
deba@1137
   261
deba@1137
   262
    typedef _ReaderTraits ReaderTraits;
deba@1137
   263
    typedef typename ReaderTraits::DefaultReader DefaultReader;
deba@1137
   264
deba@1137
   265
    /// \brief Construct a new GraphReader.
deba@1137
   266
    ///
deba@1208
   267
    /// Construct a new GraphReader. It reads into the given graph
deba@1208
   268
    /// and it use the given reader as the default skipper.
deba@1137
   269
    GraphReader(std::istream& _is, Graph& _graph, 
deba@1137
   270
		const DefaultReader& _reader = DefaultReader()) 
deba@1396
   271
      : gui_reader(0), is(_is), graph(_graph), 
deba@1396
   272
	nodeSkipper(_reader), edgeSkipper(_reader) {}
deba@1137
   273
deba@1137
   274
    /// \brief Destruct the graph reader.
deba@1137
   275
    ///
deba@1137
   276
    /// Destruct the graph reader.
deba@1137
   277
    ~GraphReader() {
deba@1137
   278
      for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
deba@1137
   279
	   it != node_map_readers.end(); ++it) {
deba@1137
   280
	delete it->second;
deba@1137
   281
      }
deba@1137
   282
deba@1137
   283
      for (typename EdgeMapReaders::iterator it = edge_map_readers.begin(); 
deba@1137
   284
	   it != edge_map_readers.end(); ++it) {
deba@1137
   285
	delete it->second;
deba@1137
   286
      }
deba@1137
   287
deba@1137
   288
    }
deba@1137
   289
deba@1137
   290
    /// \brief Add a new node map reader command for the reader.
deba@1137
   291
    ///
deba@1137
   292
    /// Add a new node map reader command for the reader.
deba@1137
   293
    template <typename Map>
deba@1394
   294
    GraphReader& readNodeMap(std::string name, Map& map) {
deba@1394
   295
      return readNodeMap<typename ReaderTraits::template 
deba@1137
   296
	Reader<typename Map::Value>, Map>(name, map);
deba@1137
   297
    }
deba@1137
   298
deba@1137
   299
    /// \brief Add a new node map reader command for the reader.
deba@1137
   300
    ///
deba@1137
   301
    /// Add a new node map reader command for the reader.
deba@1137
   302
    template <typename Reader, typename Map>
deba@1394
   303
    GraphReader& readNodeMap(std::string name, Map& map, 
deba@1137
   304
			     const Reader& reader = Reader()) {
deba@1137
   305
      if (node_map_readers.find(name) != node_map_readers.end()) {
deba@1208
   306
	ErrorMessage msg;
deba@1208
   307
	msg << "Multiple read rule for node map: " << name;
deba@1214
   308
	throw IOParameterError(msg.message());
deba@1137
   309
      }
deba@1137
   310
      node_map_readers.insert(
deba@1137
   311
        make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
deba@1137
   312
      return *this;
deba@1137
   313
    }
deba@1137
   314
deba@1137
   315
    /// \brief Add a new node map skipper command for the reader.
deba@1137
   316
    ///
deba@1137
   317
    /// Add a new node map skipper command for the reader.
deba@1137
   318
    template <typename Reader>
deba@1137
   319
    GraphReader& skipNodeMap(std::string name, 
deba@1137
   320
			     const Reader& reader = Reader()) {
deba@1137
   321
      if (node_map_readers.find(name) != node_map_readers.end()) {
deba@1208
   322
	ErrorMessage msg;
deba@1208
   323
	msg << "Multiple read rule for node map: " << name;
deba@1214
   324
	throw IOParameterError(msg.message());
deba@1137
   325
      }
deba@1137
   326
      node_map_readers.insert(
deba@1137
   327
        make_pair(name, new SkipReader<Node, Reader>(reader)));
deba@1137
   328
      return *this;
deba@1137
   329
    }
deba@1137
   330
deba@1137
   331
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   332
    ///
deba@1137
   333
    /// Add a new edge map reader command for the reader.
deba@1137
   334
    template <typename Map>
deba@1394
   335
    GraphReader& readEdgeMap(std::string name, Map& map) { 
deba@1394
   336
      return readEdgeMap<typename ReaderTraits::template
deba@1137
   337
	Reader<typename Map::Value>, Map>(name, map);
deba@1137
   338
    }
deba@1137
   339
deba@1137
   340
deba@1137
   341
    /// \brief Add a new edge map reader command for the reader.
deba@1137
   342
    ///
deba@1137
   343
    /// Add a new edge map reader command for the reader.
deba@1137
   344
    template <typename Reader, typename Map>
deba@1394
   345
    GraphReader& readEdgeMap(std::string name, Map& map,
deba@1137
   346
			     const Reader& reader = Reader()) {
deba@1137
   347
      if (edge_map_readers.find(name) != edge_map_readers.end()) {
deba@1208
   348
	ErrorMessage msg;
deba@1208
   349
	msg << "Multiple read rule for edge map: " << name;
deba@1214
   350
	throw IOParameterError(msg.message());
deba@1137
   351
      }
deba@1137
   352
      edge_map_readers.insert(
deba@1137
   353
        make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
deba@1137
   354
      return *this;
deba@1137
   355
    }
deba@1137
   356
deba@1137
   357
    /// \brief Add a new edge map skipper command for the reader.
deba@1137
   358
    ///
deba@1137
   359
    /// Add a new edge map skipper command for the reader.
deba@1137
   360
    template <typename Reader>
deba@1137
   361
    GraphReader& skipEdgeMap(std::string name,
deba@1137
   362
			     const Reader& reader = Reader()) {
deba@1137
   363
      if (edge_map_readers.find(name) != edge_map_readers.end()) {
deba@1208
   364
	ErrorMessage msg;
deba@1208
   365
	msg << "Multiple read rule for edge map: " << name;
deba@1214
   366
	throw IOParameterError(msg.message());
deba@1137
   367
      }
deba@1137
   368
      edge_map_readers.insert(
deba@1137
   369
        make_pair(name, new SkipReader<Edge, Reader>(reader)));
deba@1137
   370
      return *this;
deba@1137
   371
    }
deba@1137
   372
deba@1137
   373
    /// \brief Add a new labeled node reader for the reader.
deba@1137
   374
    ///
deba@1137
   375
    /// Add a new labeled node reader for the reader.
deba@1394
   376
    GraphReader& readNode(std::string name, Node& node) {
deba@1137
   377
      if (node_readers.find(name) != node_readers.end()) {
deba@1208
   378
	ErrorMessage msg;
deba@1208
   379
	msg << "Multiple read rule for node: " << name;
deba@1214
   380
	throw IOParameterError(msg.message());
deba@1137
   381
      }
deba@1137
   382
      node_readers.insert(make_pair(name, &node));
deba@1137
   383
      return *this;
deba@1137
   384
    }
deba@1137
   385
deba@1137
   386
    /// \brief Add a new labeled edge reader for the reader.
deba@1137
   387
    ///
deba@1137
   388
    /// Add a new labeled edge reader for the reader.
deba@1394
   389
    GraphReader& readEdge(std::string name, Edge& edge) {
deba@1137
   390
      if (edge_readers.find(name) != edge_readers.end()) {
deba@1208
   391
	ErrorMessage msg;
deba@1208
   392
	msg << "Multiple read rule for edge: " << name;
deba@1214
   393
	throw IOParameterError(msg.message());
deba@1137
   394
      }
deba@1137
   395
      edge_readers.insert(make_pair(name, &edge));
deba@1137
   396
      return *this;
deba@1137
   397
    }
deba@1137
   398
deba@1137
   399
    /// \brief Executes the reader commands.
deba@1137
   400
    ///
deba@1137
   401
    /// Executes the reader commands.
deba@1137
   402
    void run() {
deba@1137
   403
      int line_num = 0;
deba@1137
   404
      std::auto_ptr<InverterBase<Node> > nodeInverter;
deba@1137
   405
      std::auto_ptr<InverterBase<Edge> > edgeInverter;
deba@1137
   406
      try {
deba@1137
   407
	std::string line = readNotEmptyLine(is, line_num);
deba@1137
   408
	if (line.find("@nodeset") == 0) {
deba@1137
   409
	  line = readNodeSet(line_num, nodeInverter);
deba@1137
   410
	} 
deba@1137
   411
	if (line.find("@edgeset") == 0) {
deba@1137
   412
	  line = readEdgeSet(line_num, edgeInverter, nodeInverter);
deba@1137
   413
	}
deba@1137
   414
	if (line.find("@nodes") == 0) {
deba@1137
   415
	  line = readNodes(line_num, nodeInverter);
deba@1137
   416
	}
deba@1137
   417
	if (line.find("@edges") == 0) {
deba@1137
   418
	  line = readEdges(line_num, edgeInverter);
deba@1137
   419
	}
deba@1396
   420
	if (line.find("@gui") == 0) {
deba@1396
   421
	  line = readGUI(line_num);
deba@1396
   422
	}
deba@1137
   423
	if (line.find("@end") != 0) {
deba@1208
   424
	  throw DataFormatError("Invalid control sequence error");
deba@1137
   425
	}
deba@1208
   426
      } catch (DataFormatError e) {
deba@1208
   427
	e.line(line_num);
deba@1208
   428
	throw e;
deba@1137
   429
      }
deba@1137
   430
    }
deba@1137
   431
deba@1396
   432
    GraphReader& readGUI(GUIReader& reader) {
deba@1396
   433
      gui_reader = &reader;
deba@1396
   434
      return *this;
deba@1396
   435
    }
deba@1396
   436
deba@1137
   437
  private:
deba@1137
   438
deba@1137
   439
    template <typename Item> class InverterBase;
deba@1137
   440
deba@1137
   441
    std::string readNodeSet(int& line_num, 
deba@1311
   442
			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   443
      std::vector<ReaderBase<Node>* > index;
deba@1137
   444
      {
deba@1137
   445
	std::string line = readNotEmptyLine(is, line_num);    
deba@1137
   446
	std::string id;
deba@1137
   447
	std::istringstream ls(line);	
deba@1137
   448
	while (ls >> id) {
deba@1137
   449
	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
deba@1137
   450
	  if (it != node_map_readers.end()) {
deba@1137
   451
	    index.push_back(it->second);
deba@1137
   452
	    node_map_readers.erase(it);
deba@1137
   453
	  } else {
deba@1137
   454
	    index.push_back(&nodeSkipper);
deba@1137
   455
	  }
deba@1333
   456
	  if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
deba@1333
   457
	    nodeInverter.reset(index.back()->getInverter());
deba@1333
   458
	    index.back() = nodeInverter.get();
deba@1333
   459
	  }
deba@1137
   460
	}
deba@1137
   461
      }
deba@1137
   462
deba@1333
   463
//       if (index.size() == 0) {
deba@1333
   464
// 	throw DataFormatError("Cannot find node id map");
deba@1333
   465
//       }
deba@1137
   466
deba@1333
   467
//       nodeInverter = 
deba@1333
   468
// 	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
deba@1137
   469
      std::string line;
deba@1137
   470
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   471
	Node node = graph.addNode();
deba@1137
   472
	std::istringstream ls(line);
deba@1333
   473
	for (int i = 0; i < (int)index.size(); ++i) {
deba@1137
   474
	  index[i]->read(ls, node);
deba@1137
   475
	}
deba@1137
   476
      }
deba@1137
   477
      return line;
deba@1137
   478
    }
deba@1137
   479
deba@1137
   480
    std::string readEdgeSet(int& line_num, 
deba@1311
   481
			    std::auto_ptr<InverterBase<Edge> >& edgeInverter, 
deba@1311
   482
			    std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   483
      std::vector<ReaderBase<Edge>*> index;
deba@1137
   484
      {
deba@1137
   485
	std::string line = readNotEmptyLine(is, line_num);    
deba@1137
   486
	std::string id;
deba@1137
   487
	std::istringstream ls(line);	
deba@1137
   488
	while (ls >> id) {
deba@1137
   489
	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
deba@1137
   490
	  if (it != edge_map_readers.end()) {
deba@1137
   491
	    index.push_back(it->second);
deba@1137
   492
	    edge_map_readers.erase(it);
deba@1137
   493
	  } else {
deba@1137
   494
	    index.push_back(&edgeSkipper);
deba@1137
   495
	  }
deba@1333
   496
	  if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
deba@1333
   497
	    edgeInverter.reset(index.back()->getInverter());
deba@1333
   498
	    index.back() = edgeInverter.get();
deba@1333
   499
	  }
deba@1137
   500
	}
deba@1137
   501
      }
deba@1333
   502
      
deba@1333
   503
      if (nodeInverter.get() == 0) {
deba@1333
   504
 	throw DataFormatError("Cannot find node id map");
deba@1333
   505
      }
deba@1333
   506
//       if (index.size() == 0) {
deba@1333
   507
// 	throw DataFormatError("Cannot find edge id map");
deba@1333
   508
//       }
deba@1137
   509
deba@1333
   510
//       edgeInverter = 
deba@1333
   511
// 	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
deba@1137
   512
      std::string line;
deba@1137
   513
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
deba@1137
   514
	std::istringstream ls(line);
deba@1137
   515
	Node source = nodeInverter->read(ls);
deba@1137
   516
	Node target = nodeInverter->read(ls);
deba@1137
   517
	Edge edge = graph.addEdge(source, target);
deba@1333
   518
	for (int i = 0; i < (int)index.size(); ++i) {
deba@1137
   519
	  index[i]->read(ls, edge);
deba@1137
   520
	}
deba@1137
   521
      }      
deba@1137
   522
      return line;
deba@1137
   523
    }
deba@1137
   524
deba@1137
   525
    std::string readNodes(int& line_num, 
deba@1311
   526
			  std::auto_ptr<InverterBase<Node> >& nodeInverter) {
deba@1137
   527
      std::string line;
deba@1333
   528
      if (nodeInverter.get() == 0) {
deba@1333
   529
 	throw DataFormatError("Cannot find node id map");
deba@1333
   530
      }
deba@1137
   531
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   532
	std::istringstream ls(line);
deba@1137
   533
	std::string name;
deba@1137
   534
	ls >> name;
deba@1137
   535
	typename NodeReaders::iterator it = node_readers.find(name);
deba@1137
   536
	if (it != node_readers.end()) {
deba@1137
   537
	  *(it -> second) = nodeInverter->read(ls);
deba@1137
   538
	} 
deba@1137
   539
      }        
deba@1137
   540
      return line;
deba@1137
   541
    }
deba@1137
   542
deba@1137
   543
    std::string readEdges(int& line_num, 
deba@1311
   544
			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
deba@1137
   545
      std::string line;
deba@1333
   546
      if (edgeInverter.get() == 0) {
deba@1333
   547
 	throw DataFormatError("Cannot find edge id map");
deba@1333
   548
      }
deba@1137
   549
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1137
   550
	std::istringstream ls(line);
deba@1137
   551
	std::string name;
deba@1137
   552
	ls >> name;
deba@1137
   553
	typename EdgeReaders::iterator it = edge_readers.find(name);
deba@1137
   554
	if (it != edge_readers.end()) {
deba@1137
   555
	  *(it -> second) = edgeInverter->read(ls);
deba@1137
   556
	} 
deba@1137
   557
      }        
deba@1137
   558
      return line;    
deba@1137
   559
    }
deba@1137
   560
deba@1396
   561
    std::string readGUI(int& line_num) {
deba@1396
   562
      std::stringstream section;
deba@1396
   563
      std::string line;
deba@1396
   564
      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
deba@1396
   565
	section << line << std::endl;
deba@1396
   566
      }
deba@1396
   567
      if (gui_reader != 0) {
deba@1396
   568
	gui_reader->read(section);
deba@1396
   569
      }
deba@1396
   570
      return line;
deba@1396
   571
    }
deba@1396
   572
deba@1137
   573
    std::string readNotEmptyLine(std::istream& is, int& line_num) {
deba@1137
   574
      std::string line;
deba@1137
   575
      while (++line_num, getline(is, line)) {	
deba@1333
   576
	int vi = line.find('#');
deba@1333
   577
	if (vi != (int)::std::string::npos) {
deba@1333
   578
	  line = line.substr(0, vi);
deba@1333
   579
	}
deba@1333
   580
	vi = line.find_first_not_of(" \t");
deba@1333
   581
	if (vi != (int)std::string::npos) { 
deba@1137
   582
	  return line.substr(vi);
deba@1137
   583
	}
deba@1137
   584
      }
deba@1208
   585
      throw DataFormatError("End of stream error");
deba@1137
   586
    }
deba@1137
   587
    
deba@1333
   588
    template <typename _Item>
deba@1333
   589
    class ReaderBase;
deba@1137
   590
    
deba@1137
   591
    template <typename _Item>
deba@1333
   592
    class InverterBase : public ReaderBase<_Item> {
deba@1137
   593
    public:
deba@1137
   594
      typedef _Item Item;
deba@1137
   595
      virtual void read(std::istream&, const Item&) = 0;
deba@1137
   596
      virtual Item read(std::istream&) = 0;
deba@1333
   597
deba@1333
   598
      virtual InverterBase<_Item>* getInverter() {
deba@1333
   599
	return this;
deba@1333
   600
      }
deba@1137
   601
    };
deba@1137
   602
deba@1137
   603
    template <typename _Item, typename _Map, typename _Reader>
deba@1137
   604
    class MapReaderInverter : public InverterBase<_Item> {
deba@1137
   605
    public:
deba@1137
   606
      typedef _Item Item;
deba@1137
   607
      typedef _Reader Reader;
deba@1137
   608
      typedef typename Reader::Value Value;
deba@1137
   609
      typedef _Map Map;
deba@1137
   610
      typedef std::map<Value, Item> Inverse;
deba@1137
   611
deba@1137
   612
      Map& map;
deba@1137
   613
      Reader reader;
deba@1137
   614
      Inverse inverse;
deba@1137
   615
deba@1137
   616
      MapReaderInverter(Map& _map, const Reader& _reader) 
deba@1137
   617
	: map(_map), reader(_reader) {}
deba@1137
   618
deba@1137
   619
      virtual ~MapReaderInverter() {}
deba@1137
   620
deba@1137
   621
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   622
	Value value;
deba@1137
   623
	reader.read(is, value);
deba@1137
   624
	map.set(item, value);
deba@1137
   625
	typename Inverse::iterator it = inverse.find(value);
deba@1137
   626
	if (it == inverse.end()) {
deba@1311
   627
	  inverse.insert(std::make_pair(value, item));
deba@1137
   628
	} else {
deba@1208
   629
	  throw DataFormatError("Multiple ID occurence");
deba@1137
   630
	}
deba@1137
   631
      }
deba@1137
   632
deba@1137
   633
      virtual Item read(std::istream& is) {
deba@1137
   634
	Value value;
deba@1137
   635
	reader.read(is, value);	
deba@1137
   636
	typename Inverse::const_iterator it = inverse.find(value);
deba@1137
   637
	if (it != inverse.end()) {
deba@1137
   638
	  return it->second;
deba@1137
   639
	} else {
deba@1208
   640
	  throw DataFormatError("Invalid ID error");
deba@1137
   641
	}
deba@1137
   642
      }      
deba@1137
   643
    };
deba@1137
   644
deba@1137
   645
    template <typename _Item, typename _Reader>
deba@1137
   646
    class SkipReaderInverter : public InverterBase<_Item> {
deba@1137
   647
    public:
deba@1137
   648
      typedef _Item Item;
deba@1137
   649
      typedef _Reader Reader;
deba@1137
   650
      typedef typename Reader::Value Value;
deba@1137
   651
      typedef std::map<Value, Item> Inverse;
deba@1137
   652
deba@1137
   653
      Reader reader;
deba@1137
   654
deba@1137
   655
      SkipReaderInverter(const Reader& _reader) 
deba@1137
   656
	: reader(_reader) {}
deba@1137
   657
deba@1137
   658
      virtual ~SkipReaderInverter() {}
deba@1137
   659
deba@1137
   660
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   661
	Value value;
deba@1137
   662
	reader.read(is, value);
deba@1137
   663
	typename Inverse::iterator it = inverse.find(value);
deba@1137
   664
	if (it == inverse.end()) {
deba@1311
   665
	  inverse.insert(std::make_pair(value, item));
deba@1137
   666
	} else {
deba@1208
   667
	  throw DataFormatError("Multiple ID occurence error");
deba@1137
   668
	}
deba@1137
   669
      }
deba@1137
   670
deba@1137
   671
      virtual Item read(std::istream& is) {
deba@1137
   672
	Value value;
deba@1137
   673
	reader.read(is, value);	
deba@1137
   674
	typename Inverse::const_iterator it = inverse.find(value);
deba@1137
   675
	if (it != inverse.end()) {
deba@1137
   676
	  return it->second;
deba@1137
   677
	} else {
deba@1208
   678
	  throw DataFormatError("Invalid ID error");
deba@1137
   679
	}
deba@1137
   680
      }      
deba@1137
   681
    private:
deba@1137
   682
      Inverse inverse;
deba@1137
   683
    };
deba@1137
   684
deba@1137
   685
    // Readers
deba@1137
   686
deba@1137
   687
    template <typename _Item>    
deba@1137
   688
    class ReaderBase {
deba@1137
   689
    public:
deba@1137
   690
      typedef _Item Item;
deba@1137
   691
deba@1137
   692
      //      virtual ~ReaderBase() {}
deba@1137
   693
deba@1137
   694
      virtual void read(std::istream& is, const Item& item) = 0;
deba@1137
   695
      virtual InverterBase<_Item>* getInverter() = 0;
deba@1137
   696
    };
deba@1137
   697
deba@1137
   698
    template <typename _Item, typename _Map, typename _Reader>
deba@1137
   699
    class MapReader : public ReaderBase<_Item> {
deba@1137
   700
    public:
deba@1137
   701
      typedef _Map Map;
deba@1137
   702
      typedef _Reader Reader;
deba@1137
   703
      typedef typename Reader::Value Value;
deba@1137
   704
      typedef _Item Item;
deba@1137
   705
      
deba@1137
   706
      Map& map;
deba@1137
   707
      Reader reader;
deba@1137
   708
deba@1137
   709
      MapReader(Map& _map, const Reader& _reader) 
deba@1137
   710
	: map(_map), reader(_reader) {}
deba@1137
   711
deba@1137
   712
      virtual ~MapReader() {}
deba@1137
   713
deba@1137
   714
      virtual void read(std::istream& is, const Item& item) {
deba@1137
   715
	Value value;
deba@1137
   716
	reader.read(is, value);
deba@1137
   717
	map.set(item, value);
deba@1137
   718
      }
deba@1137
   719
deba@1137
   720
      virtual InverterBase<_Item>* getInverter() {
deba@1137
   721
	return new MapReaderInverter<Item, Map, Reader>(map, reader);
deba@1137
   722
      }
deba@1137
   723
    };
deba@1137
   724
deba@1137
   725
deba@1137
   726
    template <typename _Item, typename _Reader>
deba@1137
   727
    class SkipReader : public ReaderBase<_Item> {
deba@1137
   728
    public:
deba@1137
   729
      typedef _Reader Reader;
deba@1137
   730
      typedef typename Reader::Value Value;
deba@1137
   731
      typedef _Item Item;
deba@1137
   732
deba@1137
   733
      Reader reader;
deba@1137
   734
      SkipReader(const Reader& _reader) : reader(_reader) {}
deba@1137
   735
deba@1137
   736
      virtual ~SkipReader() {}
deba@1137
   737
alpar@1250
   738
      virtual void read(std::istream& is, const Item&) {
deba@1137
   739
	Value value;
deba@1137
   740
	reader.read(is, value);
deba@1137
   741
      }      
deba@1137
   742
deba@1137
   743
      virtual InverterBase<Item>* getInverter() {
deba@1137
   744
	return new SkipReaderInverter<Item, Reader>(reader);
deba@1137
   745
      }
deba@1137
   746
    };
deba@1137
   747
deba@1137
   748
deba@1137
   749
    typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
deba@1137
   750
    NodeMapReaders node_map_readers;
deba@1137
   751
deba@1137
   752
    typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
deba@1137
   753
    EdgeMapReaders edge_map_readers;
deba@1137
   754
deba@1137
   755
    typedef std::map<std::string, Node*> NodeReaders;
deba@1137
   756
    NodeReaders node_readers;
deba@1137
   757
deba@1137
   758
    typedef std::map<std::string, Edge*> EdgeReaders;
deba@1137
   759
    EdgeReaders edge_readers;
deba@1137
   760
deba@1396
   761
    GUIReader* gui_reader;
deba@1396
   762
deba@1137
   763
    std::istream& is;
deba@1137
   764
    Graph& graph;
deba@1137
   765
deba@1137
   766
    SkipReader<Node, DefaultReader> nodeSkipper;
deba@1137
   767
    SkipReader<Edge, DefaultReader> edgeSkipper;
deba@1137
   768
deba@1137
   769
  };
deba@1137
   770
deba@1333
   771
  /// \brief Read a graph from the input.
deba@1333
   772
  ///
deba@1333
   773
  /// Read a graph from the input.
deba@1333
   774
  /// \param is The input stream.
deba@1333
   775
  /// \param g The graph.
deba@1333
   776
  /// \param capacity The capacity map.
deba@1333
   777
  /// \param s The source node.
deba@1333
   778
  /// \param t The target node.
deba@1333
   779
  /// \param cost The cost map.
deba@1208
   780
  template<typename Graph, typename CapacityMap, typename CostMap>
deba@1208
   781
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   782
		  typename Graph::Node &s, typename Graph::Node &t, 
deba@1208
   783
		  CostMap& cost) {
deba@1208
   784
    GraphReader<Graph> reader(is, g);
deba@1394
   785
    reader.readEdgeMap("capacity", capacity);
deba@1394
   786
    reader.readEdgeMap("cost", cost);
deba@1394
   787
    reader.readNode("source", s);
deba@1394
   788
    reader.readNode("target", t);
deba@1208
   789
    reader.run();
deba@1208
   790
  }
deba@1208
   791
deba@1333
   792
  /// \brief Read a graph from the input.
deba@1333
   793
  ///
deba@1333
   794
  /// Read a graph from the input.
deba@1333
   795
  /// \param is The input stream.
deba@1333
   796
  /// \param g The graph.
deba@1333
   797
  /// \param capacity The capacity map.
deba@1333
   798
  /// \param s The source node.
deba@1333
   799
  /// \param t The target node.
deba@1208
   800
  template<typename Graph, typename CapacityMap>
deba@1208
   801
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   802
		  typename Graph::Node &s, typename Graph::Node &t) {
deba@1208
   803
    GraphReader<Graph> reader(is, g);
deba@1394
   804
    reader.readEdgeMap("capacity", capacity);
deba@1394
   805
    reader.readNode("source", s);
deba@1394
   806
    reader.readNode("target", t);
deba@1208
   807
    reader.run();
deba@1208
   808
  }
deba@1208
   809
deba@1333
   810
  /// \brief Read a graph from the input.
deba@1333
   811
  ///
deba@1333
   812
  /// Read a graph from the input.
deba@1333
   813
  /// \param is The input stream.
deba@1333
   814
  /// \param g The graph.
deba@1333
   815
  /// \param capacity The capacity map.
deba@1333
   816
  /// \param s The source node.
deba@1208
   817
  template<typename Graph, typename CapacityMap>
deba@1208
   818
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
deba@1208
   819
		  typename Graph::Node &s) {
deba@1208
   820
    GraphReader<Graph> reader(is, g);
deba@1394
   821
    reader.readEdgeMap("capacity", capacity);
deba@1394
   822
    reader.readNode("source", s);
deba@1208
   823
    reader.run();
deba@1208
   824
  }
deba@1208
   825
deba@1333
   826
  /// \brief Read a graph from the input.
deba@1333
   827
  ///
deba@1333
   828
  /// Read a graph from the input.
deba@1333
   829
  /// \param is The input stream.
deba@1333
   830
  /// \param g The graph.
deba@1333
   831
  /// \param capacity The capacity map.
deba@1208
   832
  template<typename Graph, typename CapacityMap>
deba@1208
   833
  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
deba@1208
   834
    GraphReader<Graph> reader(is, g);
deba@1394
   835
    reader.readEdgeMap("capacity", capacity);
deba@1208
   836
    reader.run();
deba@1208
   837
  }
deba@1208
   838
deba@1333
   839
  /// \brief Read a graph from the input.
deba@1333
   840
  ///
deba@1333
   841
  /// Read a graph from the input.
deba@1333
   842
  /// \param is The input stream.
deba@1333
   843
  /// \param g The graph.
deba@1208
   844
  template<typename Graph>
deba@1208
   845
  void readGraph(std::istream& is, Graph &g) {
deba@1208
   846
    GraphReader<Graph> reader(is, g);
deba@1208
   847
    reader.run();
deba@1208
   848
  }
deba@1208
   849
deba@1333
   850
  /// @}
deba@1137
   851
}
deba@1214
   852
deba@1214
   853
#endif