gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Undirected LGF IO
0 2 0
default
2 files changed with 1473 insertions and 0 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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief Lemon Graph Format reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

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

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

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

	
37 37
#include <lemon/lgf_writer.h>
38 38

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

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _reader_bits {
45 45

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

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

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

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

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

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

	
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
    template <typename _Graph, bool _dir, typename _Map, 
104
	      typename _Converter = DefaultConverter<typename _Map::Value> >
105
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
106
    public:
107
      typedef _Map Map;
108
      typedef _Converter Converter;
109
      typedef _Graph Graph;
110
      typedef typename Graph::Edge Item;
111
      static const bool dir = _dir;
112
      
113
    private:
114
      const Graph& _graph;
115
      Map& _map;
116
      Converter _converter;
117

	
118
    public:
119
      GraphArcMapStorage(const Graph& graph, Map& map, 
120
			 const Converter& converter = Converter()) 
121
	: _graph(graph), _map(map), _converter(converter) {}
122
      virtual ~GraphArcMapStorage() {}
123

	
124
      virtual void set(const Item& item ,const std::string& value) {
125
	_map.set(_graph.direct(item, dir), _converter(value));
126
      }
127
    };
128

	
103 129
    class ValueStorageBase {
104 130
    public:
105 131
      ValueStorageBase() {}
106 132
      virtual ~ValueStorageBase() {}
107 133

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

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

	
117 143
    private:
118 144
      Value& _value;
119 145
      Converter _converter;
120 146

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

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

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

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

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

	
175
    template <typename Graph>
176
    struct GraphArcLookUpConverter {
177
      const Graph& _graph;
178
      const std::map<std::string, typename Graph::Edge>& _map;
179
      
180
      GraphArcLookUpConverter(const Graph& graph, 
181
			      const std::map<std::string,
182
			                     typename Graph::Edge>& map) 
183
	: _graph(graph), _map(map) {}
184
      
185
      typename Graph::Arc operator()(const std::string& str) {
186
	if (str.empty() || (str[0] != '+' && str[0] != '-')) {
187
	  throw DataFormatError("Item must start with '+' or '-'");
188
	}
189
	typename std::map<std::string, typename Graph::Edge>
190
	  ::const_iterator it = _map.find(str.substr(1));
191
	if (it == _map.end()) {
192
	  throw DataFormatError("Item not found");
193
	}
194
	return _graph.direct(it->second, str[0] == '+');
195
      }
196
    };
197

	
149 198
    bool isWhiteSpace(char c) {
150 199
      return c == ' ' || c == '\t' || c == '\v' || 
151 200
        c == '\n' || c == '\r' || c == '\f'; 
152 201
    }
153 202
    
154 203
    bool isOct(char c) {
155 204
      return '0' <= c && c <='7'; 
156 205
    }
157 206
    
158 207
    int valueOct(char c) {
159 208
      LEMON_ASSERT(isOct(c), "The character is not octal.");
160 209
      return c - '0';
161 210
    }
162 211

	
163 212
    bool isHex(char c) {
164 213
      return ('0' <= c && c <= '9') || 
165 214
	('a' <= c && c <= 'z') || 
166 215
	('A' <= c && c <= 'Z'); 
167 216
    }
168 217
    
169 218
    int valueHex(char c) {
170 219
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
171 220
      if ('0' <= c && c <= '9') return c - '0';
172 221
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
173 222
      return c - 'A' + 10;
174 223
    }
175 224

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

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

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

	
191 240
      switch (c) {
192 241
      case '\\':
193 242
	return '\\';
194 243
      case '\"':
195 244
	return '\"';
196 245
      case '\'':
197 246
	return '\'';
198 247
      case '\?':
199 248
	return '\?';
200 249
      case 'a':
201 250
	return '\a';
202 251
      case 'b':
203 252
	return '\b';
204 253
      case 'f':
205 254
	return '\f';
206 255
      case 'n':
207 256
	return '\n';
208 257
      case 'r':
209 258
	return '\r';
210 259
      case 't':
211 260
	return '\t';
212 261
      case 'v':
213 262
	return '\v';
214 263
      case 'x':
215 264
	{
216 265
	  int code;
217 266
	  if (!is.get(c) || !isHex(c)) 
218 267
	    throw DataFormatError("Escape format error");
219 268
	  else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
220 269
	  else code = code * 16 + valueHex(c);
221 270
	  return code;
222 271
	}
223 272
      default:
224 273
	{
225 274
	  int code;
226 275
	  if (!isOct(c)) 
227 276
	    throw DataFormatError("Escape format error");
228 277
	  else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
229 278
	    is.putback(c);
230 279
	  else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
231 280
	    is.putback(c);
232 281
	  else code = code * 8 + valueOct(c);
233 282
	  return code;
234 283
	}	      
235 284
      } 
236 285
    }
237 286
    
238 287
    std::istream& readToken(std::istream& is, std::string& str) {
239 288
      std::ostringstream os;
240 289

	
241 290
      char c;
242 291
      is >> std::ws;
243 292
      
244 293
      if (!is.get(c)) 
245 294
	return is;
246 295

	
247 296
      if (c == '\"') {
248 297
	while (is.get(c) && c != '\"') {
249 298
	  if (c == '\\') 
250 299
	    c = readEscape(is);
251 300
	  os << c;
252 301
	}
253 302
	if (!is) 
254 303
	  throw DataFormatError("Quoted format error");
255 304
      } else {
256 305
	is.putback(c);
257 306
	while (is.get(c) && !isWhiteSpace(c)) {
258 307
	  if (c == '\\') 
259 308
	    c = readEscape(is);
260 309
	  os << c;
261 310
	}
262 311
	if (!is) {
263 312
	  is.clear();
264 313
	} else {
265 314
	  is.putback(c);
266 315
	}
267 316
      }
268 317
      str = os.str();
269 318
      return is;
270 319
    }
271 320

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

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

	
282 331
      Functor _functor;
283 332

	
284 333
    public:
285 334
      
286 335
      LineSection(const Functor& functor) : _functor(functor) {}
287 336
      virtual ~LineSection() {}
288 337

	
289 338
      virtual void process(std::istream& is, int& line_num) {
290 339
	char c;
291 340
	std::string line;
292 341
	while (is.get(c) && c != '@') {
293 342
	  if (c == '\n') {
294 343
	    ++line_num;
295 344
	  } else if (c == '#') {
296 345
	    getline(is, line);
297 346
	    ++line_num;
298 347
	  } else if (!isWhiteSpace(c)) {
299 348
	    is.putback(c);
300 349
	    getline(is, line);
301 350
	    _functor(line);
302 351
	    ++line_num;
303 352
	  }
304 353
	}
305 354
	if (is) is.putback(c);
306 355
	else if (is.eof()) is.clear();
307 356
      }
308 357
    };
309 358

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

	
314 363
      Functor _functor;
315 364

	
316 365
    public:
317 366
      
318 367
      StreamSection(const Functor& functor) : _functor(functor) {}
319 368
      virtual ~StreamSection() {} 
320 369

	
321 370
      virtual void process(std::istream& is, int& line_num) {
322 371
	_functor(is, line_num);
323 372
	char c;
324 373
	std::string line;
325 374
	while (is.get(c) && c != '@') {
326 375
	  if (c == '\n') {
327 376
	    ++line_num;
328 377
	  } else if (!isWhiteSpace(c)) {
329 378
	    getline(is, line);
330 379
	    ++line_num;
331 380
	  }
332 381
	}
333 382
	if (is) is.putback(c);
334 383
	else if (is.eof()) is.clear();	
335 384
      }
336 385
    };
337 386
    
338 387
  }
339 388

	
340 389
  /// \ingroup lemon_io
... ...
@@ -991,195 +1040,1037 @@
991 1040
          Node source = it->second;
992 1041

	
993 1042
          it = _node_index.find(target_token);
994 1043
          if (it == _node_index.end()) {       
995 1044
            std::ostringstream msg;            
996 1045
            msg << "Item not found: " << target_token;
997 1046
            throw DataFormatError(msg.str().c_str());
998 1047
          }                                          
999 1048
          Node target = it->second;                            
1000 1049

	
1001 1050
	  a = _digraph.addArc(source, target);
1002 1051
	  _arc_index.insert(std::make_pair(tokens[label_index], a));
1003 1052
	} else {
1004 1053
	  typename std::map<std::string, Arc>::iterator it =
1005 1054
	    _arc_index.find(tokens[label_index]);
1006 1055
	  if (it == _arc_index.end()) {
1007 1056
	    std::ostringstream msg;
1008 1057
	    msg << "Arc with label not found: " << tokens[label_index];
1009 1058
	    throw DataFormatError(msg.str().c_str());	    
1010 1059
	  }
1011 1060
	  a = it->second;
1012 1061
	}
1013 1062

	
1014 1063
	for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1015 1064
	  _arc_maps[i].second->set(a, tokens[map_index[i]]);
1016 1065
	}
1017 1066

	
1018 1067
      }
1019 1068
      if (readSuccess()) {
1020 1069
	line.putback(c);
1021 1070
      }
1022 1071
    }
