gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Section reader for DigraphReader
0 2 0
default
2 files changed with 183 insertions and 12 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format Lemon Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences. 
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, it columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label   coordinates size    title
61 61
 1       (10,20)     10      "First node"
62 62
 2       (80,80)     8       "Second node"
63 63
 3       (40,10)     10      "Third node"
64 64
\endcode
65 65

	
66 66
The \c \@arcs section is very similar to the \c \@nodes section,
67 67
it again starts with a header line describing the names of the arc,
68 68
but the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are
70 70
the source and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
 	      capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81 81
The \c \@edges is just a synonym of \c \@arcs.
82 82

	
83 83
The \c \@attributes section contains key-value pairs, each line
84 84
consists of two tokens, an attribute name, and then an attribute value.
85 85

	
86 86
\code
87 87
 @attributes
88 88
 source 1
89 89
 target 3
90 90
 caption "LEMON test digraph"
91 91
\endcode
92 92

	
93
The \e LGF can contain extra sections, but there is no restriction on
94
the format of such sections.
95

	
93 96
*/
94 97
}
95 98

	
96 99
//  LocalWords:  whitespace whitespaces
Ignore white space 384 line context
... ...
@@ -79,934 +79,1102 @@
79 79
    };
80 80

	
81 81
    template <typename _Item, typename _Map, 
82 82
	      typename _Converter = DefaultConverter<typename _Map::Value> >
83 83
    class MapStorage : public MapStorageBase<_Item> {
84 84
    public:
85 85
      typedef _Map Map;
86 86
      typedef _Converter Converter;
87 87
      typedef _Item Item;
88 88
      
89 89
    private:
90 90
      Map& _map;
91 91
      Converter _converter;
92 92

	
93 93
    public:
94 94
      MapStorage(Map& map, const Converter& converter = Converter()) 
95 95
	: _map(map), _converter(converter) {}
96 96
      virtual ~MapStorage() {}
97 97

	
98 98
      virtual void set(const Item& item ,const std::string& value) {
99 99
	_map.set(item, _converter(value));
100 100
      }
101 101
    };
102 102

	
103 103
    class ValueStorageBase {
104 104
    public:
105 105
      ValueStorageBase() {}
106 106
      virtual ~ValueStorageBase() {}
107 107

	
108 108
      virtual void set(const std::string&) = 0;
109 109
    };
110 110

	
111 111
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
112 112
    class ValueStorage : public ValueStorageBase {
113 113
    public:
114 114
      typedef _Value Value;
115 115
      typedef _Converter Converter;
116 116

	
117 117
    private:
118 118
      Value& _value;
119 119
      Converter _converter;
120 120

	
121 121
    public:
122 122
      ValueStorage(Value& value, const Converter& converter = Converter())
123 123
 	: _value(value), _converter(converter) {}
124 124

	
125 125
      virtual void set(const std::string& value) {
126 126
	_value = _converter(value);
127 127
      }
128 128
    };
129 129

	
130 130
    template <typename Value>
131 131
    struct MapLookUpConverter {
132 132
      const std::map<std::string, Value>& _map;
133 133

	
134 134
      MapLookUpConverter(const std::map<std::string, Value>& map)
135 135
        : _map(map) {}
136 136

	
137 137
      Value operator()(const std::string& str) {
138 138
        typename std::map<std::string, Value>::const_iterator it =
139 139
          _map.find(str);
140 140
        if (it == _map.end()) {
141 141
          std::ostringstream msg;
142 142
          msg << "Item not found: " << str;
143 143
          throw DataFormatError(msg.str().c_str());
144 144
        }
145 145
        return it->second;
146 146
      }
147 147
    };
148 148

	
149 149
    bool isWhiteSpace(char c) {
150 150
      return c == ' ' || c == '\t' || c == '\v' || 
151 151
        c == '\n' || c == '\r' || c == '\f'; 
152 152
    }
153 153
    
154 154
    bool isOct(char c) {
155 155
      return '0' <= c && c <='7'; 
156 156
    }
157 157
    
158 158
    int valueOct(char c) {
159 159
      LEMON_ASSERT(isOct(c), "The character is not octal.");
160 160
      return c - '0';
161 161
    }
162 162

	
163 163
    bool isHex(char c) {
164 164
      return ('0' <= c && c <= '9') || 
165 165
	('a' <= c && c <= 'z') || 
166 166
	('A' <= c && c <= 'Z'); 
167 167
    }
168 168
    
169 169
    int valueHex(char c) {
170 170
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
171 171
      if ('0' <= c && c <= '9') return c - '0';
172 172
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
173 173
      return c - 'A' + 10;
174 174
    }
175 175

	
176 176
    bool isIdentifierFirstChar(char c) {
177 177
      return ('a' <= c && c <= 'z') ||
178 178
	('A' <= c && c <= 'Z') || c == '_';
179 179
    }
180 180

	
181 181
    bool isIdentifierChar(char c) {
182 182
      return isIdentifierFirstChar(c) ||
183 183
	('0' <= c && c <= '9');
184 184
    }
