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

	
19
///\ingroup demos
20
///\file
21
///\brief Demonstrating graph input and output
22
///
23
/// This simple demo program gives an example of how to read and write
24
/// a graph and additional maps (on the nodes or the edges) from/to a
25
/// stream. 
26
///
27
/// \include reader_writer_demo.cc
28

	
29
#include <iostream>
30
#include <lemon/smart_graph.h>
31
#include <lemon/lgf_reader.h>
32
#include <lemon/lgf_writer.h>
33
#include <lemon/random.h>
34

	
35

	
36
using namespace lemon;
37

	
38
int main(int argc, const char *argv[]) {
39
  const int n = argc > 1 ? std::atoi(argv[1]) : 20;
40
  const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * log(n));
41
  const int m = argc > 3 ? std::atoi(argv[3]) : 100;
42

	
43
  SmartDigraph digraph;
44

	
45
  std::stringstream ss;
46

	
47
  try {
48

	
49
    typedef SmartDigraph Digraph;
50
    typedef Digraph::Node Node;
51
    typedef Digraph::Arc Arc;
52
    typedef Digraph::ArcIt ArcIt;
53

	
54
    typedef Digraph::NodeMap<int> PotentialMap;
55
    typedef Digraph::ArcMap<int> CapacityMap;
56
    typedef Digraph::ArcMap<std::string> NameMap;
57

	
58
    Digraph digraph;
59
    PotentialMap potential(digraph);
60
    CapacityMap capacity(digraph);
61
    NameMap name(digraph);
62

	
63
    std::vector<Node> nodes;
64
    for (int i = 0; i < n; ++i) {
65
      Node node = digraph.addNode();
66
      potential[node] = rnd[m];
67
      nodes.push_back(node);
68
    }
69

	
70
    std::vector<Arc> arcs;
71
    for (int i = 0; i < e; ++i) {
72
      int s = rnd[n];
73
      int t = rnd[n];
74
      int c = rnd[m];
75
      Arc arc = digraph.addArc(nodes[s], nodes[t]);
76
      capacity[arc] = c;
77
      std::ostringstream os;
78
      os << "arc \t" << i << std::endl;
79
      name[arc] = os.str();
80
      arcs.push_back(arc);
81
    }
82

	
83

	
84
    DigraphWriter<Digraph>(ss, digraph).
85
      nodeMap("potential", potential).
86
      arcMap("capacity", capacity).
87
      arcMap("name", name).
88
      node("source", nodes[0]).
89
      node("target", nodes[1]).
90
      arc("bottleneck", arcs[e / 2]).
91
      attribute("creator", "lemon library").
92
      run();
93

	
94
  } catch (DataFormatError& error) {
95
    std::cerr << error.what() << std::endl;
96
  }
97

	
98
  try {
99

	
100
    typedef SmartDigraph Digraph;
101
    typedef Digraph::Node Node;
102
    typedef Digraph::Arc Arc;
103
    typedef Digraph::ArcIt ArcIt;
104

	
105
    typedef Digraph::NodeMap<int> LabelMap;
106
    typedef Digraph::NodeMap<int> PotentialMap;
107
    typedef Digraph::ArcMap<int> CapacityMap;
108
    typedef Digraph::ArcMap<std::string> NameMap;
109

	
110
    Digraph digraph;
111
    LabelMap label(digraph);
112
    PotentialMap potential(digraph);
113
    CapacityMap capacity(digraph);
114
    NameMap name(digraph);
115

	
116
    Node s, t;
117
    Arc a;
118
    
119
    std::string creator;
120

	
121
    for (int i = 0; i < n; ++i) {
122
      Node node = digraph.addNode();
123
      label[node] = i;
124
    }
125
    
126
    DigraphReader<Digraph>(ss, digraph).
127
      useNodes(label).
128
      nodeMap("potential", potential).
129
      arcMap("capacity", capacity).
130
      arcMap("name", name).
131
      node("source", s).
132
      node("target", t).
133
      arc("bottleneck", a).
134
      attribute("creator", creator).
135
      run();
136

	
137
    DigraphWriter<Digraph>(std::cout, digraph).
138
      nodeMap("potential", potential).
139
      arcMap("capacity", capacity).
140
      arcMap("name", name).
141
      node("source", s).
142
      node("target", t).
143
      arc("bottleneck", a).
144
      attribute("creator", creator).
145
      run();
146

	
147
  } catch (DataFormatError& error) {
148
    std::cerr << error.what() << std::endl;
149
  }
150

	
151

	
152
  return 0;