1023 1072

	
1024 1073
    void readAttributes() {
1025 1074

	
1026 1075
      std::set<std::string> read_attr;
1027 1076

	
1028 1077
      char c;
1029 1078
      while (readLine() && line >> c && c != '@') {
1030 1079
	line.putback(c);
1031 1080
	
1032 1081
	std::string attr, token;
1033 1082
	if (!_reader_bits::readToken(line, attr))
1034 1083
	  throw DataFormatError("Attribute name not found");
1035 1084
	if (!_reader_bits::readToken(line, token))
1036 1085
	  throw DataFormatError("Attribute value not found");
1037 1086
	if (line >> c)
1038 1087
	  throw DataFormatError("Extra character on the end of line");	  
1039 1088

	
1040 1089
	{
1041 1090
	  std::set<std::string>::iterator it = read_attr.find(attr);
1042 1091
	  if (it != read_attr.end()) {
1043 1092
	    std::ostringstream msg;
1044 1093
	    msg << "Multiple occurence of attribute " << attr;
1045 1094
	    throw DataFormatError(msg.str().c_str());
1046 1095
	  }
1047 1096
	  read_attr.insert(attr);
1048 1097
	}
1049 1098
	
1050 1099
	{
1051 1100
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1052 1101
	  while (it != _attributes.end() && it->first == attr) {
1053 1102
	    it->second->set(token);
1054 1103
	    ++it;
1055 1104
	  }
1056 1105
	}
1057 1106

	
1058 1107
      }
1059 1108
      if (readSuccess()) {
1060 1109
	line.putback(c);
1061 1110
      }
1062 1111
      for (typename Attributes::iterator it = _attributes.begin();
1063 1112
	   it != _attributes.end(); ++it) {
1064 1113
	if (read_attr.find(it->first) == read_attr.end()) {
1065 1114
	  std::ostringstream msg;
1066 1115
	  msg << "Attribute not found in file: " << it->first;
1067 1116
	  throw DataFormatError(msg.str().c_str());
1068 1117
	}	
1069 1118
      }
1070 1119
    }
1071 1120

	
1072 1121
  public:
1073 1122

	
1074 1123
    /// \name Execution of the reader    
1075 1124
    /// @{
1076 1125

	
1077 1126
    /// \brief Start the batch processing
1078 1127
    ///
1079 1128
    /// This function starts the batch processing
1080 1129
    void run() {
1081 1130
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1082 1131
      if (!*_is) {
1083 1132
	throw DataFormatError("Cannot find file");
1084 1133
      }
1085 1134
      
1086 1135
      bool nodes_done = false;
1087 1136
      bool arcs_done = false;
1088 1137
      bool attributes_done = false;
1089 1138
      std::set<std::string> extra_sections;
1090 1139

	
1091 1140
      line_num = 0;      
1092 1141
      readLine();
1093 1142

	
1094 1143
      while (readSuccess()) {
1095 1144
	skipSection();
1096 1145
	try {
1097 1146
	  char c;
1098 1147
	  std::string section, caption;
1099 1148
	  line >> c;
1100 1149
	  _reader_bits::readToken(line, section);
1101 1150
	  _reader_bits::readToken(line, caption);
1102 1151

	
1103 1152
	  if (line >> c) 
1104 1153
	    throw DataFormatError("Extra character on the end of line");
1105 1154

	
1106 1155
	  if (section == "nodes" && !nodes_done) {
1107 1156
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1108 1157
	      readNodes();
1109 1158
	      nodes_done = true;
1110 1159
	    }
1111 1160
	  } else if ((section == "arcs" || section == "edges") && 
1112 1161
		     !arcs_done) {
1113 1162
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
1114 1163
	      readArcs();
1115 1164
	      arcs_done = true;
1116 1165
	    }
1117 1166
	  } else if (section == "attributes" && !attributes_done) {
1118 1167
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1119 1168
	      readAttributes();
1120 1169
	      attributes_done = true;
1121 1170
	    }
1122 1171
	  } else {
1123 1172
	    if (extra_sections.find(section) != extra_sections.end()) {
1124 1173
	      std::ostringstream msg;
1125 1174
	      msg << "Multiple occurence of section " << section;
1126 1175
	      throw DataFormatError(msg.str().c_str());
1127 1176
	    }
1128 1177
	    Sections::iterator it = _sections.find(section);
1129 1178
	    if (it != _sections.end()) {
1130 1179
	      extra_sections.insert(section);
1131 1180
	      it->second->process(*_is, line_num);
1132 1181
	      readLine();
1133 1182
	    } else {
1134 1183
	      readLine();
1135 1184
	      skipSection();
1136 1185
	    }
1137 1186
	  }
1138 1187
	} catch (DataFormatError& error) {
1139 1188
	  error.line(line_num);
1140 1189
	  throw;
1141 1190
	}	
1142 1191
      }
1143 1192

	
1144 1193
      if (!nodes_done) {
1145 1194
	throw DataFormatError("Section @nodes not found");
1146 1195
      }
1147 1196

	
1148 1197
      if (!arcs_done) {
1149 1198
	throw DataFormatError("Section @arcs not found");
1150 1199
      }
1151 1200

	
1152 1201
      if (!attributes_done && !_attributes.empty()) {
1153 1202
	throw DataFormatError("Section @attributes not found");
1154 1203
      }
1155 1204

	
1156 1205
    }
1157 1206

	
1158 1207
    /// @}
1159 1208
    
1160 1209
  };
1161 1210

	
1162 1211
  /// \relates DigraphReader
1163 1212
  template <typename Digraph>
1164 1213
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1165 1214
    DigraphReader<Digraph> tmp(is, digraph);
1166 1215
    return tmp;
1167 1216
  }
1168 1217

	
1169 1218
  /// \relates DigraphReader
1170 1219
  template <typename Digraph>
1171 1220
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1172 1221
				       Digraph& digraph) {
1173 1222
    DigraphReader<Digraph> tmp(fn, digraph);
1174 1223
    return tmp;
1175 1224
  }
1176 1225

	
1177 1226
  /// \relates DigraphReader
1178 1227
  template <typename Digraph>
1179 1228
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1180 1229
    DigraphReader<Digraph> tmp(fn, digraph);
1181 1230
    return tmp;
1182 1231
  }
1232

	
1233
  /// \ingroup lemon_io
1234
  ///  
1235
  /// \brief LGF reader for undirected graphs
1236
  ///
1237
  /// This utility reads an \ref lgf-format "LGF" file.
1238
  template <typename _Graph>
1239
  class GraphReader {
1240
  public:
1241

	
1242
    typedef _Graph Graph;
1243
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1244
    
1245
  private:
1246

	
1247

	
1248
    std::istream* _is;
1249
    bool local_is;
1250

	
1251
    Graph& _graph;
1252

	
1253
    std::string _nodes_caption;
1254
    std::string _edges_caption;
1255
    std::string _attributes_caption;
1256

	
1257
    typedef std::map<std::string, Node> NodeIndex;
1258
    NodeIndex _node_index;
1259
    typedef std::map<std::string, Edge> EdgeIndex;
1260
    EdgeIndex _edge_index;
1261
    
1262
    typedef std::vector<std::pair<std::string, 
1263
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1264
    NodeMaps _node_maps; 
1265

	
1266
    typedef std::vector<std::pair<std::string,
1267
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1268
    EdgeMaps _edge_maps;
1269

	
1270
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1271
      Attributes;
1272
    Attributes _attributes;
1273

	
1274
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1275
    Sections _sections;
1276

	
1277
    bool _use_nodes;
1278
    bool _use_edges;
1279

	
1280
    int line_num;
1281
    std::istringstream line;
1282

	
1283
  public:
1284

	
1285
    /// \brief Constructor
1286
    ///
1287
    /// Construct a undirected graph reader, which reads from the given
1288
    /// input stream.
1289
    GraphReader(std::istream& is, Graph& graph) 
1290
      : _is(&is), local_is(false), _graph(graph),
1291
	_use_nodes(false), _use_edges(false) {}
1292

	
1293
    /// \brief Constructor
1294
    ///
1295
    /// Construct a undirected graph reader, which reads from the given
1296
    /// file.
1297
    GraphReader(const std::string& fn, Graph& graph) 
1298
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1299
    	_use_nodes(false), _use_edges(false) {}
1300
    
1301
    /// \brief Constructor
1302
    ///
1303
    /// Construct a undirected graph reader, which reads from the given
1304
    /// file.
1305
    GraphReader(const char* fn, Graph& graph) 
1306
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1307
    	_use_nodes(false), _use_edges(false) {}
1308

	
1309
    /// \brief Copy constructor
1310
    ///
1311
    /// The copy constructor transfers all data from the other reader,
1312
    /// therefore the copied reader will not be usable more. 
1313
    GraphReader(GraphReader& other) 
1314
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1315
	_use_nodes(other._use_nodes), _use_edges(other._use_edges) {
1316

	
1317
      other._is = 0;
1318
      other.local_is = false;
1319
      
1320
      _node_index.swap(other._node_index);
1321
      _edge_index.swap(other._edge_index);
1322

	
1323
      _node_maps.swap(other._node_maps);
1324
      _edge_maps.swap(other._edge_maps);
1325
      _attributes.swap(other._attributes);
1326

	
1327
      _nodes_caption = other._nodes_caption;
1328
      _edges_caption = other._edges_caption;
1329
      _attributes_caption = other._attributes_caption;
1330

	
1331
      _sections.swap(other._sections);
1332
    }
1333

	
1334
    /// \brief Destructor
1335
    ~GraphReader() {
1336
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1337
	   it != _node_maps.end(); ++it) {
1338
	delete it->second;
1339
      }
1340

	
1341
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1342
	   it != _edge_maps.end(); ++it) {
1343
	delete it->second;
1344
      }
1345

	
1346
      for (typename Attributes::iterator it = _attributes.begin(); 
1347
	   it != _attributes.end(); ++it) {
1348
	delete it->second;
1349
      }
1350

	
1351
      for (typename Sections::iterator it = _sections.begin(); 
1352
	   it != _sections.end(); ++it) {
1353
	delete it->second;
1354
      }
1355

	
1356
      if (local_is) {
1357
	delete _is;
1358
      }
1359

	
1360
    }
1361

	
1362
  private:
1363
    
1364
    GraphReader& operator=(const GraphReader&);
1365

	
1366
  public:
1367

	
1368
    /// \name Reading rules
1369
    /// @{
1370
    
1371
    /// \brief Node map reading rule
1372
    ///
1373
    /// Add a node map reading rule to the reader.