185 185

	
186 186
    char readEscape(std::istream& is) {
187 187
      char c;
188 188
      if (!is.get(c))
189 189
	throw DataFormatError("Escape format error");
190 190

	
191 191
      switch (c) {
192 192
      case '\\':
193 193
	return '\\';
194 194
      case '\"':
195 195
	return '\"';
196 196
      case '\'':
197 197
	return '\'';
198 198
      case '\?':
199 199
	return '\?';
200 200
      case 'a':
201 201
	return '\a';
202 202
      case 'b':
203 203
	return '\b';
204 204
      case 'f':
205 205
	return '\f';
206 206
      case 'n':
207 207
	return '\n';
208 208
      case 'r':
209 209
	return '\r';
210 210
      case 't':
211 211
	return '\t';
212 212
      case 'v':
213 213
	return '\v';
214 214
      case 'x':
215 215
	{
216 216
	  int code;
217 217
	  if (!is.get(c) || !isHex(c)) 
218 218
	    throw DataFormatError("Escape format error");
219 219
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
220 220
	  else code = code * 16 + valueHex(c);
221 221
	  return code;
222 222
	}
223 223
      default:
224 224
	{
225 225
	  int code;
226 226
	  if (!isOct(c)) 
227 227
	    throw DataFormatError("Escape format error");
228 228
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
229 229
	    is.putback(c);
230 230
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
231 231
	    is.putback(c);
232 232
	  else code = code * 8 + valueOct(c);
233 233
	  return code;
234 234
	}	      
235 235
      } 
236 236
    }
237 237
    
238 238
    std::istream& readToken(std::istream& is, std::string& str) {
239 239
      std::ostringstream os;
240 240

	
241 241
      char c;
242 242
      is >> std::ws;
243 243
      
244 244
      if (!is.get(c)) 
245 245
	return is;
246 246

	
247 247
      if (c == '\"') {
248 248
	while (is.get(c) && c != '\"') {
249 249
	  if (c == '\\') 
250 250
	    c = readEscape(is);
251 251
	  os << c;
252 252
	}
253 253
	if (!is) 
254 254
	  throw DataFormatError("Quoted format error");
255 255
      } else {
256 256
	is.putback(c);
257 257
	while (is.get(c) && !isWhiteSpace(c)) {
258 258
	  if (c == '\\') 
259 259
	    c = readEscape(is);
260 260
	  os << c;
261 261
	}
262 262
	if (!is) {
263 263
	  is.clear();
264 264
	} else {
265 265
	  is.putback(c);
266 266
	}
267 267
      }
268 268
      str = os.str();
269 269
      return is;
270 270
    }
271

	
272
    class Section {
273
    public:
274
      virtual ~Section() {}
275
      virtual void process(std::istream& is, int& line_num) = 0;
276
    };
277

	
278
    template <typename Functor>
279
    class LineSection : public Section {
280
    private:
281

	
282
      Functor _functor;
283

	
284
    public:
285
      
286
      LineSection(const Functor& functor) : _functor(functor) {}
287
      virtual ~LineSection() {}
288

	
289
      virtual void process(std::istream& is, int& line_num) {
290
	char c;
291
	std::string line;
292
	while (is.get(c) && c != '@') {
293
	  if (c == '\n') {
294
	    ++line_num;
295
	  } else if (c == '#') {
296
	    getline(is, line);
297
	    ++line_num;
298
	  } else if (!isWhiteSpace(c)) {
299
	    is.putback(c);
300
	    getline(is, line);
301
	    _functor(line);
302
	    ++line_num;
303
	  }
304
	}
305
	if (is) is.putback(c);
306
	else if (is.eof()) is.clear();
307
      }
308
    };
309

	
310
    template <typename Functor>
311
    class StreamSection : public Section {
312
    private:
313

	
314
      Functor _functor;
315

	
316
    public:
317
      
318
      StreamSection(const Functor& functor) : _functor(functor) {}
319
      virtual ~StreamSection() {} 
320

	
321
      virtual void process(std::istream& is, int& line_num) {
322
	_functor(is, line_num);
323
	char c;
324
	std::string line;
325
	while (is.get(c) && c != '@') {
326
	  if (c == '\n') {
327
	    ++line_num;
328
	  } else if (!isWhiteSpace(c)) {
329
	    getline(is, line);
330
	    ++line_num;
331
	  }
332
	}
333
	if (is) is.putback(c);
334
	else if (is.eof()) is.clear();	
335
      }
336
    };
271 337
    
272 338
  }
273 339

	
274 340
  /// \ingroup lemon_io
275 341
  ///  
276 342
  /// \brief LGF reader for directed graphs
277 343
  ///
278 344
  /// This utility reads an \ref lgf-format "LGF" file.
279 345
  ///
280 346
  /// The reading method does a batch processing. The user creates a
281 347
  /// reader object, then various reading rules can be added to the
282 348
  /// reader, and eventually the reading is executed with the \c run()
283 349
  /// member function. A map reading rule can be added to the reader
284 350
  /// with the \c nodeMap() or \c arcMap() members. An optional
285
  /// converter parameter can also be added as a standard functor converting from
286
  /// std::string to the value type of the map. If it is set, it will
287
  /// determine how the tokens in the file should be is converted to the map's
288
  /// value type. If the functor is not set, then a default conversion
289
  /// will be used. One map can be read into multiple map objects at the
290
  /// same time. The \c attribute(), \c node() and \c arc() functions