153
}
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
///\ingroup lemon_io
20
///\file
21
///\brief Lemon Graph Format reader.
22

	
23

	
24
#ifndef LEMON_LGF_READER_H
25
#define LEMON_LGF_READER_H
26

	
27
#include <iostream>
28
#include <fstream>
29
#include <sstream>
30

	
31
#include <set>
32
#include <map>
33

	
34
#include <lemon/assert.h>
35
#include <lemon/graph_utils.h>
36

	
37
#include <lemon/lgf_writer.h>
38

	
39
#include <lemon/concept_check.h>
40
#include <lemon/concepts/maps.h>
41

	
42
namespace lemon {
43

	
44
  namespace _reader_bits {
45

	
46
    template <typename Value>
47
    struct DefaultConverter {
48
      Value operator()(const std::string& str) {
49
	std::istringstream is(str);
50
	Value value;
51
	is >> value;
52

	
53
	char c;
54
	if (is >> std::ws >> c) {
55
	  throw DataFormatError("Remaining characters in token");
56
	}
57
	return value;
58
      }
59
    };
60

	
61
    template <>
62
    struct DefaultConverter<std::string> {
63
      std::string operator()(const std::string& str) {
64
	return str;
65
      }
66
    };
67

	
68
    template <typename _Item>    
69
    class MapStorageBase {
70
    public:
71
      typedef _Item Item;
72

	
73
    public:
74
      MapStorageBase() {}
75
      virtual ~MapStorageBase() {}
76

	
77
      virtual void set(const Item& item, const std::string& value) = 0;
78

	
79
    };
80

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
272
    std::istream& readIdentifier(std::istream& is, std::string& str) {
273
      std::ostringstream os;
274

	
275
      char c;
276
      is >> std::ws;
277
      
278
      if (!is.get(c))
279
	return is;
280

	
281
      if (!isIdentifierFirstChar(c))
282
	throw DataFormatError("Wrong char in identifier");
283
      
284
      os << c;
285
      
286
      while (is.get(c) && !isWhiteSpace(c)) {
287
	if (!isIdentifierChar(c)) 
288
	  throw DataFormatError("Wrong char in identifier");	  
289
	os << c;
290
      }
291
      if (!is) is.clear();
292
     
293
      str = os.str();
294
      return is;
295
    }
296
    
297
  }
298
  
299
  /// \e
300
  template <typename _Digraph>
301
  class DigraphReader {
302
  public:
303

	
304
    typedef _Digraph Digraph;
305
    GRAPH_TYPEDEFS(typename Digraph);
306
    
307
  private:
308

	
309

	
310
    std::istream* _is;
311
    bool local_is;
312

	
313
    Digraph& _digraph;
314

	
315
    std::string _nodes_caption;
316
    std::string _arcs_caption;
317
    std::string _attributes_caption;
318

	
319
    typedef std::map<std::string, Node> NodeIndex;
320
    NodeIndex _node_index;
321
    typedef std::map<std::string, Arc> ArcIndex;
322
    ArcIndex _arc_index;
323
    
324
    typedef std::vector<std::pair<std::string, 
325
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
326
    NodeMaps _node_maps; 
327

	
328
    typedef std::vector<std::pair<std::string,
329
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
330
    ArcMaps _arc_maps;
331

	
332
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
333
      Attributes;
334
    Attributes _attributes;
335

	
336
    bool _use_nodes;
337
    bool _use_arcs;
338

	
339
    int line_num;
340
    std::istringstream line;
341

	
342
  public:
343

	
344
    /// \e
345
    DigraphReader(std::istream& is, Digraph& digraph) 
346
      : _is(&is), local_is(false), _digraph(digraph),
347
	_use_nodes(false), _use_arcs(false) {}
348

	
349
    /// \e
350
    DigraphReader(const std::string& fn, Digraph& digraph) 
351
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
352
    	_use_nodes(false), _use_arcs(false) {}
353

	
354

	
355
    /// \e
356
    DigraphReader(const char* fn, Digraph& digraph) 
357
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
358
    	_use_nodes(false), _use_arcs(false) {}
359

	
360
    /// \e
361
    DigraphReader(DigraphReader& other) 
362
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
363
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
364

	
365
      other.is = 0;
366
      other.local_is = false;
367
      
368
      _node_index.swap(other._node_index);
369
      _arc_index.swap(other._arc_index);
370

	
371
      _node_maps.swap(other._node_maps);
372
      _arc_maps.swap(other._arc_maps);
373
      _attributes.swap(other._attributes);
374

	
375
      _nodes_caption = other._nodes_caption;
376
      _arcs_caption = other._arcs_caption;
377
      _attributes_caption = other._attributes_caption;
378
    }
379

	
380
    /// \e
381
    ~DigraphReader() {
382
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
383
	   it != _node_maps.end(); ++it) {
384
	delete it->second;
385
      }
386

	
387
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
388
	   it != _arc_maps.end(); ++it) {
389
	delete it->second;
390
      }
391

	
392
      for (typename Attributes::iterator it = _attributes.begin(); 
393
	   it != _attributes.end(); ++it) {
394
	delete it->second;
395
      }
396

	
397
      if (local_is) {
398
	delete _is;
399
      }
400

	
401
    }
402

	
403
  private:
404
    
405
    DigraphReader& operator=(const DigraphReader&);
406

	
407
  public:
408

	
409
    /// \e
410
    template <typename Map>
411
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
412
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
413
      _reader_bits::MapStorageBase<Node>* storage = 
414
	new _reader_bits::MapStorage<Node, Map>(map);
415
      _node_maps.push_back(std::make_pair(caption, storage));
416
      return *this;
417
    }
418

	
419
    /// \e
420
    template <typename Map, typename Converter>
421
    DigraphReader& nodeMap(const std::string& caption, Map& map, 
422
			   const Converter& converter = Converter()) {
423
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
424
      _reader_bits::MapStorageBase<Node>* storage = 
425
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
426
      _node_maps.push_back(std::make_pair(caption, storage));
427
      return *this;
428
    }
429

	
430
    /// \e
431
    template <typename Map>
432
    DigraphReader& arcMap(const std::string& caption, Map& map) {
433
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
434
      _reader_bits::MapStorageBase<Arc>* storage = 
435
	new _reader_bits::MapStorage<Arc, Map>(map);
436
      _arc_maps.push_back(std::make_pair(caption, storage));
437
      return *this;
438
    }
439

	
440
    /// \e
441
    template <typename Map, typename Converter>