1374
    template <typename Map>
1375
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1376
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1377
      _reader_bits::MapStorageBase<Node>* storage = 
1378
	new _reader_bits::MapStorage<Node, Map>(map);
1379
      _node_maps.push_back(std::make_pair(caption, storage));
1380
      return *this;
1381
    }
1382

	
1383
    /// \brief Node map reading rule
1384
    ///
1385
    /// Add a node map reading rule with specialized converter to the
1386
    /// reader.
1387
    template <typename Map, typename Converter>
1388
    GraphReader& nodeMap(const std::string& caption, Map& map, 
1389
			   const Converter& converter = Converter()) {
1390
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1391
      _reader_bits::MapStorageBase<Node>* storage = 
1392
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1393
      _node_maps.push_back(std::make_pair(caption, storage));
1394
      return *this;
1395
    }
1396

	
1397
    /// \brief Edge map reading rule
1398
    ///
1399
    /// Add an edge map reading rule to the reader.
1400
    template <typename Map>
1401
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1402
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1403
      _reader_bits::MapStorageBase<Edge>* storage = 
1404
	new _reader_bits::MapStorage<Edge, Map>(map);
1405
      _edge_maps.push_back(std::make_pair(caption, storage));
1406
      return *this;
1407
    }
1408

	
1409
    /// \brief Edge map reading rule
1410
    ///
1411
    /// Add an edge map reading rule with specialized converter to the
1412
    /// reader.
1413
    template <typename Map, typename Converter>
1414
    GraphReader& edgeMap(const std::string& caption, Map& map, 
1415
			  const Converter& converter = Converter()) {
1416
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1417
      _reader_bits::MapStorageBase<Edge>* storage = 
1418
	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1419
      _edge_maps.push_back(std::make_pair(caption, storage));
1420
      return *this;
1421
    }
1422

	
1423
    /// \brief Arc map reading rule
1424
    ///
1425
    /// Add an arc map reading rule to the reader.
1426
    template <typename Map>
1427
    GraphReader& arcMap(const std::string& caption, Map& map) {
1428
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1429
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1430
	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1431
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1432
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1433
	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1434
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1435
      return *this;
1436
    }
1437

	
1438
    /// \brief Arc map reading rule
1439
    ///
1440
    /// Add an arc map reading rule with specialized converter to the
1441
    /// reader.
1442
    template <typename Map, typename Converter>
1443
    GraphReader& arcMap(const std::string& caption, Map& map, 
1444
			  const Converter& converter = Converter()) {
1445
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1446
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1447
	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1448
	(_graph, map, converter);
1449
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1450
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1451
	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1452
	(_graph, map, converter);
1453
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1454
      return *this;
1455
    }
1456

	
1457
    /// \brief Attribute reading rule
1458
    ///
1459
    /// Add an attribute reading rule to the reader.
1460
    template <typename Value>
1461
    GraphReader& attribute(const std::string& caption, Value& value) {
1462
      _reader_bits::ValueStorageBase* storage = 
1463
	new _reader_bits::ValueStorage<Value>(value);
1464
      _attributes.insert(std::make_pair(caption, storage));
1465
      return *this;
1466
    }
1467

	
1468
    /// \brief Attribute reading rule
1469
    ///
1470
    /// Add an attribute reading rule with specialized converter to the
1471
    /// reader.
1472
    template <typename Value, typename Converter>
1473
    GraphReader& attribute(const std::string& caption, Value& value, 
1474
			     const Converter& converter = Converter()) {
1475
      _reader_bits::ValueStorageBase* storage = 
1476
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1477
      _attributes.insert(std::make_pair(caption, storage));
1478
      return *this;
1479
    }
1480

	
1481
    /// \brief Node reading rule
1482
    ///
1483
    /// Add a node reading rule to reader.
1484
    GraphReader& node(const std::string& caption, Node& node) {
1485
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1486
      Converter converter(_node_index);
1487
      _reader_bits::ValueStorageBase* storage = 
1488
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1489
      _attributes.insert(std::make_pair(caption, storage));
1490
      return *this;
1491
    }
1492

	
1493
    /// \brief Edge reading rule
1494
    ///
1495
    /// Add an edge reading rule to reader.
1496
    GraphReader& edge(const std::string& caption, Edge& edge) {
1497
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1498
      Converter converter(_edge_index);
1499
      _reader_bits::ValueStorageBase* storage = 
1500
	new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1501
      _attributes.insert(std::make_pair(caption, storage));
1502
      return *this;
1503
    }
1504

	
1505
    /// \brief Arc reading rule
1506
    ///
1507
    /// Add an arc reading rule to reader.
1508
    GraphReader& arc(const std::string& caption, Arc& arc) {
1509
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1510
      Converter converter(_graph, _edge_index);
1511
      _reader_bits::ValueStorageBase* storage = 
1512
	new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1513
      _attributes.insert(std::make_pair(caption, storage));
1514
      return *this;
1515
    }
1516

	
1517
    /// @}
1518

	
1519
    /// \name Select section by name
1520
    /// @{
1521

	
1522
    /// \brief Set \c \@nodes section to be read
1523
    ///
1524
    /// Set \c \@nodes section to be read
1525
    GraphReader& nodes(const std::string& caption) {
1526
      _nodes_caption = caption;
1527
      return *this;
1528
    }
1529

	
1530
    /// \brief Set \c \@edges section to be read
1531
    ///
1532
    /// Set \c \@edges section to be read
1533
    GraphReader& edges(const std::string& caption) {
1534
      _edges_caption = caption;
1535
      return *this;
1536
    }
1537

	
1538
    /// \brief Set \c \@attributes section to be read
1539
    ///
1540
    /// Set \c \@attributes section to be read
1541
    GraphReader& attributes(const std::string& caption) {
1542
      _attributes_caption = caption;
1543
      return *this;
1544
    }
1545

	
1546
    /// @}
1547

	
1548
    /// \name Section readers
1549
    /// @{
1550

	
1551
    /// \brief Add a section processor with line oriented reading
1552
    ///
1553
    /// In the \e LGF file extra sections can be placed, which contain
1554
    /// any data in arbitrary format. These sections can be read with
1555
    /// this function line by line. The first parameter is the type
1556
    /// descriptor of the section, the second is a functor, which
1557
    /// takes just one \c std::string parameter. At the reading
1558
    /// process, each line of the section will be given to the functor
1559
    /// object. However, the empty lines and the comment lines are
1560
    /// filtered out, and the leading whitespaces are stipped from
1561
    /// each processed string.
1562
    ///
1563
    /// For example let's see a section, which contain several
1564
    /// integers, which should be inserted into a vector.
1565
    ///\code
1566
    ///  @numbers
1567
    ///  12 45 23
1568
    ///  4
1569
    ///  23 6
1570
    ///\endcode
1571
    ///
1572
    /// The functor is implemented as an struct:
1573
    ///\code
1574
    ///  struct NumberSection {
1575
    ///    std::vector<int>& _data;
1576
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
1577
    ///    void operator()(const std::string& line) {
1578
    ///      std::istringstream ls(line);
1579
    ///      int value;
1580
    ///      while (ls >> value) _data.push_back(value);
1581
    ///    }
1582
    ///  };
1583
    ///
1584
    ///  // ...
1585
    ///
1586
    ///  reader.sectionLines("numbers", NumberSection(vec));  
1587
    ///\endcode
1588
    template <typename Functor>
1589
    GraphReader& sectionLines(const std::string& type, Functor functor) {
1590
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1591
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1592
		   "Multiple reading of section.");
1593
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1594
		   type != "attributes", "Multiple reading of section.");
1595
      _sections.insert(std::make_pair(type, 
1596
        new _reader_bits::LineSection<Functor>(functor)));
1597
      return *this;
1598
    }
1599

	
1600

	
1601
    /// \brief Add a section processor with stream oriented reading
1602
    ///
1603
    /// In the \e LGF file extra sections can be placed, which contain
1604
    /// any data in arbitrary format. These sections can be read
1605
    /// directly with this function. The first parameter is the type
1606
    /// of the section, the second is a functor, which takes an \c
1607
    /// std::istream& and an int& parameter, the latter regard to the
1608
    /// line number of stream. The functor can read the input while
1609
    /// the section go on, and the line number should be modified
1610
    /// accordingly.
1611
    template <typename Functor>
1612
    GraphReader& sectionStream(const std::string& type, Functor functor) {
1613
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
1614
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
1615
		   "Multiple reading of section.");
1616
      LEMON_ASSERT(type != "nodes" && type != "arcs" && type != "edges" &&
1617
		   type != "attributes", "Multiple reading of section.");
1618
      _sections.insert(std::make_pair(type, 
1619
	 new _reader_bits::StreamSection<Functor>(functor)));
1620
      return *this;
1621
    }    
1622
    
1623
    /// @}
1624

	
1625
    /// \name Using previously constructed node or edge set
1626
    /// @{
1627

	
1628
    /// \brief Use previously constructed node set
1629
    ///
1630
    /// Use previously constructed node set, and specify the node
1631
    /// label map.
1632
    template <typename Map>
1633
    GraphReader& useNodes(const Map& map) {
1634
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1635
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1636
      _use_nodes = true;
1637
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1638
      for (NodeIt n(_graph); n != INVALID; ++n) {
1639
	_node_index.insert(std::make_pair(converter(map[n]), n));
1640
      }
1641
      return *this;
1642
    }
1643

	
1644
    /// \brief Use previously constructed node set
1645
    ///
1646
    /// Use previously constructed node set, and specify the node
1647
    /// label map and a functor which converts the label map values to
1648
    /// std::string.
1649
    template <typename Map, typename Converter>
1650
    GraphReader& useNodes(const Map& map, 
1651
			    const Converter& converter = Converter()) {
1652
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1653
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); 
1654
      _use_nodes = true;