291
  /// are used to add attribute reading rules.
351
  /// converter parameter can also be added as a standard functor
352
  /// converting from std::string to the value type of the map. If it
353
  /// is set, it will determine how the tokens in the file should be
354
  /// is converted to the map's value type. If the functor is not set,
355
  /// then a default conversion will be used. One map can be read into
356
  /// multiple map objects at the same time. The \c attribute(), \c
357
  /// node() and \c arc() functions are used to add attribute reading
358
  /// rules.
292 359
  ///
293 360
  ///\code
294 361
  ///     DigraphReader<Digraph>(std::cin, digraph).
295 362
  ///       nodeMap("coordinates", coord_map).
296 363
  ///       arcMap("capacity", cap_map).
297 364
  ///       node("source", src).
298 365
  ///       node("target", trg).
299 366
  ///       attribute("caption", caption).
300 367
  ///       run();
301 368
  ///\endcode
302 369
  ///
303 370
  /// By default the reader uses the first section in the file of the
304 371
  /// proper type. If a section has an optional name, then it can be
305
  /// selected for reading by giving an optional name parameter to
306
  /// the \c nodes(), \c arcs() or \c attributes()
307
  /// functions.
372
  /// selected for reading by giving an optional name parameter to the
373
  /// \c nodes(), \c arcs() or \c attributes() functions. The readers
374
  /// also can load extra sections with the \c sectionLines() and
375
  /// sectionStream() functions.
308 376
  ///
309 377
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
310 378
  /// that the nodes or arcs should not be constructed (added to the
311 379
  /// graph) during the reading, but instead the label map of the items
312 380
  /// are given as a parameter of these functions. An
313 381
  /// application of these function is multipass reading, which is
314 382
  /// important if two \e \@arcs sections must be read from the
315 383
  /// file. In this example the first phase would read the node set and one
316 384
  /// of the arc sets, while the second phase would read the second arc
317 385
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
318 386
  /// The previously read label node map should be passed to the \c
319 387
  /// useNodes() functions. Another application of multipass reading when
320 388
  /// paths are given as a node map or an arc map. It is impossible read this in
321 389
  /// a single pass, because the arcs are not constructed when the node
322 390
  /// maps are read.
323 391
  template <typename _Digraph>
324 392
  class DigraphReader {
325 393
  public:
326 394

	
327 395
    typedef _Digraph Digraph;
328 396
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
329 397
    
330 398
  private:
331 399

	
332 400

	
333 401
    std::istream* _is;
334 402
    bool local_is;
335 403

	
336 404
    Digraph& _digraph;
337 405

	
338 406
    std::string _nodes_caption;
339 407
    std::string _arcs_caption;
340 408
    std::string _attributes_caption;
341 409

	
342 410
    typedef std::map<std::string, Node> NodeIndex;
343 411
    NodeIndex _node_index;
344 412
    typedef std::map<std::string, Arc> ArcIndex;
345 413
    ArcIndex _arc_index;
346 414
    
347 415
    typedef std::vector<std::pair<std::string, 
348 416
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
349 417
    NodeMaps _node_maps; 
350 418

	
351 419
    typedef std::vector<std::pair<std::string,
352 420
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
353 421
    ArcMaps _arc_maps;
354 422

	
355 423
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
356 424
      Attributes;
357 425
    Attributes _attributes;
358 426

	
427
    typedef std::map<std::string, _reader_bits::Section*> Sections;
428
    Sections _sections;
429

	
359 430
    bool _use_nodes;
360 431
    bool _use_arcs;
361 432

	
362 433
    int line_num;
363 434
    std::istringstream line;
364 435

	
365 436
  public:
366 437

	
367 438
    /// \brief Constructor
368 439
    ///
369 440
    /// Construct a directed graph reader, which reads from the given
370 441
    /// input stream.
371 442
    DigraphReader(std::istream& is, Digraph& digraph) 
372 443
      : _is(&is), local_is(false), _digraph(digraph),
373 444
	_use_nodes(false), _use_arcs(false) {}
374 445

	
375 446
    /// \brief Constructor
376 447
    ///
377 448
    /// Construct a directed graph reader, which reads from the given
378 449
    /// file.
379 450
    DigraphReader(const std::string& fn, Digraph& digraph) 
380 451
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
381 452
    	_use_nodes(false), _use_arcs(false) {}
382 453
    
383 454
    /// \brief Constructor
384 455
    ///
385 456
    /// Construct a directed graph reader, which reads from the given
386 457
    /// file.
387 458
    DigraphReader(const char* fn, Digraph& digraph) 
388 459
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
389 460
    	_use_nodes(false), _use_arcs(false) {}
390 461

	
391 462
    /// \brief Copy constructor
392 463
    ///
393 464
    /// The copy constructor transfers all data from the other reader,
394 465
    /// therefore the copied reader will not be usable more. 
395 466
    DigraphReader(DigraphReader& other) 
396 467
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
397 468
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
398 469

	
399 470
      other.is = 0;
400 471
      other.local_is = false;
401 472
      
402 473
      _node_index.swap(other._node_index);
403 474
      _arc_index.swap(other._arc_index);
404 475

	
405 476
      _node_maps.swap(other._node_maps);
406 477
      _arc_maps.swap(other._arc_maps);
407 478
      _attributes.swap(other._attributes);
408 479

	
409 480
      _nodes_caption = other._nodes_caption;
410 481
      _arcs_caption = other._arcs_caption;
411 482
      _attributes_caption = other._attributes_caption;
483

	
484
      _sections.swap(other._sections);
412 485
    }