442
    DigraphReader& arcMap(const std::string& caption, Map& map, 
443
			  const Converter& converter = Converter()) {
444
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
445
      _reader_bits::MapStorageBase<Arc>* storage = 
446
	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
447
      _arc_maps.push_back(std::make_pair(caption, storage));
448
      return *this;
449
    }
450

	
451
    /// \e
452
    template <typename Value>
453
    DigraphReader& attribute(const std::string& caption, Value& value) {
454
      _reader_bits::ValueStorageBase* storage = 
455
	new _reader_bits::ValueStorage<Value>(value);
456
      _attributes.insert(std::make_pair(caption, storage));
457
      return *this;
458
    }
459

	
460
    /// \e
461
    template <typename Value, typename Converter>
462
    DigraphReader& attribute(const std::string& caption, Value& value, 
463
			     const Converter& converter = Converter()) {
464
      _reader_bits::ValueStorageBase* storage = 
465
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
466
      _attributes.insert(std::make_pair(caption, storage));
467
      return *this;
468
    }
469

	
470
    /// \e
471
    DigraphReader& node(const std::string& caption, Node& node) {
472
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
473
      Converter converter(_node_index);
474
      _reader_bits::ValueStorageBase* storage = 
475
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
476
      _attributes.insert(std::make_pair(caption, storage));
477
      return *this;
478
    }
479

	
480
    /// \e
481
    DigraphReader& arc(const std::string& caption, Arc& arc) {
482
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
483
      Converter converter(_arc_index);
484
      _reader_bits::ValueStorageBase* storage = 
485
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
486
      _attributes.insert(std::make_pair(caption, storage));
487
      return *this;
488
    }
489

	
490
    /// \e
491
    DigraphReader& nodes(const std::string& caption) {
492
      _nodes_caption = caption;
493
      return *this;
494
    }
495

	
496
    /// \e
497
    DigraphReader& arcs(const std::string& caption) {
498
      _arcs_caption = caption;
499
      return *this;
500
    }
501

	
502
    /// \e
503
    DigraphReader& attributes(const std::string& caption) {
504
      _attributes_caption = caption;
505
      return *this;
506
    }
507

	
508
    /// \e
509
    template <typename Map>
510
    DigraphReader& useNodes(const Map& map) {
511
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
512
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
513
      _use_nodes = true;
514
      _writer_bits::DefaultConverter<typename Map::Value> converter;
515
      for (NodeIt n(_digraph); n != INVALID; ++n) {
516
	_node_index.insert(std::make_pair(converter(map[n]), n));
517
      }
518
      return *this;
519
    }
520

	
521
    /// \e
522
    template <typename Map, typename Converter>
523
    DigraphReader& useNodes(const Map& map, 
524
			    const Converter& converter = Converter()) {
525
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
526
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
527
      _use_nodes = true;
528
      for (NodeIt n(_digraph); n != INVALID; ++n) {
529
	_node_index.insert(std::make_pair(converter(map[n]), n));
530
      }
531
      return *this;
532
    }
533

	
534
    /// \e
535
    template <typename Map>
536
    DigraphReader& useArcs(const Map& map) {
537
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
538
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
539
      _use_arcs = true;
540
      _writer_bits::DefaultConverter<typename Map::Value> converter;
541
      for (ArcIt a(_digraph); a != INVALID; ++a) {
542
	_arc_index.insert(std::make_pair(converter(map[a]), a));
543
      }
544
      return *this;
545
    }
546

	
547
    /// \e
548
    template <typename Map, typename Converter>
549
    DigraphReader& useArcs(const Map& map, 
550
			    const Converter& converter = Converter()) {
551
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
552
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); 
553
      _use_arcs = true;
554
      for (ArcIt a(_digraph); a != INVALID; ++a) {
555
	_arc_index.insert(std::make_pair(converter(map[a]), a));
556
      }
557
      return *this;
558
    }
559

	
560
  private:
561

	
562
    bool readLine() {
563
      std::string str;
564
      while(++line_num, std::getline(*_is, str)) {
565
	line.clear(); line.str(str);
566
	char c;
567
	if (line >> std::ws >> c && c != '#') {
568
	  line.putback(c);
569
	  return true;
570
	}
571
      }
572
      return false;
573
    }
574

	
575
    bool readSuccess() {
576
      return static_cast<bool>(*_is);
577
    }
578
    
579
    void skipSection() {
580
      char c;
581
      while (readSuccess() && line >> c && c != '@') {
582
	readLine();
583
      }
584
      line.putback(c);
585
    }
586

	
587
    void readNodes() {
588

	
589
      std::vector<int> map_index(_node_maps.size());
590
      int map_num, label_index;
591

	
592
      if (!readLine()) 
593
	throw DataFormatError("Cannot find map captions");
594
      
595
      {
596
	std::map<std::string, int> maps;
597
	
598
	std::string map;
599
	int index = 0;
600
	while (_reader_bits::readIdentifier(line, map)) {
601
	  if (maps.find(map) != maps.end()) {
602
	    std::ostringstream msg;
603
	    msg << "Multiple occurence of node map: " << map;
604
	    throw DataFormatError(msg.str().c_str());
605
	  }
606
	  maps.insert(std::make_pair(map, index));
607
	  ++index;
608
	}
609
	
610
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
611
	  std::map<std::string, int>::iterator jt = 
612
	    maps.find(_node_maps[i].first);
613
	  if (jt == maps.end()) {
614
	    std::ostringstream msg;
615
	    msg << "Map not found in file: " << _node_maps[i].first;
616
	    throw DataFormatError(msg.str().c_str());
617
	  }
618
	  map_index[i] = jt->second;
619
	}
620

	
621
	{
622
	  std::map<std::string, int>::iterator jt = maps.find("label");
623
	  if (jt == maps.end())
624
	    throw DataFormatError("Label map not found in file");
625
	  label_index = jt->second;
626
	}
627
	map_num = maps.size();
628
      }