1655
      for (NodeIt n(_graph); n != INVALID; ++n) {
1656
	_node_index.insert(std::make_pair(converter(map[n]), n));
1657
      }
1658
      return *this;
1659
    }
1660

	
1661
    /// \brief Use previously constructed edge set
1662
    ///
1663
    /// Use previously constructed edge set, and specify the edge
1664
    /// label map.
1665
    template <typename Map>
1666
    GraphReader& useEdges(const Map& map) {
1667
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1668
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1669
      _use_edges = true;
1670
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1671
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1672
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1673
      }
1674
      return *this;
1675
    }
1676

	
1677
    /// \brief Use previously constructed edge set
1678
    ///
1679
    /// Use previously constructed edge set, and specify the edge
1680
    /// label map and a functor which converts the label map values to
1681
    /// std::string.
1682
    template <typename Map, typename Converter>
1683
    GraphReader& useEdges(const Map& map, 
1684
			    const Converter& converter = Converter()) {
1685
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1686
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); 
1687
      _use_edges = true;
1688
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1689
	_edge_index.insert(std::make_pair(converter(map[a]), a));
1690
      }
1691
      return *this;
1692
    }
1693

	
1694
    /// @}
1695

	
1696
  private:
1697

	
1698
    bool readLine() {
1699
      std::string str;
1700
      while(++line_num, std::getline(*_is, str)) {
1701
	line.clear(); line.str(str);
1702
	char c;
1703
	if (line >> std::ws >> c && c != '#') {
1704
	  line.putback(c);
1705
	  return true;
1706
	}
1707
      }
1708
      return false;
1709
    }
1710

	
1711
    bool readSuccess() {
1712
      return static_cast<bool>(*_is);
1713
    }
1714
    
1715
    void skipSection() {
1716
      char c;
1717
      while (readSuccess() && line >> c && c != '@') {
1718
	readLine();
1719
      }
1720
      line.putback(c);
1721
    }
1722

	
1723
    void readNodes() {
1724

	
1725
      std::vector<int> map_index(_node_maps.size());
1726
      int map_num, label_index;
1727

	
1728
      if (!readLine()) 
1729
	throw DataFormatError("Cannot find map captions");
1730
      
1731
      {
1732
	std::map<std::string, int> maps;
1733
	
1734
	std::string map;
1735
	int index = 0;
1736
	while (_reader_bits::readToken(line, map)) {
1737
	  if (maps.find(map) != maps.end()) {
1738
	    std::ostringstream msg;
1739
	    msg << "Multiple occurence of node map: " << map;
1740
	    throw DataFormatError(msg.str().c_str());
1741
	  }
1742
	  maps.insert(std::make_pair(map, index));
1743
	  ++index;
1744
	}
1745
	
1746
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1747
	  std::map<std::string, int>::iterator jt = 
1748
	    maps.find(_node_maps[i].first);
1749
	  if (jt == maps.end()) {
1750
	    std::ostringstream msg;
1751
	    msg << "Map not found in file: " << _node_maps[i].first;
1752
	    throw DataFormatError(msg.str().c_str());
1753
	  }
1754
	  map_index[i] = jt->second;
1755
	}
1756

	
1757
	{
1758
	  std::map<std::string, int>::iterator jt = maps.find("label");
1759
	  if (jt == maps.end())
1760
	    throw DataFormatError("Label map not found in file");
1761
	  label_index = jt->second;
1762
	}
1763
	map_num = maps.size();
1764
      }
1765

	
1766
      char c;
1767
      while (readLine() && line >> c && c != '@') {
1768
	line.putback(c);
1769

	
1770
	std::vector<std::string> tokens(map_num);
1771
	for (int i = 0; i < map_num; ++i) {
1772
	  if (!_reader_bits::readToken(line, tokens[i])) {
1773
	    std::ostringstream msg;
1774
	    msg << "Column not found (" << i + 1 << ")";
1775
	    throw DataFormatError(msg.str().c_str());
1776
	  }
1777
	}
1778
	if (line >> std::ws >> c)
1779
	  throw DataFormatError("Extra character on the end of line");
1780
	
1781
	Node n;
1782
	if (!_use_nodes) {
1783
	  n = _graph.addNode();
1784
	  _node_index.insert(std::make_pair(tokens[label_index], n));
1785
	} else {
1786
	  typename std::map<std::string, Node>::iterator it =
1787
	    _node_index.find(tokens[label_index]);
1788
	  if (it == _node_index.end()) {
1789
	    std::ostringstream msg;
1790
	    msg << "Node with label not found: " << tokens[label_index];
1791
	    throw DataFormatError(msg.str().c_str());	    
1792
	  }
1793
	  n = it->second;
1794
	}
1795

	
1796
	for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1797
	  _node_maps[i].second->set(n, tokens[map_index[i]]);
1798
	}
1799

	
1800
      }
1801
      if (readSuccess()) {
1802
	line.putback(c);
1803
      }
1804
    }
1805

	
1806
    void readEdges() {
1807

	
1808
      std::vector<int> map_index(_edge_maps.size());
1809
      int map_num, label_index;
1810

	
1811
      if (!readLine()) 
1812
	throw DataFormatError("Cannot find map captions");
1813
      
1814
      {
1815
	std::map<std::string, int> maps;
1816
	
1817
	std::string map;
1818
	int index = 0;
1819
	while (_reader_bits::readToken(line, map)) {
1820
	  if (maps.find(map) != maps.end()) {
1821
	    std::ostringstream msg;
1822
	    msg << "Multiple occurence of edge map: " << map;
1823
	    throw DataFormatError(msg.str().c_str());
1824
	  }
1825
	  maps.insert(std::make_pair(map, index));
1826
	  ++index;
1827
	}
1828
	
1829
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1830
	  std::map<std::string, int>::iterator jt = 
1831
	    maps.find(_edge_maps[i].first);
1832
	  if (jt == maps.end()) {
1833
	    std::ostringstream msg;
1834
	    msg << "Map not found in file: " << _edge_maps[i].first;
1835
	    throw DataFormatError(msg.str().c_str());
1836
	  }
1837
	  map_index[i] = jt->second;
1838
	}
1839

	
1840
	{
1841
	  std::map<std::string, int>::iterator jt = maps.find("label");
1842
	  if (jt == maps.end())
1843
	    throw DataFormatError("Label map not found in file");
1844
	  label_index = jt->second;
1845
	}
1846
	map_num = maps.size();
1847
      }
1848

	
1849
      char c;
1850
      while (readLine() && line >> c && c != '@') {
1851
	line.putback(c);
1852

	
1853
	std::string source_token;
1854
	std::string target_token;
1855

	
1856
	if (!_reader_bits::readToken(line, source_token))
1857
	  throw DataFormatError("Source not found");
1858

	
1859
	if (!_reader_bits::readToken(line, target_token))
1860
	  throw DataFormatError("Source not found");
1861
	
1862
	std::vector<std::string> tokens(map_num);
1863
	for (int i = 0; i < map_num; ++i) {
1864
	  if (!_reader_bits::readToken(line, tokens[i])) {
1865
	    std::ostringstream msg;
1866
	    msg << "Column not found (" << i + 1 << ")";
1867
	    throw DataFormatError(msg.str().c_str());
1868
	  }
1869
	}
1870
	if (line >> std::ws >> c)
1871
	  throw DataFormatError("Extra character on the end of line");
1872
	
1873
	Edge e;
1874
	if (!_use_edges) {
1875

	
1876
          typename NodeIndex::iterator it;
1877
 
1878
          it = _node_index.find(source_token);
1879
          if (it == _node_index.end()) {
1880
            std::ostringstream msg;
1881
            msg << "Item not found: " << source_token;
1882
            throw DataFormatError(msg.str().c_str());
1883
          }
1884
          Node source = it->second;
1885

	
1886
          it = _node_index.find(target_token);
1887
          if (it == _node_index.end()) {       
1888
            std::ostringstream msg;            
1889
            msg << "Item not found: " << target_token;
1890
            throw DataFormatError(msg.str().c_str());
1891
          }                                          
1892
          Node target = it->second;                            
1893

	
1894
	  e = _graph.addEdge(source, target);
1895
	  _edge_index.insert(std::make_pair(tokens[label_index], e));
1896
	} else {
1897
	  typename std::map<std::string, Edge>::iterator it =
1898
	    _edge_index.find(tokens[label_index]);
1899
	  if (it == _edge_index.end()) {
1900
	    std::ostringstream msg;
1901
	    msg << "Edge with label not found: " << tokens[label_index];
1902
	    throw DataFormatError(msg.str().c_str());	    
1903
	  }
1904
	  e = it->second;
1905
	}
1906

	
1907
	for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1908
	  _edge_maps[i].second->set(e, tokens[map_index[i]]);
1909
	}
1910

	
1911
      }
1912
      if (readSuccess()) {
1913
	line.putback(c);
1914
      }
1915
    }
1916

	
1917
    void readAttributes() {
1918

	
1919
      std::set<std::string> read_attr;
1920

	
1921
      char c;
1922
      while (readLine() && line >> c && c != '@') {
1923
	line.putback(c);
1924
	
1925
	std::string attr, token;
1926
	if (!_reader_bits::readToken(line, attr))
1927
	  throw DataFormatError("Attribute name not found");
1928
	if (!_reader_bits::readToken(line, token))
1929
	  throw DataFormatError("Attribute value not found");
1930
	if (line >> c)
1931
	  throw DataFormatError("Extra character on the end of line");	  
1932

	
1933
	{
1934
	  std::set<std::string>::iterator it = read_attr.find(attr);
1935
	  if (it != read_attr.end()) {
1936
	    std::ostringstream msg;
1937
	    msg << "Multiple occurence of attribute " << attr;
1938
	    throw DataFormatError(msg.str().c_str());
1939
	  }
1940
	  read_attr.insert(attr);
1941
	}
1942
	
1943
	{
1944
	  typename Attributes::iterator it = _attributes.lower_bound(attr);
1945
	  while (it != _attributes.end() && it->first == attr) {
1946
	    it->second->set(token);
1947
	    ++it;
1948
	  }
1949
	}
1950

	
1951
      }
1952
      if (readSuccess()) {
1953
	line.putback(c);
1954
      }
1955
      for (typename Attributes::iterator it = _attributes.begin();
1956
	   it != _attributes.end(); ++it) {
1957
	if (read_attr.find(it->first) == read_attr.end()) {
1958
	  std::ostringstream msg;
1959
	  msg << "Attribute not found in file: " << it->first;
1960
	  throw DataFormatError(msg.str().c_str());
1961
	}	
1962
      }
1963
    }