413 486

	
414 487
    /// \brief Destructor
415 488
    ~DigraphReader() {
416 489
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
417 490
	   it != _node_maps.end(); ++it) {
418 491
	delete it->second;
419 492
      }
420 493

	
421 494
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
422 495
	   it != _arc_maps.end(); ++it) {
423 496
	delete it->second;
424 497
      }
425 498

	
426 499
      for (typename Attributes::iterator it = _attributes.begin(); 
427 500
	   it != _attributes.end(); ++it) {
428 501
	delete it->second;
429 502
      }
430 503

	
504
      for (typename Sections::iterator it = _sections.begin(); 
505
	   it != _sections.end(); ++it) {
506
	delete it->second;
507
      }
508

	
431 509
      if (local_is) {
432 510
	delete _is;
433 511
      }
434 512

	
435 513
    }
436 514

	
437 515
  private:
438 516
    
439 517
    DigraphReader& operator=(const DigraphReader&);
440 518

	
441 519
  public:
442 520

	
443 521
    /// \name Reading rules
444 522
    /// @{
445 523
    
446 524
    /// \brief Node map reading rule
447 525
    ///
448 526
    /// Add a node map reading rule to the reader.
449 527
    template <typename Map>
450 528
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
451 529
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
452 530
      _reader_bits::MapStorageBase<Node>* storage = 
453 531
	new _reader_bits::MapStorage<Node, Map>(map);
454 532
      _node_maps.push_back(std::make_pair(caption, storage));
455 533
      return *this;
456 534
    }
457 535

	
458 536
    /// \brief Node map reading rule
459 537
    ///
460 538
    /// Add a node map reading rule with specialized converter to the
461 539
    /// reader.
462 540
    template <typename Map, typename Converter>
463 541
    DigraphReader& nodeMap(const std::string& caption, Map& map, 
464 542
			   const Converter& converter = Converter()) {
465 543
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
466 544
      _reader_bits::MapStorageBase<Node>* storage = 
467 545
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
468 546
      _node_maps.push_back(std::make_pair(caption, storage));
469 547
      return *this;
470 548
    }
471 549

	
472 550
    /// \brief Arc map reading rule
473 551
    ///
474 552
    /// Add an arc map reading rule to the reader.
475 553
    template <typename Map>
476 554
    DigraphReader& arcMap(const std::string& caption, Map& map) {
477 555
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
478 556
      _reader_bits::MapStorageBase<Arc>* storage = 
479 557
	new _reader_bits::MapStorage<Arc, Map>(map);
480 558
      _arc_maps.push_back(std::make_pair(caption, storage));
481 559
      return *this;
482 560
    }
483 561

	
484 562
    /// \brief Arc map reading rule
485 563
    ///
486 564
    /// Add an arc map reading rule with specialized converter to the
487 565
    /// reader.
488 566
    template <typename Map, typename Converter>
489 567
    DigraphReader& arcMap(const std::string& caption, Map& map, 
490 568
			  const Converter& converter = Converter()) {
491 569
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
492 570
      _reader_bits::MapStorageBase<Arc>* storage = 
493 571
	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
494 572
      _arc_maps.push_back(std::make_pair(caption, storage));
495 573
      return *this;
496 574
    }
497 575

	
498 576
    /// \brief Attribute reading rule
499 577
    ///
500 578
    /// Add an attribute reading rule to the reader.
501 579
    template <typename Value>
502 580
    DigraphReader& attribute(const std::string& caption, Value& value) {
503 581
      _reader_bits::ValueStorageBase* storage = 
504 582
	new _reader_bits::ValueStorage<Value>(value);
505 583
      _attributes.insert(std::make_pair(caption, storage));
506 584
      return *this;
507 585
    }
508 586

	
509 587
    /// \brief Attribute reading rule
510 588
    ///
511 589
    /// Add an attribute reading rule with specialized converter to the
512 590
    /// reader.
513 591
    template <typename Value, typename Converter>
514 592
    DigraphReader& attribute(const std::string& caption, Value& value, 
515 593
			     const Converter& converter = Converter()) {
516 594
      _reader_bits::ValueStorageBase* storage = 
517 595
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
518 596
      _attributes.insert(std::make_pair(caption, storage));
519 597
      return *this;
520 598
    }
521 599

	
522 600
    /// \brief Node reading rule
523 601
    ///
524 602
    /// Add a node reading rule to reader.
525 603
    DigraphReader& node(const std::string& caption, Node& node) {
526 604
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
527 605
      Converter converter(_node_index);
528 606
      _reader_bits::ValueStorageBase* storage = 
529 607
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
530 608
      _attributes.insert(std::make_pair(caption, storage));
531 609
      return *this;
532 610
    }
533 611

	
534 612
    /// \brief Arc reading rule
535 613
    ///
536 614
    /// Add an arc reading rule to reader.