629

	
630
      char c;
631
      while (readLine() && line >> c && c != '@') {
632
	line.putback(c);
633

	
634
	std::vector<std::string> tokens(map_num);
635
	for (int i = 0; i < map_num; ++i) {
636
	  if (!_reader_bits::readToken(line, tokens[i])) {
637
	    std::ostringstream msg;
638
	    msg << "Column not found (" << i + 1 << ")";
639
	    throw DataFormatError(msg.str().c_str());
640
	  }
641
	}
642
	if (line >> std::ws >> c)
643
	  throw DataFormatError("Extra character on the end of line");
644
	
645
	Node n;
646
	if (!_use_nodes) {
647
	  n = _digraph.addNode();
648
	  _node_index.insert(std::make_pair(tokens[label_index], n));
649
	} else {
650
	  typename std::map<std::string, Node>::iterator it =
651
	    _node_index.find(tokens[label_index]);
652
	  if (it == _node_index.end()) {
653
	    std::ostringstream msg;
654
	    msg << "Node with label not found: " << tokens[label_index];
655
	    throw DataFormatError(msg.str().c_str());	    
656
	  }
657
	  n = it->second;
658
	}
659

	
660
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
661
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
662
	}
663

	
664
      }
665
      if (readSuccess()) {
666
	line.putback(c);
667
      }
668
    }
669

	
670
    void readArcs() {
671

	
672
      std::vector<int> map_index(_arc_maps.size());
673
      int map_num, label_index;
674

	
675
      if (!readLine()) 
676
	throw DataFormatError("Cannot find map captions");
677
      
678
      {
679
	std::map<std::string, int> maps;
680
	
681
	std::string map;
682
	int index = 0;
683
	while (_reader_bits::readIdentifier(line, map)) {
684
	  if (maps.find(map) != maps.end()) {
685
	    std::ostringstream msg;
686
	    msg << "Multiple occurence of arc map: " << map;
687
	    throw DataFormatError(msg.str().c_str());
688
	  }
689
	  maps.insert(std::make_pair(map, index));
690
	  ++index;
691
	}
692
	
693
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
694
	  std::map<std::string, int>::iterator jt = 
695
	    maps.find(_arc_maps[i].first);
696
	  if (jt == maps.end()) {
697
	    std::ostringstream msg;
698
	    msg << "Map not found in file: " << _arc_maps[i].first;
699
	    throw DataFormatError(msg.str().c_str());
700
	  }
701
	  map_index[i] = jt->second;
702
	}
703

	
704
	{
705
	  std::map<std::string, int>::iterator jt = maps.find("label");
706
	  if (jt == maps.end())
707
	    throw DataFormatError("Label map not found in file");
708
	  label_index = jt->second;
709
	}
710
	map_num = maps.size();
711
      }
712

	
713
      char c;
714
      while (readLine() && line >> c && c != '@') {
715
	line.putback(c);
716

	
717
	std::string source_token;
718
	std::string target_token;
719

	
720
	if (!_reader_bits::readToken(line, source_token))
721
	  throw DataFormatError("Source not found");
722

	
723
	if (!_reader_bits::readToken(line, target_token))
724
	  throw DataFormatError("Source not found");
725
	
726
	std::vector<std::string> tokens(map_num);
727
	for (int i = 0; i < map_num; ++i) {
728
	  if (!_reader_bits::readToken(line, tokens[i])) {
729
	    std::ostringstream msg;
730
	    msg << "Column not found (" << i + 1 << ")";
731
	    throw DataFormatError(msg.str().c_str());
732
	  }
733
	}
734
	if (line >> std::ws >> c)
735
	  throw DataFormatError("Extra character on the end of line");
736
	
737
	Arc a;
738
	if (!_use_arcs) {
739

	
740
          typename NodeIndex::iterator it;
741
 
742
          it = _node_index.find(source_token);
743
          if (it == _node_index.end()) {
744
            std::ostringstream msg;
745
            msg << "Item not found: " << source_token;
746
            throw DataFormatError(msg.str().c_str());
747
          }
748
          Node source = it->second;
749

	
750
          it = _node_index.find(target_token);
751
          if (it == _node_index.end()) {       
752
            std::ostringstream msg;            
753
            msg << "Item not found: " << target_token;
754
            throw DataFormatError(msg.str().c_str());
755
          }                                          
756
          Node target = it->second;                            
757

	
758
	  a = _digraph.addArc(source, target);
759
	  _arc_index.insert(std::make_pair(tokens[label_index], a));
760
	} else {
761
	  typename std::map<std::string, Arc>::iterator it =
762
	    _arc_index.find(tokens[label_index]);
763
	  if (it == _arc_index.end()) {
764
	    std::ostringstream msg;
765
	    msg << "Arc with label not found: " << tokens[label_index];
766
	    throw DataFormatError(msg.str().c_str());	    
767
	  }
768
	  a = it->second;
769
	}
770

	
771
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
772
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
773
	}
774

	
775
      }
776
      if (readSuccess()) {
777
	line.putback(c);
778
      }
779
    }