1964

	
1965
  public:
1966

	
1967
    /// \name Execution of the reader    
1968
    /// @{
1969

	
1970
    /// \brief Start the batch processing
1971
    ///
1972
    /// This function starts the batch processing
1973
    void run() {
1974
      
1975
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1976
      
1977
      bool nodes_done = false;
1978
      bool edges_done = false;
1979
      bool attributes_done = false;
1980
      std::set<std::string> extra_sections;
1981

	
1982
      line_num = 0;      
1983
      readLine();
1984

	
1985
      while (readSuccess()) {
1986
	skipSection();
1987
	try {
1988
	  char c;
1989
	  std::string section, caption;
1990
	  line >> c;
1991
	  _reader_bits::readToken(line, section);
1992
	  _reader_bits::readToken(line, caption);
1993

	
1994
	  if (line >> c) 
1995
	    throw DataFormatError("Extra character on the end of line");
1996

	
1997
	  if (section == "nodes" && !nodes_done) {
1998
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1999
	      readNodes();
2000
	      nodes_done = true;
2001
	    }
2002
	  } else if ((section == "edges" || section == "arcs") && 
2003
		     !edges_done) {
2004
	    if (_edges_caption.empty() || _edges_caption == caption) {
2005
	      readEdges();
2006
	      edges_done = true;
2007
	    }
2008
	  } else if (section == "attributes" && !attributes_done) {
2009
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
2010
	      readAttributes();
2011
	      attributes_done = true;
2012
	    }
2013
	  } else {
2014
	    if (extra_sections.find(section) != extra_sections.end()) {
2015
	      std::ostringstream msg;
2016
	      msg << "Multiple occurence of section " << section;
2017
	      throw DataFormatError(msg.str().c_str());
2018
	    }
2019
	    Sections::iterator it = _sections.find(section);
2020
	    if (it != _sections.end()) {
2021
	      extra_sections.insert(section);
2022
	      it->second->process(*_is, line_num);
2023
	      readLine();
2024
	    } else {
2025
	      readLine();
2026
	      skipSection();
2027
	    }
2028
	  }
2029
	} catch (DataFormatError& error) {
2030
	  error.line(line_num);
2031
	  throw;
2032
	}	
2033
      }
2034

	
2035
      if (!nodes_done) {
2036
	throw DataFormatError("Section @nodes not found");
2037
      }
2038

	
2039
      if (!edges_done) {
2040
	throw DataFormatError("Section @edges not found");
2041
      }
2042

	
2043
      if (!attributes_done && !_attributes.empty()) {
2044
	throw DataFormatError("Section @attributes not found");
2045
      }
2046

	
2047
    }
2048

	
2049
    /// @}
2050
    
2051
  };
2052

	
2053
  /// \relates GraphReader
2054
  template <typename Graph>
2055
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2056
    GraphReader<Graph> tmp(is, graph);
2057
    return tmp;
2058
  }
2059

	
2060
  /// \relates GraphReader
2061
  template <typename Graph>
2062
  GraphReader<Graph> graphReader(const std::string& fn, 
2063
				       Graph& graph) {
2064
    GraphReader<Graph> tmp(fn, graph);
2065
    return tmp;
2066
  }
2067

	
2068
  /// \relates GraphReader
2069
  template <typename Graph>
2070
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2071
    GraphReader<Graph> tmp(fn, graph);
2072
    return tmp;
2073
  }