537 615
    DigraphReader& arc(const std::string& caption, Arc& arc) {
538 616
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
539 617
      Converter converter(_arc_index);
540 618
      _reader_bits::ValueStorageBase* storage = 
541 619
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
542 620
      _attributes.insert(std::make_pair(caption, storage));
543 621
      return *this;
544 622
    }
545 623

	
546 624
    /// @}
547 625

	
548 626
    /// \name Select section by name
549 627
    /// @{
550 628

	
551 629
    /// \brief Set \c \@nodes section to be read
552 630
    ///
553 631
    /// Set \c \@nodes section to be read
554 632
    DigraphReader& nodes(const std::string& caption) {
555 633
      _nodes_caption = caption;
556 634
      return *this;
557 635
    }
558 636

	
559 637
    /// \brief Set \c \@arcs section to be read
560 638
    ///
561 639
    /// Set \c \@arcs section to be read
562 640
    DigraphReader& arcs(const std::string& caption) {
563 641
      _arcs_caption = caption;
564 642
      return *this;
565 643
    }
566 644

	
567 645
    /// \brief Set \c \@attributes section to be read
568 646
    ///
569 647
    /// Set \c \@attributes section to be read
570 648
    DigraphReader& attributes(const std::string& caption) {
571 649
      _attributes_caption = caption;
572 650
      return *this;
573 651
    }
574 652

	
575 653
    /// @}
576 654

	
655
    /// \name Section readers
656
    /// @{
657

	
658
    /// \brief Add a section processor with line oriented reading
659
    ///
660
    /// In the \e LGF file extra sections can be placed, which contain
661
    /// any data in arbitrary format. These sections can be read with
662
    /// this function line by line. The first parameter is the type
663
    /// descriptor of the section, the second is a functor, which
664
    /// takes just one \c std::string parameter. At the reading
665
    /// process, each line of the section will be given to the functor
666
    /// object. However, the empty lines and the comment lines are
667
    /// filtered out, and the leading whitespaces are stipped from
668
    /// each processed string.
669
    ///
670
    /// For example let's see a section, which contain several
671
    /// integers, which should be inserted into a vector.
672
    ///\code
673
    ///  @numbers
674
    ///  12 45 23
675
    ///  4
676
    ///  23 6
677
    ///\endcode
678
    ///
679
    /// The functor is implemented as an struct:
680
    ///\code
681
    ///  struct NumberSection {
682
    ///    std::vector<int>& _data;
683
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
684
    ///    void operator()(const std::string& line) {
685
    ///      std::istringstream ls(line);
686
    ///      int value;
687
    ///      while (ls >> value) _data.push_back(value);
688
    ///    }
689
    ///  };
690
    ///
691
    ///  // ...
692
    ///
693
    ///  reader.sectionLines("numbers", NumberSection(vec));  
694
    ///\endcode
695
    template <typename Functor>
696
    DigraphReader& sectionLines(const std::string& type, Functor functor) {
697
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
698
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
699
		   "Multiple reading of section.");
700
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
701
		   type != "attributes", "Multiple reading of section.");
702
      _sections.insert(std::make_pair(type, 
703
        new _reader_bits::LineSection<Functor>(functor)));
704
      return *this;
705
    }
706

	
707

	
708
    /// \brief Add a section processor with stream oriented reading
709
    ///
710
    /// In the \e LGF file extra sections can be placed, which contain
711
    /// any data in arbitrary format. These sections can be read
712
    /// directly with this function. The first parameter is the type
713
    /// of the section, the second is a functor, which takes an \c
714
    /// std::istream& and an int& parameter, the latter regard to the
715
    /// line number of stream. The functor can read the input while
716
    /// the section go on, and the line number should be modified
717
    /// accordingly.
718
    template <typename Functor>
719
    DigraphReader& sectionStream(const std::string& type, Functor functor) {
720
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
721
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
722
		   "Multiple reading of section.");
723
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
724
		   type != "attributes", "Multiple reading of section.");
725
      _sections.insert(std::make_pair(type, 
726
	 new _reader_bits::StreamSection<Functor>(functor)));
727
      return *this;
728
    }    
729
    
730
    /// @}
731

	
577 732
    /// \name Using previously constructed node or arc set
578 733
    /// @{
579 734

	
580 735
    /// \brief Use previously constructed node set
581 736
    ///
582 737
    /// Use previously constructed node set, and specify the node
583 738
    /// label map.
584 739
    template <typename Map>
585 740
    DigraphReader& useNodes(const Map& map) {
586 741
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
587 742
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
588 743
      _use_nodes = true;
589 744
      _writer_bits::DefaultConverter<typename Map::Value> converter;
590 745
      for (NodeIt n(_digraph); n != INVALID; ++n) {
591 746
	_node_index.insert(std::make_pair(converter(map[n]), n));
592 747
      }
593 748
      return *this;
594 749
    }
595 750

	
596 751
    /// \brief Use previously constructed node set
597 752
    ///
598 753
    /// Use previously constructed node set, and specify the node
599 754
    /// label map and a functor which converts the label map values to
600 755
    /// std::string.
601 756
    template <typename Map, typename Converter>