780

	
781
    void readAttributes() {
782

	
783
      std::set<std::string> read_attr;
784

	
785
      char c;
786
      while (readLine() && line >> c && c != '@') {
787
	line.putback(c);
788
	
789
	std::string attr, token;
790
	if (!_reader_bits::readIdentifier(line, attr))
791
	  throw DataFormatError("Attribute name not found");
792
	if (!_reader_bits::readToken(line, token))
793
	  throw DataFormatError("Attribute value not found");
794
	if (line >> c)
795
	  throw DataFormatError("Extra character on the end of line");	  
796

	
797
	{
798
	  std::set<std::string>::iterator it = read_attr.find(attr);
799
	  if (it != read_attr.end()) {
800
	    std::ostringstream msg;
801
	    msg << "Multiple occurence of attribute " << attr;
802
	    throw DataFormatError(msg.str().c_str());
803
	  }
804
	  read_attr.insert(attr);
805
	}
806
	
807
	{
808
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
809
	  while (it != _attributes.end() && it->first == attr) {
810
	    it->second->set(token);
811
	    ++it;
812
	  }
813
	}
814

	
815
      }
816
      if (readSuccess()) {
817
	line.putback(c);
818
      }
819
      for (typename Attributes::iterator it = _attributes.begin();
820
	   it != _attributes.end(); ++it) {
821
	if (read_attr.find(it->first) == read_attr.end()) {
822
	  std::ostringstream msg;
823
	  msg << "Attribute not found in file: " << it->first;
824
	  throw DataFormatError(msg.str().c_str());
825
	}	
826
      }
827
    }
828

	
829
  public:
830
    
831
    /// \e
832
    void run() {
833
      
834
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
835
      
836
      bool nodes_done = false;
837
      bool arcs_done = false;
838
      bool attributes_done = false;
839

	
840
      line_num = 0;      
841
      readLine();
842

	
843
      while (readSuccess()) {
844
	skipSection();
845
	try {
846
	  char c;
847
	  std::string section, caption;
848
	  line >> c;
849
	  _reader_bits::readIdentifier(line, section);
850
	  _reader_bits::readIdentifier(line, caption);
851

	
852
	  if (line >> c) 
853
	    throw DataFormatError("Extra character on the end of line");
854

	
855
	  if (section == "nodes" && !nodes_done) {
856
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
857
	      readNodes();
858
	      nodes_done = true;
859
	    }
860
	  } else if ((section == "arcs" || section == "edges") && 
861
		     !arcs_done) {
862
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
863
	      readArcs();
864
	      arcs_done = true;
865
	    }
866
	  } else if (section == "attributes" && !attributes_done) {
867
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
868
	      readAttributes();
869
	      attributes_done = true;
870
	    }
871
	  } else {
872
	    readLine();
873
	    skipSection();
874
	  }
875
	} catch (DataFormatError& error) {
876
	  error.line(line_num);
877
	  throw;
878
	}	
879
      }
880

	
881
      if (!nodes_done) {
882
	throw DataFormatError("Section @nodes not found");
883
      }
884

	
885
      if (!arcs_done) {
886
	throw DataFormatError("Section @arcs not found");
887
      }
888

	
889
      if (!attributes_done && !_attributes.empty()) {
890
	throw DataFormatError("Section @attributes not found");
891
      }
892

	
893
    }
894
    
895
  };
896

	
897
  template <typename Digraph>
898
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
899
    return DigraphReader<Digraph>(is, digraph);
900
  }
901

	
902
  template <typename Digraph>
903
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
904
				       Digraph& digraph) {
905
    return DigraphReader<Digraph>(fn, digraph);
906
  }
907

	
908
  template <typename Digraph>
909
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
910
    return DigraphReader<Digraph>(fn, digraph);
911
  }