1183 2074
}
1184 2075

	
1185 2076
#endif
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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief Lemon Graph Format writer.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_WRITER_H
25 25
#define LEMON_LGF_WRITER_H
26 26

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

	
31 31
#include <algorithm>
32 32

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

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

	
39 39
namespace lemon {
40 40

	
41 41
  namespace _writer_bits {
42 42

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

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

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

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

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

	
74
    template <typename _Graph, bool _dir, typename _Map>
75
    class GraphArcMapLess {
76
    public:
77
      typedef _Map Map;
78
      typedef _Graph Graph;
79
      typedef typename Graph::Edge Item;
80

	
81
    private:
82
      const Graph& _graph;
83
      const Map& _map;
84
      
85
    public:
86
      GraphArcMapLess(const Graph& graph, const Map& map) 
87
	: _graph(graph), _map(map) {}
88

	
89
      bool operator()(const Item& left, const Item& right) {
90
	return _map[_graph.direct(left, _dir)] < 
91
	  _map[_graph.direct(right, _dir)];
92
      }
93
    };
94

	
74 95
    template <typename _Item>    
75 96
    class MapStorageBase {
76 97
    public:
77 98
      typedef _Item Item;
78 99

	
79 100
    public:
80 101
      MapStorageBase() {}
81 102
      virtual ~MapStorageBase() {}
82 103

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

	
87 108
    template <typename _Item, typename _Map, 
88 109
	      typename _Converter = DefaultConverter<typename _Map::Value> >
89 110
    class MapStorage : public MapStorageBase<_Item> {
90 111
    public:
91 112
      typedef _Map Map;
92 113
      typedef _Converter Converter;
93 114
      typedef _Item Item;
94 115
      
95 116
    private:
96 117
      const Map& _map;
97 118
      Converter _converter;
98 119

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

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

	
134
    template <typename _Graph, bool _dir, typename _Map, 
135
	      typename _Converter = DefaultConverter<typename _Map::Value> >
136
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
137
    public:
138
      typedef _Map Map;
139
      typedef _Converter Converter;
140
      typedef _Graph Graph;
141
      typedef typename Graph::Edge Item;
142
      static const bool dir = _dir;
143
      
144
    private:
145
      const Graph& _graph;
146
      const Map& _map;
147
      Converter _converter;
148

	
149
    public:
150
      GraphArcMapStorage(const Graph& graph, const Map& map,  
151
			 const Converter& converter = Converter()) 
152
	: _graph(graph), _map(map), _converter(converter) {}
153
      virtual ~GraphArcMapStorage() {}
154

	
155
      virtual std::string get(const Item& item) {
156
	return _converter(_map[_graph.direct(item, dir)]);
157
      }
158
      virtual void sort(std::vector<Item>& items) {
159
	GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
160
	std::sort(items.begin(), items.end(), less);
161
      }
162
    };
163

	
113 164
    class ValueStorageBase {
114 165
    public:
115 166
      ValueStorageBase() {}
116 167
      virtual ~ValueStorageBase() {}
117 168

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

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

	
127 178
    private:
128 179
      const Value& _value;
129 180
      Converter _converter;
130 181

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

	
135 186
      virtual std::string get() {
136 187
	return _converter(_value);
137 188
      }
138 189
    };
139 190

	
140 191
    template <typename Value>
141 192
    struct MapLookUpConverter {
142 193
      const std::map<Value, std::string>& _map;
143 194
      
144 195
      MapLookUpConverter(const std::map<Value, std::string>& map) 
145 196
	: _map(map) {}
146 197
      
147 198
      std::string operator()(const Value& str) {
148 199
	typename std::map<Value, std::string>::const_iterator it = 
149 200
	  _map.find(str);
150 201
	if (it == _map.end()) {
151 202
	  throw DataFormatError("Item not found");
152 203
	}
153 204
	return it->second;
154 205
      }
155 206
    };
156 207

	
208
    template <typename Graph>
209
    struct GraphArcLookUpConverter {
210
      const Graph& _graph;
211
      const std::map<typename Graph::Edge, std::string>& _map;
212
      
213
      GraphArcLookUpConverter(const Graph& graph, 
214
			      const std::map<typename Graph::Edge, 
215
			                     std::string>& map) 
216
	: _graph(graph), _map(map) {}
217
      
218
      std::string operator()(const typename Graph::Arc& val) {
219
	typename std::map<typename Graph::Edge, std::string>
220
	  ::const_iterator it = _map.find(val);
221
	if (it == _map.end()) {
222
	  throw DataFormatError("Item not found");
223
	}
224
	return (_graph.direction(val) ? '+' : '-') + it->second;
225
      }
226
    };
227

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

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

	
167 238
    static void writeEscape(std::ostream& os, char c) {
168 239
      switch (c) {
169 240
      case '\\':
170 241
	os << "\\\\";
171 242
	return;
172 243
      case '\"':
173 244
	os << "\\\"";
174 245
	return;
175 246
      case '\a':
176 247
	os << "\\a";
177 248
	return;
178 249
      case '\b':
179 250
	os << "\\b";
180 251
	return;
181 252
      case '\f':
182 253
	os << "\\f";
183 254
	return;
184 255
      case '\r':
185 256
	os << "\\r";
186 257
	return;
187 258
      case '\n':
188 259
	os << "\\n";
189 260
	return;
190 261
      case '\t':
191 262
	os << "\\t";
192 263
	return;
193 264
      case '\v':
194 265
	os << "\\v";
195 266
	return;
196 267
      default:
197 268
	if (c < 0x20) {
198 269
	  std::ios::fmtflags flags = os.flags();
199 270
	  os << '\\' << std::oct << static_cast<int>(c);
200 271
	  os.flags(flags);
201 272
	} else {
202 273
	  os << c;
203 274
	}
204 275
	return;
205 276
      }     
206 277
    }
207 278

	
208 279
    bool requireEscape(const std::string& str) {
209 280
      if (str.empty() || str[0] == '@') return true;
210 281
      std::istringstream is(str);
211 282
      char c;
212 283
      while (is.get(c)) {
213 284
	if (isWhiteSpace(c) || isEscaped(c)) {
214 285
	  return true;
215 286
	}
216 287
      }
217 288
      return false;
218 289
    }
219 290
    
220 291
    std::ostream& writeToken(std::ostream& os, const std::string& str) {
221 292

	
222 293
      if (requireEscape(str)) {
223 294
	os << '\"';
224 295
	for (std::string::const_iterator it = str.begin(); 
225 296
	     it != str.end(); ++it) {
226 297
	  writeEscape(os, *it);
227 298
	}	
228 299
	os << '\"';
229 300
      } else {
230 301
	os << str;
231 302
      }
232 303
      return os;
233 304
    }
234 305

	
235 306
  }
236 307
  
237 308
  /// \ingroup lemon_io
238 309
  ///  
239 310
  /// \brief LGF writer for directed graphs
240 311
  ///
241 312
  /// This utility writes an \ref lgf-format "LGF" file.
242 313
  ///
243 314
  /// The writing method does a batch processing. The user creates a
244 315
  /// writer object, then various writing rules can be added to the
245 316
  /// writer, and eventually the writing is executed with the \c run()
246 317
  /// member function. A map writing rule can be added to the writer
247 318
  /// with the \c nodeMap() or \c arcMap() members. An optional
248 319
  /// converter parameter can also be added as a standard functor
249 320
  /// converting from the value type of the map to std::string. If it
250 321
  /// is set, it will determine how the map's value type is written to
251 322
  /// the output stream. If the functor is not set, then a default
252 323
  /// conversion will be used. The \c attribute(), \c node() and \c
253 324
  /// arc() functions are used to add attribute writing rules.
254 325
  ///
255 326
  ///\code
256 327
  ///     DigraphWriter<Digraph>(std::cout, digraph).
257 328
  ///       nodeMap("coordinates", coord_map).
258 329
  ///       nodeMap("size", size).
259 330
  ///       nodeMap("title", title).
260 331
  ///       arcMap("capacity", cap_map).
261 332
  ///       node("source", src).
262 333
  ///       node("target", trg).
263 334
  ///       attribute("caption", caption).
264 335
  ///       run();
265 336
  ///\endcode
266 337
  ///
267 338
  ///
268 339
  /// By default, the writer does not write additional captions to the
269 340
  /// sections, but they can be give as an optional parameter of
270 341
  /// the \c nodes(), \c arcs() or \c
271 342
  /// attributes() functions.
272 343
  ///
273 344
  /// The \c skipNodes() and \c skipArcs() functions forbid the
274 345
  /// writing of the sections. If two arc sections should be written
275 346
  /// to the output, it can be done in two passes, the first pass
276 347
  /// writes the node section and the first arc section, then the
277 348
  /// second pass skips the node section and writes just the arc
278 349
  /// section to the stream. The output stream can be retrieved with
279 350
  /// the \c ostream() function, hence the second pass can append its
280 351
  /// output to the output of the first pass.
281 352
  template <typename _Digraph>
282 353
  class DigraphWriter {
283 354
  public:
284 355

	
285 356
    typedef _Digraph Digraph;
286 357
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
287 358
    
288 359
  private:
289 360

	
290 361

	
291 362
    std::ostream* _os;
292 363
    bool local_os;
293 364

	
294 365
    Digraph& _digraph;
295 366

	
296 367
    std::string _nodes_caption;
297 368
    std::string _arcs_caption;
298 369
    std::string _attributes_caption;
299 370
    
300 371
    typedef std::map<Node, std::string> NodeIndex;
301 372
    NodeIndex _node_index;
302 373
    typedef std::map<Arc, std::string> ArcIndex;
303 374
    ArcIndex _arc_index;
304 375

	
305 376
    typedef std::vector<std::pair<std::string, 
306 377
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
307 378
    NodeMaps _node_maps; 
308 379

	
309 380
    typedef std::vector<std::pair<std::string, 
310 381
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
311 382
    ArcMaps _arc_maps;
312 383

	
313 384
    typedef std::vector<std::pair<std::string, 
314 385
      _writer_bits::ValueStorageBase*> > Attributes;
315 386
    Attributes _attributes;
316 387

	
317 388
    bool _skip_nodes;
318 389
    bool _skip_arcs;
319 390

	
320 391
  public:
321 392

	
322 393
    /// \brief Constructor
323 394
    ///
324 395
    /// Construct a directed graph writer, which writes to the given
325 396
    /// output stream.
326 397
    DigraphWriter(std::ostream& is, Digraph& digraph) 
327 398
      : _os(&is), local_os(false), _digraph(digraph),
328 399
	_skip_nodes(false), _skip_arcs(false) {}
329 400

	
330 401
    /// \brief Constructor
331 402
    ///
332 403
    /// Construct a directed graph writer, which writes to the given
333 404
    /// output file.
334 405
    DigraphWriter(const std::string& fn, Digraph& digraph) 
335 406
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
336 407
	_skip_nodes(false), _skip_arcs(false) {}
337 408

	
338 409
    /// \brief Constructor
339 410
    ///
340 411
    /// Construct a directed graph writer, which writes to the given
341 412
    /// output file.
342 413
    DigraphWriter(const char* fn, Digraph& digraph) 
343 414
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
344 415
	_skip_nodes(false), _skip_arcs(false) {}
345 416

	
346 417
    /// \brief Copy constructor
347 418
    ///
348 419
    /// The copy constructor transfers all data from the other writer,
... ...
@@ -549,195 +620,706 @@
549 620

	
550 621
    void writeNodes() {
551 622
      _writer_bits::MapStorageBase<Node>* label = 0;
552 623
      for (typename NodeMaps::iterator it = _node_maps.begin();
553 624
	   it != _node_maps.end(); ++it) {
554 625
        if (it->first == "label") {
555 626
	  label = it->second;
556 627
	  break;
557 628
	}
558 629
      }
559 630

	
560 631
      *_os << "@nodes";
561 632
      if (!_nodes_caption.empty()) {
562 633
	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
563 634
      }
564 635
      *_os << std::endl;
565 636

	
566 637
      if (label == 0) {
567 638
	*_os << "label" << '\t';
568 639
      }
569 640
      for (typename NodeMaps::iterator it = _node_maps.begin();
570 641
	   it != _node_maps.end(); ++it) {
571 642
	_writer_bits::writeToken(*_os, it->first) << '\t';
572 643
      }
573 644
      *_os << std::endl;
574 645

	
575 646
      std::vector<Node> nodes;
576 647
      for (NodeIt n(_digraph); n != INVALID; ++n) {
577 648
	nodes.push_back(n);
578 649
      }
579 650
      
580 651
      if (label == 0) {
581 652
	IdMap<Digraph, Node> id_map(_digraph);
582 653
	_writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
583 654
	std::sort(nodes.begin(), nodes.end(), id_less);
584 655
      } else {
585 656
	label->sort(nodes);
586 657
      }
587 658

	
588 659
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
589 660
	Node n = nodes[i];
590 661
	if (label == 0) {
591 662
	  std::ostringstream os;
592 663
	  os << _digraph.id(n);
593 664
	  _writer_bits::writeToken(*_os, os.str());
594 665
	  *_os << '\t';
595 666
	  _node_index.insert(std::make_pair(n, os.str()));
596 667
	}
597 668
	for (typename NodeMaps::iterator it = _node_maps.begin();
598 669
	     it != _node_maps.end(); ++it) {
599 670
	  std::string value = it->second->get(n);
600 671
	  _writer_bits::writeToken(*_os, value);
601 672
	  if (it->first == "label") {
602 673
	    _node_index.insert(std::make_pair(n, value));
603 674
	  }
604 675
	  *_os << '\t';
605 676
	}
606 677
	*_os << std::endl;
607 678
      }
608 679
    }
609 680

	
610 681
    void writeArcs() {
611 682
      _writer_bits::MapStorageBase<Arc>* label = 0;
612 683
      for (typename ArcMaps::iterator it = _arc_maps.begin();
613 684
	   it != _arc_maps.end(); ++it) {
614 685
        if (it->first == "label") {
615 686
	  label = it->second;
616 687
	  break;
617 688
	}
618 689
      }
619 690

	
620 691
      *_os << "@arcs";
621 692
      if (!_arcs_caption.empty()) {
622 693
	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
623 694
      }
624 695
      *_os << std::endl;
625 696

	
626 697
      *_os << '\t' << '\t';
627 698
      if (label == 0) {
628 699
	*_os << "label" << '\t';
629 700
      }
630 701
      for (typename ArcMaps::iterator it = _arc_maps.begin();
631 702
	   it != _arc_maps.end(); ++it) {
632 703
	_writer_bits::writeToken(*_os, it->first) << '\t';
633 704
      }
634 705
      *_os << std::endl;
635 706

	
636 707
      std::vector<Arc> arcs;
637 708
      for (ArcIt n(_digraph); n != INVALID; ++n) {
638 709
	arcs.push_back(n);
639 710
      }
640 711
      
641 712
      if (label == 0) {
642 713
	IdMap<Digraph, Arc> id_map(_digraph);
643 714
	_writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
644 715
	std::sort(arcs.begin(), arcs.end(), id_less);
645 716
      } else {
646 717
	label->sort(arcs);
647 718
      }
648 719

	
649 720
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
650 721
	Arc a = arcs[i];
651 722
	_writer_bits::writeToken(*_os, _node_index.
652 723
				 find(_digraph.source(a))->second);
653 724
	*_os << '\t';
654 725
	_writer_bits::writeToken(*_os, _node_index.
655 726
				 find(_digraph.target(a))->second);
656 727
	*_os << '\t';
657 728
	if (label == 0) {
658 729
	  std::ostringstream os;
659 730
	  os << _digraph.id(a);
660 731
	  _writer_bits::writeToken(*_os, os.str());
661 732
	  *_os << '\t';
662 733
	  _arc_index.insert(std::make_pair(a, os.str()));
663 734
	}
664 735
	for (typename ArcMaps::iterator it = _arc_maps.begin();
665 736
	     it != _arc_maps.end(); ++it) {
666 737
	  std::string value = it->second->get(a);
667 738
	  _writer_bits::writeToken(*_os, value);
668 739
	  if (it->first == "label") {
669 740
	    _arc_index.insert(std::make_pair(a, value));
670 741
	  }
671 742
	  *_os << '\t';
672 743
	}
673 744
	*_os << std::endl;
674 745
      }
675 746
    }
676 747

	
677 748
    void writeAttributes() {
678 749
      if (_attributes.empty()) return;
679 750
      *_os << "@attributes";
680 751
      if (!_attributes_caption.empty()) {
681 752
	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
682 753
      }
683 754
      *_os << std::endl;
684 755
      for (typename Attributes::iterator it = _attributes.begin();
685 756
	   it != _attributes.end(); ++it) {
686 757
	_writer_bits::writeToken(*_os, it->first) << ' ';
687 758
	_writer_bits::writeToken(*_os, it->second->get());
688 759
	*_os << std::endl;
689 760
      }
690 761
    }
691 762
    
692 763
  public:
693 764
    
694 765
    /// \name Execution of the writer    
695 766
    /// @{
696 767

	
697 768
    /// \brief Start the batch processing
698 769
    ///
699 770
    /// This function starts the batch processing
700 771
    void run() {
701 772
      if (!_skip_nodes) {
702 773
	writeNodes();
703 774
      }
704 775
      if (!_skip_arcs) {      
705 776
	writeArcs();
706 777
      }
707 778
      writeAttributes();
708 779
    }
709 780

	
710 781
    /// \brief Gives back the stream of the writer
711 782
    ///
712 783
    /// Gives back the stream of the writer
713 784
    std::ostream& ostream() {
714 785
      return *_os;
715 786
    }
716 787

	
717 788
    /// @}
718 789
  };