602 757
    DigraphReader& useNodes(const Map& map, 
603 758
			    const Converter& converter = Converter()) {
604 759
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
605 760
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
606 761
      _use_nodes = true;
607 762
      for (NodeIt n(_digraph); n != INVALID; ++n) {
608 763
	_node_index.insert(std::make_pair(converter(map[n]), n));
609 764
      }
610 765
      return *this;
611 766
    }
612 767

	
613 768
    /// \brief Use previously constructed arc set
614 769
    ///
615 770
    /// Use previously constructed arc set, and specify the arc
616 771
    /// label map.
617 772
    template <typename Map>
618 773
    DigraphReader& useArcs(const Map& map) {
619 774
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
620 775
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
621 776
      _use_arcs = true;
622 777
      _writer_bits::DefaultConverter<typename Map::Value> converter;
623 778
      for (ArcIt a(_digraph); a != INVALID; ++a) {
624 779
	_arc_index.insert(std::make_pair(converter(map[a]), a));
625 780
      }
626 781
      return *this;
627 782
    }
628 783

	
629 784
    /// \brief Use previously constructed arc set
630 785
    ///
631 786
    /// Use previously constructed arc set, and specify the arc
632 787
    /// label map and a functor which converts the label map values to
633 788
    /// std::string.
634 789
    template <typename Map, typename Converter>
635 790
    DigraphReader& useArcs(const Map& map, 
636 791
			    const Converter& converter = Converter()) {
637 792
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
638 793
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
639 794
      _use_arcs = true;
640 795
      for (ArcIt a(_digraph); a != INVALID; ++a) {
641 796
	_arc_index.insert(std::make_pair(converter(map[a]), a));
642 797
      }
643 798
      return *this;
644 799
    }
645 800

	
646 801
    /// @}
647 802

	
648 803
  private:
649 804

	
650 805
    bool readLine() {
651 806
      std::string str;
652 807
      while(++line_num, std::getline(*_is, str)) {
653 808
	line.clear(); line.str(str);
654 809
	char c;
655 810
	if (line >> std::ws >> c && c != '#') {
656 811
	  line.putback(c);
657 812
	  return true;
658 813
	}
659 814
      }
660 815
      return false;
661 816
    }
662 817

	
663 818
    bool readSuccess() {
664 819
      return static_cast<bool>(*_is);
665 820
    }
666 821
    
667 822
    void skipSection() {
668 823
      char c;
669 824
      while (readSuccess() && line >> c && c != '@') {
670 825
	readLine();
671 826
      }
672 827
      line.putback(c);
673 828
    }
674 829

	
675 830
    void readNodes() {
676 831

	
677 832
      std::vector<int> map_index(_node_maps.size());
678 833
      int map_num, label_index;
679 834

	
680 835
      if (!readLine()) 
681 836
	throw DataFormatError("Cannot find map captions");
682 837
      
683 838
      {
684 839
	std::map<std::string, int> maps;
685 840
	
686 841
	std::string map;
687 842
	int index = 0;
688 843
	while (_reader_bits::readToken(line, map)) {
689 844
	  if (maps.find(map) != maps.end()) {
690 845
	    std::ostringstream msg;
691 846
	    msg << "Multiple occurence of node map: " << map;
692 847
	    throw DataFormatError(msg.str().c_str());
693 848
	  }
694 849
	  maps.insert(std::make_pair(map, index));
695 850
	  ++index;
696 851
	}
697 852
	
698 853
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
699 854
	  std::map<std::string, int>::iterator jt = 
700 855
	    maps.find(_node_maps[i].first);
701 856
	  if (jt == maps.end()) {
702 857
	    std::ostringstream msg;
703 858
	    msg << "Map not found in file: " << _node_maps[i].first;
704 859
	    throw DataFormatError(msg.str().c_str());
705 860
	  }
706 861
	  map_index[i] = jt->second;
707 862
	}
708 863

	
709 864
	{
710 865
	  std::map<std::string, int>::iterator jt = maps.find("label");
711 866
	  if (jt == maps.end())
712 867
	    throw DataFormatError("Label map not found in file");
713 868
	  label_index = jt->second;
714 869
	}
715 870
	map_num = maps.size();
716 871
      }
717 872

	
718 873
      char c;
719 874
      while (readLine() && line >> c && c != '@') {
720 875
	line.putback(c);
721 876

	
722 877
	std::vector<std::string> tokens(map_num);
723 878
	for (int i = 0; i < map_num; ++i) {
724 879
	  if (!_reader_bits::readToken(line, tokens[i])) {
725 880
	    std::ostringstream msg;
726 881
	    msg << "Column not found (" << i + 1 << ")";
727 882
	    throw DataFormatError(msg.str().c_str());
728 883
	  }
729 884
	}
730 885
	if (line >> std::ws >> c)
731 886
	  throw DataFormatError("Extra character on the end of line");
732 887
	
733 888
	Node n;
734 889
	if (!_use_nodes) {
735 890
	  n = _digraph.addNode();
736 891
	  _node_index.insert(std::make_pair(tokens[label_index], n));
737 892
	} else {
738 893
	  typename std::map<std::string, Node>::iterator it =
739 894
	    _node_index.find(tokens[label_index]);
740 895
	  if (it == _node_index.end()) {
741 896
	    std::ostringstream msg;
742 897
	    msg << "Node with label not found: " << tokens[label_index];
743 898
	    throw DataFormatError(msg.str().c_str());	    
744 899
	  }
745 900
	  n = it->second;
746 901
	}
747 902

	
748 903
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
749 904
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
750 905
	}