912
}
913

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

	
19
///\ingroup lemon_io
20
///\file
21
///\brief Lemon Graph Format writer.
22

	
23

	
24
#ifndef LEMON_LGF_WRITER_H
25
#define LEMON_LGF_WRITER_H
26

	
27
#include <iostream>
28
#include <fstream>
29
#include <sstream>
30

	
31
#include <algorithm>
32

	
33
#include <vector>
34
#include <functional>
35

	
36
#include <lemon/assert.h>
37
#include <lemon/graph_utils.h>
38

	
39
namespace lemon {
40

	
41
  namespace _writer_bits {
42

	
43
    template <typename Value>
44
    struct DefaultConverter {
45
      std::string operator()(const Value& value) {
46
	std::ostringstream os;
47
	os << value;
48
	return os.str();
49
      }
50
    };
51

	
52
    template <typename T>
53
    bool operator<(const T&, const T&) {
54
      throw DataFormatError("Label map is not comparable");
55
    }
56

	
57
    template <typename _Map>
58
    class MapLess {
59
    public:
60
      typedef _Map Map;
61
      typedef typename Map::Key Item;
62

	
63
    private:
64
      const Map& _map;
65
      
66
    public:
67
      MapLess(const Map& map) : _map(map) {}
68

	
69
      bool operator()(const Item& left, const Item& right) {
70
	return _map[left] < _map[right];
71
      }
72
    };
73

	
74
    template <typename _Item>    
75
    class MapStorageBase {
76
    public:
77
      typedef _Item Item;
78

	
79
    public:
80
      MapStorageBase() {}
81
      virtual ~MapStorageBase() {}
82

	
83
      virtual std::string get(const Item& item) = 0;
84
      virtual void sort(std::vector<Item>&) = 0;
85
    };
86

	
87
    template <typename _Item, typename _Map, 
88
	      typename _Converter = DefaultConverter<typename _Map::Value> >
89
    class MapStorage : public MapStorageBase<_Item> {
90
    public:
91
      typedef _Map Map;
92
      typedef _Converter Converter;
93
      typedef _Item Item;
94
      
95
    private:
96
      const Map& _map;
97
      Converter _converter;
98

	
99
    public:
100
      MapStorage(const Map& map, const Converter& converter = Converter()) 
101
	: _map(map), _converter(converter) {}
102
      virtual ~MapStorage() {}
103

	
104
      virtual std::string get(const Item& item) {
105
	return _converter(_map[item]);
106
      }
107
      virtual void sort(std::vector<Item>& items) {
108
	MapLess<Map> less(_map);
109
	std::sort(items.begin(), items.end(), less);
110
      }
111
    };
112

	
113
    class ValueStorageBase {
114
    public:
115
      ValueStorageBase() {}
116
      virtual ~ValueStorageBase() {}
117

	
118
      virtual std::string get() = 0;      
119
    };
120

	
121
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
122
    class ValueStorage : public ValueStorageBase {
123
    public:
124
      typedef _Value Value;
125
      typedef _Converter Converter;
126

	
127
    private:
128
      const Value& _value;
129
      Converter _converter;
130

	
131
    public:
132
      ValueStorage(const Value& value, const Converter& converter = Converter())
133
 	: _value(value), _converter(converter) {}
134

	
135
      virtual std::string get() {
136
	return _converter(_value);
137
      }
138
    };
139

	
140
    template <typename Value>
141
    struct MapLookUpConverter {
142
      const std::map<Value, std::string>& _map;
143
      
144
      MapLookUpConverter(const std::map<Value, std::string>& map) 
145
	: _map(map) {}
146
      
147
      std::string operator()(const Value& str) {
148
	typename std::map<Value, std::string>::const_iterator it = 
149
	  _map.find(str);
150
	if (it == _map.end()) {
151
	  throw DataFormatError("Item not found");
152
	}
153
	return it->second;
154
      }
155
    };
156

	
157
    bool isWhiteSpace(char c) {
158
      return c == ' ' || c == '\t' || c == '\v' || 
159
        c == '\n' || c == '\r' || c == '\f'; 
160
    }
161

	
162
    bool isEscaped(char c) {
163
      return c == '\\' || c == '\"' || c == '\'' || 
164
	c == '\a' || c == '\b';
165
    }
166

	
167
    static void writeEscape(std::ostream& os, char c) {
168
      switch (c) {
169
      case '\\':
170
	os << "\\\\";
171
	return;
172
      case '\"':
173
	os << "\\\"";
174
	return;
175
      case '\a':
176
	os << "\\a";
177
	return;
178
      case '\b':
179
	os << "\\b";
180
	return;
181
      case '\f':
182
	os << "\\f";
183
	return;
184
      case '\r':
185
	os << "\\r";
186
	return;
187
      case '\n':
188
	os << "\\n";
189
	return;
190
      case '\t':
191
	os << "\\t";
192
	return;
193
      case '\v':
194
	os << "\\v";
195
	return;
196
      default:
197
	if (c < 0x20) {
198
	  os << '\\' << std::oct << static_cast<int>(c);
199
	} else {
200
	  os << c;
201
	}
202
	return;
203
      }     
204
    }
205

	
206
    bool requireEscape(const std::string& str) {
207
      std::istringstream is(str);
208
      char c;
209
      while (is.get(c)) {
210
	if (isWhiteSpace(c) || isEscaped(c)) {
211
	  return true;
212
	}
213
      }
214
      return false;
215
    }
216
    
217
    std::ostream& writeToken(std::ostream& os, const std::string& str) {
218

	
219
      if (requireEscape(str)) {
220
	os << '\"';
221
	for (std::string::const_iterator it = str.begin(); 
222
	     it != str.end(); ++it) {
223
	  writeEscape(os, *it);
224
	}	
225
	os << '\"';
226
      } else {
227
	os << str;
228
      }
229
      return os;
230
    }
231

	
232
  }
233
  
234
  /// \e
235
  template <typename _Digraph>
236
  class DigraphWriter {
237
  public:
238

	
239
    typedef _Digraph Digraph;
240
    GRAPH_TYPEDEFS(typename Digraph);
241
    
242
  private:
243

	
244

	
245
    std::ostream* _os;
246
    bool local_os;
247

	
248
    Digraph& _digraph;
249

	
250
    std::string _nodes_caption;
251
    std::string _arcs_caption;
252
    std::string _attributes_caption;
253
    
254
    typedef std::map<Node, std::string> NodeIndex;
255
    NodeIndex _node_index;
256
    typedef std::map<Arc, std::string> ArcIndex;
257
    ArcIndex _arc_index;
258

	
259
    typedef std::vector<std::pair<std::string, 
260
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
261
    NodeMaps _node_maps; 
262

	
263
    typedef std::vector<std::pair<std::string, 
264
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
265
    ArcMaps _arc_maps;
266

	
267
    typedef std::vector<std::pair<std::string, 
268
      _writer_bits::ValueStorageBase*> > Attributes;
269
    Attributes _attributes;
270

	
271
    bool _skip_nodes;
272
    bool _skip_arcs;
273

	
274
  public:
275

	
276
    /// \e
277
    DigraphWriter(std::ostream& is, Digraph& digraph) 
278
      : _os(&is), local_os(false), _digraph(digraph),
279
	_skip_nodes(false), _skip_arcs(false) {}
280

	
281
    /// \e
282
    DigraphWriter(const std::string& fn, Digraph& digraph) 
283
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
284
	_skip_nodes(false), _skip_arcs(false) {}
285

	
286
    /// \e
287
    DigraphWriter(const char* fn, Digraph& digraph) 
288
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
289
	_skip_nodes(false), _skip_arcs(false) {}
290

	
291
    DigraphWriter(DigraphWriter& other) 
292
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
293
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
294

	
295
      other.is = 0;
296
      other.local_os = false;
297

	
298
      _node_index.swap(other._node_index);
299
      _arc_index.swap(other._arc_index);
300

	
301
      _node_maps.swap(other._node_maps);
302
      _arc_maps.swap(other._arc_maps);
303
      _attributes.swap(other._attributes);
304

	
305
      _nodes_caption = other._nodes_caption;
306
      _arcs_caption = other._arcs_caption;
307
      _attributes_caption = other._attributes_caption;
308
    }
309

	
310
    /// \e
311
    ~DigraphWriter() {
312
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
313
	   it != _node_maps.end(); ++it) {
314
	delete it->second;
315
      }
316

	
317
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
318
	   it != _arc_maps.end(); ++it) {
319
	delete it->second;
320
      }