719 790

	
720 791
  /// \relates DigraphWriter
721 792
  template <typename Digraph>
722 793
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, Digraph& digraph) {
723 794
    DigraphWriter<Digraph> tmp(os, digraph);
724 795
    return tmp;
725 796
  }
726 797

	
727 798
  /// \relates DigraphWriter
728 799
  template <typename Digraph>
729 800
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
730 801
				       Digraph& digraph) {
731 802
    DigraphWriter<Digraph> tmp(fn, digraph);
732 803
    return tmp;
733 804
  }
734 805

	
735 806
  /// \relates DigraphWriter
736 807
  template <typename Digraph>
737 808
  DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
738 809
    DigraphWriter<Digraph> tmp(fn, digraph);
739 810
    return tmp;
740 811
  }
812

	
813
  /// \ingroup lemon_io
814
  ///  
815
  /// \brief LGF writer for directed graphs
816
  ///
817
  /// This utility writes an \ref lgf-format "LGF" file.
818
  template <typename _Graph>
819
  class GraphWriter {
820
  public:
821

	
822
    typedef _Graph Graph;
823
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
824
    
825
  private:
826

	
827

	
828
    std::ostream* _os;
829
    bool local_os;
830

	
831
    Graph& _graph;
832

	
833
    std::string _nodes_caption;
834
    std::string _edges_caption;
835
    std::string _attributes_caption;
836
    
837
    typedef std::map<Node, std::string> NodeIndex;
838
    NodeIndex _node_index;
839
    typedef std::map<Edge, std::string> EdgeIndex;
840
    EdgeIndex _edge_index;
841

	
842
    typedef std::vector<std::pair<std::string, 
843
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
844
    NodeMaps _node_maps; 
845

	
846
    typedef std::vector<std::pair<std::string, 
847
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
848
    EdgeMaps _edge_maps;
849

	
850
    typedef std::vector<std::pair<std::string, 
851
      _writer_bits::ValueStorageBase*> > Attributes;
852
    Attributes _attributes;
853

	
854
    bool _skip_nodes;
855
    bool _skip_edges;
856

	
857
  public:
858

	
859
    /// \brief Constructor
860
    ///
861
    /// Construct a directed graph writer, which writes to the given
862
    /// output stream.
863
    GraphWriter(std::ostream& is, Graph& graph) 
864
      : _os(&is), local_os(false), _graph(graph),
865
	_skip_nodes(false), _skip_edges(false) {}
866

	
867
    /// \brief Constructor
868
    ///
869
    /// Construct a directed graph writer, which writes to the given
870
    /// output file.
871
    GraphWriter(const std::string& fn, Graph& graph) 
872
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
873
	_skip_nodes(false), _skip_edges(false) {}
874

	
875
    /// \brief Constructor
876
    ///
877
    /// Construct a directed graph writer, which writes to the given
878
    /// output file.
879
    GraphWriter(const char* fn, Graph& graph) 
880
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
881
	_skip_nodes(false), _skip_edges(false) {}
882

	
883
    /// \brief Copy constructor
884
    ///
885
    /// The copy constructor transfers all data from the other writer,
886
    /// therefore the copied writer will not be usable more. 
887
    GraphWriter(GraphWriter& other) 
888
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
889
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
890

	
891
      other._os = 0;
892
      other.local_os = false;
893

	
894
      _node_index.swap(other._node_index);
895
      _edge_index.swap(other._edge_index);
896

	
897
      _node_maps.swap(other._node_maps);
898
      _edge_maps.swap(other._edge_maps);
899
      _attributes.swap(other._attributes);
900

	
901
      _nodes_caption = other._nodes_caption;
902
      _edges_caption = other._edges_caption;
903
      _attributes_caption = other._attributes_caption;
904
    }
905

	
906
    /// \brief Destructor
907
    ~GraphWriter() {
908
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
909
	   it != _node_maps.end(); ++it) {
910
	delete it->second;
911
      }
912

	
913
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
914
	   it != _edge_maps.end(); ++it) {
915
	delete it->second;
916
      }
917

	
918
      for (typename Attributes::iterator it = _attributes.begin(); 
919
	   it != _attributes.end(); ++it) {
920
	delete it->second;
921
      }
922

	
923
      if (local_os) {
924
	delete _os;
925
      }
926
    }
927

	
928
  private:
929
    
930
    GraphWriter& operator=(const GraphWriter&);
931

	
932
  public:
933

	
934
    /// \name Writing rules
935
    /// @{
936
    
937
    /// \brief Node map reading rule
938
    ///
939
    /// Add a node map reading rule to the writer.
940
    template <typename Map>
941
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
942
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
943
      _writer_bits::MapStorageBase<Node>* storage = 
944
	new _writer_bits::MapStorage<Node, Map>(map);
945
      _node_maps.push_back(std::make_pair(caption, storage));
946
      return *this;
947
    }
948

	
949
    /// \brief Node map writing rule
950
    ///
951
    /// Add a node map writing rule with specialized converter to the
952
    /// writer.
953
    template <typename Map, typename Converter>
954
    GraphWriter& nodeMap(const std::string& caption, const Map& map, 
955
			   const Converter& converter = Converter()) {
956
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
957
      _writer_bits::MapStorageBase<Node>* storage = 
958
	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
959
      _node_maps.push_back(std::make_pair(caption, storage));
960
      return *this;
961
    }
962

	
963
    /// \brief Edge map writing rule
964
    ///
965
    /// Add an edge map writing rule to the writer.
966
    template <typename Map>
967
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
968
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
969
      _writer_bits::MapStorageBase<Edge>* storage = 
970
	new _writer_bits::MapStorage<Edge, Map>(map);
971
      _edge_maps.push_back(std::make_pair(caption, storage));
972
      return *this;
973
    }
974

	
975
    /// \brief Edge map writing rule
976
    ///
977
    /// Add an edge map writing rule with specialized converter to the
978
    /// writer.
979
    template <typename Map, typename Converter>
980
    GraphWriter& edgeMap(const std::string& caption, const Map& map, 
981
			  const Converter& converter = Converter()) {
982
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
983
      _writer_bits::MapStorageBase<Edge>* storage = 
984
	new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
985
      _edge_maps.push_back(std::make_pair(caption, storage));
986
      return *this;
987
    }
988

	
989
    /// \brief Arc map writing rule
990
    ///
991
    /// Add an arc map writing rule to the writer.
992
    template <typename Map>
993
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
994
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
995
      _writer_bits::MapStorageBase<Edge>* forward_storage = 
996
	new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
997
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
998
      _writer_bits::MapStorageBase<Edge>* backward_storage = 
999
	new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1000
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1001
      return *this;
1002
    }
1003

	
1004
    /// \brief Arc map writing rule
1005
    ///
1006
    /// Add an arc map writing rule with specialized converter to the
1007
    /// writer.
1008
    template <typename Map, typename Converter>
1009
    GraphWriter& arcMap(const std::string& caption, const Map& map, 
1010
			  const Converter& converter = Converter()) {
1011
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1012
      _writer_bits::MapStorageBase<Edge>* forward_storage = 
1013
	new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1014
	(_graph, map, converter);
1015
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1016
      _writer_bits::MapStorageBase<Edge>* backward_storage = 
1017
	new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1018
	(_graph, map, converter);
1019
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1020
      return *this;
1021
    }
1022

	
1023
    /// \brief Attribute writing rule
1024
    ///
1025
    /// Add an attribute writing rule to the writer.
1026
    template <typename Value>
1027
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1028
      _writer_bits::ValueStorageBase* storage = 