751 906

	
752 907
      }
753 908
      if (readSuccess()) {
754 909
	line.putback(c);
755 910
      }
756 911
    }
757 912

	
758 913
    void readArcs() {
759 914

	
760 915
      std::vector<int> map_index(_arc_maps.size());
761 916
      int map_num, label_index;
762 917

	
763 918
      if (!readLine()) 
764 919
	throw DataFormatError("Cannot find map captions");
765 920
      
766 921
      {
767 922
	std::map<std::string, int> maps;
768 923
	
769 924
	std::string map;
770 925
	int index = 0;
771 926
	while (_reader_bits::readToken(line, map)) {
772 927
	  if (maps.find(map) != maps.end()) {
773 928
	    std::ostringstream msg;
774 929
	    msg << "Multiple occurence of arc map: " << map;
775 930
	    throw DataFormatError(msg.str().c_str());
776 931
	  }
777 932
	  maps.insert(std::make_pair(map, index));
778 933
	  ++index;
779 934
	}
780 935
	
781 936
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
782 937
	  std::map<std::string, int>::iterator jt = 
783 938
	    maps.find(_arc_maps[i].first);
784 939
	  if (jt == maps.end()) {
785 940
	    std::ostringstream msg;
786 941
	    msg << "Map not found in file: " << _arc_maps[i].first;
787 942
	    throw DataFormatError(msg.str().c_str());
788 943
	  }
789 944
	  map_index[i] = jt->second;
790 945
	}
791 946

	
792 947
	{
793 948
	  std::map<std::string, int>::iterator jt = maps.find("label");
794 949
	  if (jt == maps.end())
795 950
	    throw DataFormatError("Label map not found in file");
796 951
	  label_index = jt->second;
797 952
	}
798 953
	map_num = maps.size();
799 954
      }
800 955

	
801 956
      char c;
802 957
      while (readLine() && line >> c && c != '@') {
803 958
	line.putback(c);
804 959

	
805 960
	std::string source_token;
806 961
	std::string target_token;
807 962

	
808 963
	if (!_reader_bits::readToken(line, source_token))
809 964
	  throw DataFormatError("Source not found");
810 965

	
811 966
	if (!_reader_bits::readToken(line, target_token))
812 967
	  throw DataFormatError("Source not found");
813 968
	
814 969
	std::vector<std::string> tokens(map_num);
815 970
	for (int i = 0; i < map_num; ++i) {
816 971
	  if (!_reader_bits::readToken(line, tokens[i])) {
817 972
	    std::ostringstream msg;
818 973
	    msg << "Column not found (" << i + 1 << ")";
819 974
	    throw DataFormatError(msg.str().c_str());
820 975
	  }
821 976
	}
822 977
	if (line >> std::ws >> c)
823 978
	  throw DataFormatError("Extra character on the end of line");
824 979
	
825 980
	Arc a;
826 981
	if (!_use_arcs) {
827 982

	
828 983
          typename NodeIndex::iterator it;
829 984
 
830 985
          it = _node_index.find(source_token);
831 986
          if (it == _node_index.end()) {
832 987
            std::ostringstream msg;
833 988
            msg << "Item not found: " << source_token;
834 989
            throw DataFormatError(msg.str().c_str());
835 990
          }
836 991
          Node source = it->second;
837 992

	
838 993
          it = _node_index.find(target_token);
839 994
          if (it == _node_index.end()) {       
840 995
            std::ostringstream msg;            
841 996
            msg << "Item not found: " << target_token;
842 997
            throw DataFormatError(msg.str().c_str());
843 998
          }                                          
844 999
          Node target = it->second;                            
845 1000

	
846 1001
	  a = _digraph.addArc(source, target);
847 1002
	  _arc_index.insert(std::make_pair(tokens[label_index], a));
848 1003
	} else {
849 1004
	  typename std::map<std::string, Arc>::iterator it =
850 1005
	    _arc_index.find(tokens[label_index]);
851 1006
	  if (it == _arc_index.end()) {
852 1007
	    std::ostringstream msg;
853 1008
	    msg << "Arc with label not found: " << tokens[label_index];
854 1009
	    throw DataFormatError(msg.str().c_str());	    
855 1010
	  }
856 1011
	  a = it->second;
857 1012
	}
858 1013

	
859 1014
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
860 1015
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
861 1016
	}
862 1017

	
863 1018
      }
864 1019
      if (readSuccess()) {
865 1020
	line.putback(c);
866 1021
      }
867 1022
    }