321

	
322
      for (typename Attributes::iterator it = _attributes.begin(); 
323
	   it != _attributes.end(); ++it) {
324
	delete it->second;
325
      }
326

	
327
      if (local_os) {
328
	delete _os;
329
      }
330
    }
331

	
332
  private:
333
    
334
    DigraphWriter& operator=(const DigraphWriter&);
335

	
336
  public:
337

	
338
    /// \e
339
    template <typename Map>
340
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
341
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
342
      _writer_bits::MapStorageBase<Node>* storage = 
343
	new _writer_bits::MapStorage<Node, Map>(map);
344
      _node_maps.push_back(std::make_pair(caption, storage));
345
      return *this;
346
    }
347

	
348
    /// \e
349
    template <typename Map, typename Converter>
350
    DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
351
			   const Converter& converter = Converter()) {
352
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
353
      _writer_bits::MapStorageBase<Node>* storage = 
354
	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
355
      _node_maps.push_back(std::make_pair(caption, storage));
356
      return *this;
357
    }
358

	
359
    /// \e
360
    template <typename Map>
361
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
362
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
363
      _writer_bits::MapStorageBase<Arc>* storage = 
364
	new _writer_bits::MapStorage<Arc, Map>(map);
365
      _arc_maps.push_back(std::make_pair(caption, storage));
366
      return *this;
367
    }
368

	
369
    /// \e
370
    template <typename Map, typename Converter>
371
    DigraphWriter& arcMap(const std::string& caption, const Map& map, 
372
			  const Converter& converter = Converter()) {
373
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
374
      _writer_bits::MapStorageBase<Arc>* storage = 
375
	new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
376
      _arc_maps.push_back(std::make_pair(caption, storage));
377
      return *this;
378
    }
379

	
380
    /// \e
381
    template <typename Value>
382
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
383
      _writer_bits::ValueStorageBase* storage = 
384
	new _writer_bits::ValueStorage<Value>(value);
385
      _attributes.push_back(std::make_pair(caption, storage));
386
      return *this;
387
    }
388

	
389
    /// \e
390
    template <typename Value, typename Converter>
391
    DigraphWriter& attribute(const std::string& caption, const Value& value, 
392
			     const Converter& converter = Converter()) {
393
      _writer_bits::ValueStorageBase* storage = 
394
	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
395
      _attributes.push_back(std::make_pair(caption, storage));
396
      return *this;
397
    }
398

	
399
    /// \e
400
    DigraphWriter& node(const std::string& caption, const Node& node) {
401
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
402
      Converter converter(_node_index);
403
      _writer_bits::ValueStorageBase* storage = 
404
	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
405
      _attributes.push_back(std::make_pair(caption, storage));
406
      return *this;
407
    }
408

	
409
    /// \e
410
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
411
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
412
      Converter converter(_arc_index);
413
      _writer_bits::ValueStorageBase* storage = 
414
	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
415
      _attributes.push_back(std::make_pair(caption, storage));
416
      return *this;
417
    }
418

	
419
    /// \e
420
    DigraphWriter& nodes(const std::string& caption) {
421
      _nodes_caption = caption;
422
      return *this;
423
    }
424

	
425
    /// \e
426
    DigraphWriter& arcs(const std::string& caption) {
427
      _arcs_caption = caption;
428
      return *this;
429
    }
430

	
431
    /// \e
432
    DigraphWriter& attributes(const std::string& caption) {
433
      _attributes_caption = caption;
434
      return *this;
435
    }
436

	
437
    DigraphWriter& skipNodes() {
438
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
439
      return *this;
440
    }
441

	
442
    DigraphWriter& skipArcs() {
443
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
444
      return *this;
445
    }
446

	
447
  private:
448

	
449
    void writeNodes() {
450
      _writer_bits::MapStorageBase<Node>* label = 0;
451
      for (typename NodeMaps::iterator it = _node_maps.begin();
452
	   it != _node_maps.end(); ++it) {
453
        if (it->first == "label") {
454
	  label = it->second;
455
	  break;
456
	}
457
      }
458

	
459
      *_os << "@nodes";
460
      if (!_nodes_caption.empty()) {
461
	*_os << ' ' << _nodes_caption;
462
      }
463
      *_os << std::endl;
464

	
465
      if (label == 0) {
466
	*_os << "label" << '\t';
467
      }
468
      for (typename NodeMaps::iterator it = _node_maps.begin();
469
	   it != _node_maps.end(); ++it) {
470
	*_os << it->first << '\t';
471
      }
472
      *_os << std::endl;
473

	
474
      std::vector<Node> nodes;
475
      for (NodeIt n(_digraph); n != INVALID; ++n) {
476
	nodes.push_back(n);
477
      }
478
      
479
      if (label == 0) {
480
	IdMap<Digraph, Node> id_map(_digraph);
481
	_writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
482
	std::sort(nodes.begin(), nodes.end(), id_less);
483
      } else {
484
	label->sort(nodes);
485
      }
486

	
487
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
488
	Node n = nodes[i];
489
	if (label == 0) {
490
	  std::ostringstream os;
491
	  os << _digraph.id(n);
492
	  _writer_bits::writeToken(*_os, os.str());
493
	  *_os << '\t';
494
	  _node_index.insert(std::make_pair(n, os.str()));
495
	}
496
	for (typename NodeMaps::iterator it = _node_maps.begin();
497
	     it != _node_maps.end(); ++it) {
498
	  std::string value = it->second->get(n);
499
	  _writer_bits::writeToken(*_os, value);
500
	  if (it->first == "label") {
501
	    _node_index.insert(std::make_pair(n, value));
502
	  }
503
	  *_os << '\t';
504
	}
505
	*_os << std::endl;
506
      }
507
    }
508

	
509
    void writeArcs() {
510
      _writer_bits::MapStorageBase<Arc>* label = 0;
511
      for (typename ArcMaps::iterator it = _arc_maps.begin();
512
	   it != _arc_maps.end(); ++it) {
513
        if (it->first == "label") {
514
	  label = it->second;
515
	  break;
516
	}
517
      }
518

	
519
      *_os << "@arcs";
520
      if (!_arcs_caption.empty()) {
521
	*_os << ' ' << _arcs_caption;
522
      }
523
      *_os << std::endl;
524

	
525
      *_os << '\t' << '\t';
526
      if (label == 0) {
527
	*_os << "label" << '\t';
528
      }
529
      for (typename ArcMaps::iterator it = _arc_maps.begin();
530
	   it != _arc_maps.end(); ++it) {
531
	*_os << it->first << '\t';
532
      }
533
      *_os << std::endl;
534

	
535
      std::vector<Arc> arcs;
536
      for (ArcIt n(_digraph); n != INVALID; ++n) {
537
	arcs.push_back(n);
538
      }
539
      
540
      if (label == 0) {
541
	IdMap<Digraph, Arc> id_map(_digraph);
542
	_writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
543
	std::sort(arcs.begin(), arcs.end(), id_less);
544
      } else {
545
	label->sort(arcs);
546
      }
547

	
548
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
549
	Arc a = arcs[i];
550
	_writer_bits::writeToken(*_os, _node_index.
551
				 find(_digraph.source(a))->second);
552
	*_os << '\t';
553
	_writer_bits::writeToken(*_os, _node_index.
554
				 find(_digraph.target(a))->second);
555
	*_os << '\t';
556
	if (label == 0) {
557
	  std::ostringstream os;
558
	  os << _digraph.id(a);
559
	  _writer_bits::writeToken(*_os, os.str());
560
	  *_os << '\t';
561
	  _arc_index.insert(std::make_pair(a, os.str()));
562
	}
563
	for (typename ArcMaps::iterator it = _arc_maps.begin();
564
	     it != _arc_maps.end(); ++it) {
565
	  std::string value = it->second->get(a);
566
	  _writer_bits::writeToken(*_os, value);
567
	  if (it->first == "label") {
568
	    _arc_index.insert(std::make_pair(a, value));
569
	  }
570
	  *_os << '\t';
571
	}
572
	*_os << std::endl;
573
      }
574
    }
575

	
576
    void writeAttributes() {
577
      if (_attributes.empty()) return;
578
      *_os << "@attributes";
579
      if (!_attributes_caption.empty()) {
580
	*_os << ' ' << _attributes_caption;
581
      }
582
      *_os << std::endl;
583
      for (typename Attributes::iterator it = _attributes.begin();
584
	   it != _attributes.end(); ++it) {
585
	*_os << it->first << ' ';
586
	_writer_bits::writeToken(*_os, it->second->get());
587
	*_os << std::endl;
588
      }
589
    }
590
    
591
  public:
592
    
593
    /// \e
594
    void run() {
595
      if (!_skip_nodes) {
596
	writeNodes();
597
      }
598
      if (!_skip_arcs) {      
599
	writeArcs();
600
      }
601
      writeAttributes();
602
    }
603

	
604
    /// \e
605
    std::ostream& stream() {
606
      return *_os;
607
    }
608
  };
609

	
610
  template <typename Digraph>
611
  DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
612
    return DigraphWriter<Digraph>(is, digraph);
613
  }
614

	
615
  template <typename Digraph>
616
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
617
				       Digraph& digraph) {
618
    return DigraphWriter<Digraph>(fn, digraph);
619
  }
620

	
621
  template <typename Digraph>
622
  DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
623
    return DigraphWriter<Digraph>(fn, digraph);
624
  }
625
}
626

	
627
#endif
Ignore white space 6 line context
... ...
@@ -6,3 +6,4 @@
6 6
noinst_PROGRAMS += \
7
        demo/arg_parser_demo
7
        demo/arg_parser_demo \
8
	demo/lgf_demo
8 9

	
... ...
@@ -11,2 +12,3 @@
11 12
demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
13
demo_lgf_demo_SOURCES = demo/lgf_demo.cc
12 14

	
Ignore white space 6 line context
... ...
@@ -29,2 +29,3 @@
29 29
	lemon/kruskal.h \
30
	lemon/lgf_reader.h \
30 31
	lemon/list_graph.h \
0 comments (0 inline)