1029
	new _writer_bits::ValueStorage<Value>(value);
1030
      _attributes.push_back(std::make_pair(caption, storage));
1031
      return *this;
1032
    }
1033

	
1034
    /// \brief Attribute writing rule
1035
    ///
1036
    /// Add an attribute writing rule with specialized converter to the
1037
    /// writer.
1038
    template <typename Value, typename Converter>
1039
    GraphWriter& attribute(const std::string& caption, const Value& value, 
1040
			     const Converter& converter = Converter()) {
1041
      _writer_bits::ValueStorageBase* storage = 
1042
	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1043
      _attributes.push_back(std::make_pair(caption, storage));
1044
      return *this;
1045
    }
1046

	
1047
    /// \brief Node writing rule
1048
    ///
1049
    /// Add a node writing rule to the writer.
1050
    GraphWriter& node(const std::string& caption, const Node& node) {
1051
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1052
      Converter converter(_node_index);
1053
      _writer_bits::ValueStorageBase* storage = 
1054
	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1055
      _attributes.push_back(std::make_pair(caption, storage));
1056
      return *this;
1057
    }
1058

	
1059
    /// \brief Edge writing rule
1060
    ///
1061
    /// Add an edge writing rule to writer.
1062
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1063
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1064
      Converter converter(_edge_index);
1065
      _writer_bits::ValueStorageBase* storage = 
1066
	new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1067
      _attributes.push_back(std::make_pair(caption, storage));
1068
      return *this;
1069
    }
1070

	
1071
    /// \brief Arc writing rule
1072
    ///
1073
    /// Add an arc writing rule to writer.
1074
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1075
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1076
      Converter converter(_graph, _edge_index);
1077
      _writer_bits::ValueStorageBase* storage = 
1078
	new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1079
      _attributes.push_back(std::make_pair(caption, storage));
1080
      return *this;
1081
    }
1082

	
1083
    /// \name Select section by name
1084
    /// @{
1085

	
1086
    /// \brief Set \c \@nodes section to be read
1087
    ///
1088
    /// Set \c \@nodes section to be read
1089
    GraphWriter& nodes(const std::string& caption) {
1090
      _nodes_caption = caption;
1091
      return *this;
1092
    }
1093

	
1094
    /// \brief Set \c \@edges section to be read
1095
    ///
1096
    /// Set \c \@edges section to be read
1097
    GraphWriter& edges(const std::string& caption) {
1098
      _edges_caption = caption;
1099
      return *this;
1100
    }
1101

	
1102
    /// \brief Set \c \@attributes section to be read
1103
    ///
1104
    /// Set \c \@attributes section to be read
1105
    GraphWriter& attributes(const std::string& caption) {
1106
      _attributes_caption = caption;
1107
      return *this;
1108
    }
1109

	
1110
    /// \name Skipping section
1111
    /// @{
1112

	
1113
    /// \brief Skip writing the node set
1114
    ///
1115
    /// The \c \@nodes section will be not written to the stream.
1116
    GraphWriter& skipNodes() {
1117
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1118
      return *this;
1119
    }
1120

	
1121
    /// \brief Skip writing edge set
1122
    ///
1123
    /// The \c \@edges section will be not written to the stream.
1124
    GraphWriter& skipEdges() {
1125
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1126
      return *this;
1127
    }
1128

	
1129
    /// @}
1130

	
1131
  private:
1132

	
1133
    void writeNodes() {
1134
      _writer_bits::MapStorageBase<Node>* label = 0;
1135
      for (typename NodeMaps::iterator it = _node_maps.begin();
1136
	   it != _node_maps.end(); ++it) {
1137
        if (it->first == "label") {
1138
	  label = it->second;
1139
	  break;
1140
	}
1141
      }
1142

	
1143
      *_os << "@nodes";
1144
      if (!_nodes_caption.empty()) {
1145
	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
1146
      }
1147
      *_os << std::endl;
1148

	
1149
      if (label == 0) {
1150
	*_os << "label" << '\t';
1151
      }
1152
      for (typename NodeMaps::iterator it = _node_maps.begin();
1153
	   it != _node_maps.end(); ++it) {
1154
	_writer_bits::writeToken(*_os, it->first) << '\t';
1155
      }
1156
      *_os << std::endl;
1157

	
1158
      std::vector<Node> nodes;
1159
      for (NodeIt n(_graph); n != INVALID; ++n) {
1160
	nodes.push_back(n);
1161
      }
1162
      
1163
      if (label == 0) {
1164
	IdMap<Graph, Node> id_map(_graph);
1165
	_writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1166
	std::sort(nodes.begin(), nodes.end(), id_less);
1167
      } else {
1168
	label->sort(nodes);
1169
      }
1170

	
1171
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1172
	Node n = nodes[i];
1173
	if (label == 0) {
1174
	  std::ostringstream os;
1175
	  os << _graph.id(n);
1176
	  _writer_bits::writeToken(*_os, os.str());
1177
	  *_os << '\t';
1178
	  _node_index.insert(std::make_pair(n, os.str()));
1179
	}
1180
	for (typename NodeMaps::iterator it = _node_maps.begin();
1181
	     it != _node_maps.end(); ++it) {
1182
	  std::string value = it->second->get(n);
1183
	  _writer_bits::writeToken(*_os, value);
1184
	  if (it->first == "label") {
1185
	    _node_index.insert(std::make_pair(n, value));
1186
	  }
1187
	  *_os << '\t';
1188
	}
1189
	*_os << std::endl;
1190
      }
1191
    }
1192

	
1193
    void writeEdges() {
1194
      _writer_bits::MapStorageBase<Edge>* label = 0;
1195
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1196
	   it != _edge_maps.end(); ++it) {
1197
        if (it->first == "label") {
1198
	  label = it->second;
1199
	  break;
1200
	}
1201
      }
1202

	
1203
      *_os << "@edges";
1204
      if (!_edges_caption.empty()) {
1205
	_writer_bits::writeToken(*_os << ' ', _edges_caption);
1206
      }
1207
      *_os << std::endl;
1208

	
1209
      *_os << '\t' << '\t';
1210
      if (label == 0) {
1211
	*_os << "label" << '\t';
1212
      }
1213
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1214
	   it != _edge_maps.end(); ++it) {
1215
	_writer_bits::writeToken(*_os, it->first) << '\t';
1216
      }
1217
      *_os << std::endl;
1218

	
1219
      std::vector<Edge> edges;
1220
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1221
	edges.push_back(n);
1222
      }
1223
      
1224
      if (label == 0) {
1225
	IdMap<Graph, Edge> id_map(_graph);
1226
	_writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1227
	std::sort(edges.begin(), edges.end(), id_less);
1228
      } else {
1229
	label->sort(edges);
1230
      }
1231

	
1232
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1233
	Edge e = edges[i];
1234
	_writer_bits::writeToken(*_os, _node_index.
1235
				 find(_graph.u(e))->second);
1236
	*_os << '\t';
1237
	_writer_bits::writeToken(*_os, _node_index.
1238
				 find(_graph.v(e))->second);
1239
	*_os << '\t';
1240
	if (label == 0) {
1241
	  std::ostringstream os;
1242
	  os << _graph.id(e);
1243
	  _writer_bits::writeToken(*_os, os.str());
1244
	  *_os << '\t';
1245
	  _edge_index.insert(std::make_pair(e, os.str()));
1246
	}
1247
	for (typename EdgeMaps::iterator it = _edge_maps.begin();
1248
	     it != _edge_maps.end(); ++it) {
1249
	  std::string value = it->second->get(e);
1250
	  _writer_bits::writeToken(*_os, value);
1251
	  if (it->first == "label") {
1252
	    _edge_index.insert(std::make_pair(e, value));
1253
	  }
1254
	  *_os << '\t';
1255
	}
1256
	*_os << std::endl;
1257
      }
1258
    }
1259

	
1260
    void writeAttributes() {
1261
      if (_attributes.empty()) return;
1262
      *_os << "@attributes";
1263
      if (!_attributes_caption.empty()) {
1264
	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
1265
      }
1266
      *_os << std::endl;
1267
      for (typename Attributes::iterator it = _attributes.begin();
1268
	   it != _attributes.end(); ++it) {
1269
	_writer_bits::writeToken(*_os, it->first) << ' ';
1270
	_writer_bits::writeToken(*_os, it->second->get());
1271
	*_os << std::endl;
1272
      }
1273
    }
1274
    
1275
  public:
1276
    
1277
    /// \name Execution of the writer    
1278
    /// @{
1279

	
1280
    /// \brief Start the batch processing
1281
    ///
1282
    /// This function starts the batch processing
1283
    void run() {
1284
      if (!_skip_nodes) {
1285
	writeNodes();
1286
      }
1287
      if (!_skip_edges) {      
1288
	writeEdges();
1289
      }
1290
      writeAttributes();
1291
    }
1292

	
1293
    /// \brief Gives back the stream of the writer
1294
    ///
1295
    /// Gives back the stream of the writer
1296
    std::ostream& ostream() {
1297
      return *_os;
1298
    }
1299

	
1300
    /// @}
1301
  };
1302

	
1303
  /// \relates GraphWriter
1304
  template <typename Graph>
1305
  GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) {
1306
    GraphWriter<Graph> tmp(os, graph);
1307
    return tmp;
1308
  }
1309

	
1310
  /// \relates GraphWriter
1311
  template <typename Graph>
1312
  GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) {
1313
    GraphWriter<Graph> tmp(fn, graph);
1314
    return tmp;
1315
  }
1316

	
1317
  /// \relates GraphWriter
1318
  template <typename Graph>
1319
  GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) {
1320
    GraphWriter<Graph> tmp(fn, graph);
1321
    return tmp;
1322
  }
741 1323
}
742 1324

	
743 1325
#endif
0 comments (0 inline)