868 1023

	
869 1024
    void readAttributes() {
870 1025

	
871 1026
      std::set<std::string> read_attr;
872 1027

	
873 1028
      char c;
874 1029
      while (readLine() && line >> c && c != '@') {
875 1030
	line.putback(c);
876 1031
	
877 1032
	std::string attr, token;
878 1033
	if (!_reader_bits::readToken(line, attr))
879 1034
	  throw DataFormatError("Attribute name not found");
880 1035
	if (!_reader_bits::readToken(line, token))
881 1036
	  throw DataFormatError("Attribute value not found");
882 1037
	if (line >> c)
883 1038
	  throw DataFormatError("Extra character on the end of line");	  
884 1039

	
885 1040
	{
886 1041
	  std::set<std::string>::iterator it = read_attr.find(attr);
887 1042
	  if (it != read_attr.end()) {
888 1043
	    std::ostringstream msg;
889 1044
	    msg << "Multiple occurence of attribute " << attr;
890 1045
	    throw DataFormatError(msg.str().c_str());
891 1046
	  }
892 1047
	  read_attr.insert(attr);
893 1048
	}
894 1049
	
895 1050
	{
896 1051
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
897 1052
	  while (it != _attributes.end() && it->first == attr) {
898 1053
	    it->second->set(token);
899 1054
	    ++it;
900 1055
	  }
901 1056
	}
902 1057

	
903 1058
      }
904 1059
      if (readSuccess()) {
905 1060
	line.putback(c);
906 1061
      }
907 1062
      for (typename Attributes::iterator it = _attributes.begin();
908 1063
	   it != _attributes.end(); ++it) {
909 1064
	if (read_attr.find(it->first) == read_attr.end()) {
910 1065
	  std::ostringstream msg;
911 1066
	  msg << "Attribute not found in file: " << it->first;
912 1067
	  throw DataFormatError(msg.str().c_str());
913 1068
	}	
914 1069
      }
915 1070
    }
916 1071

	
917 1072
  public:
918 1073

	
919 1074
    /// \name Execution of the reader    
920 1075
    /// @{
921 1076

	
922 1077
    /// \brief Start the batch processing
923 1078
    ///
924 1079
    /// This function starts the batch processing
925 1080
    void run() {
926 1081
      
927 1082
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
928 1083
      
929 1084
      bool nodes_done = false;
930 1085
      bool arcs_done = false;
931 1086
      bool attributes_done = false;
1087
      std::set<std::string> extra_sections;
932 1088

	
933 1089
      line_num = 0;      
934 1090
      readLine();
935 1091

	
936 1092
      while (readSuccess()) {
937 1093
	skipSection();
938 1094
	try {
939 1095
	  char c;
940 1096
	  std::string section, caption;
941 1097
	  line >> c;
942 1098
	  _reader_bits::readToken(line, section);
943 1099
	  _reader_bits::readToken(line, caption);
944 1100

	
945 1101
	  if (line >> c) 
946 1102
	    throw DataFormatError("Extra character on the end of line");
947 1103

	
948 1104
	  if (section == "nodes" && !nodes_done) {
949 1105
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
950 1106
	      readNodes();
951 1107
	      nodes_done = true;
952 1108
	    }
953 1109
	  } else if ((section == "arcs" || section == "edges") && 
954 1110
		     !arcs_done) {
955 1111
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
956 1112
	      readArcs();
957 1113
	      arcs_done = true;
958 1114
	    }
959 1115
	  } else if (section == "attributes" && !attributes_done) {
960 1116
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
961 1117
	      readAttributes();
962 1118
	      attributes_done = true;
963 1119
	    }
964 1120
	  } else {
965
	    readLine();
966
	    skipSection();
1121
	    if (extra_sections.find(section) != extra_sections.end()) {
1122
	      std::ostringstream msg;
1123
	      msg << "Multiple occurence of section " << section;
1124
	      throw DataFormatError(msg.str().c_str());
1125
	    }
1126
	    Sections::iterator it = _sections.find(section);
1127
	    if (it != _sections.end()) {
1128
	      extra_sections.insert(section);
1129
	      it->second->process(*_is, line_num);
1130
	      readLine();
1131
	    } else {
1132
	      readLine();
1133
	      skipSection();
1134
	    }
967 1135
	  }
968 1136
	} catch (DataFormatError& error) {
969 1137
	  error.line(line_num);
970 1138
	  throw;
971 1139
	}	
972 1140
      }
973 1141

	
974 1142
      if (!nodes_done) {
975 1143
	throw DataFormatError("Section @nodes not found");
976 1144
      }
977 1145

	
978 1146
      if (!arcs_done) {
979 1147
	throw DataFormatError("Section @arcs not found");
980 1148
      }
981 1149

	
982 1150
      if (!attributes_done && !_attributes.empty()) {
983 1151
	throw DataFormatError("Section @attributes not found");
984 1152
      }
985 1153

	
986 1154
    }
987 1155

	
988 1156
    /// @}
989 1157
    
990 1158
  };
991 1159

	
992 1160
  /// \relates DigraphReader
993 1161
  template <typename Digraph>
994 1162
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
995 1163
    return DigraphReader<Digraph>(is, digraph);
996 1164
  }
997 1165

	
998 1166
  /// \relates DigraphReader
999 1167
  template <typename Digraph>
1000 1168
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1001 1169
				       Digraph& digraph) {
1002 1170
    return DigraphReader<Digraph>(fn, digraph);
1003 1171
  }
1004 1172

	
1005 1173
  /// \relates DigraphReader
1006 1174
  template <typename Digraph>
1007 1175
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1008 1176
    return DigraphReader<Digraph>(fn, digraph);
1009 1177
  }
1010 1178
}
1011 1179

	
1012 1180
#endif
0 comments (0 inline)