103 |
103 |
104 virtual std::string get(const Item& item) = 0; |
104 virtual std::string get(const Item& item) = 0; |
105 virtual void sort(std::vector<Item>&) = 0; |
105 virtual void sort(std::vector<Item>&) = 0; |
106 }; |
106 }; |
107 |
107 |
108 template <typename _Item, typename _Map, |
108 template <typename _Item, typename _Map, |
109 typename _Converter = DefaultConverter<typename _Map::Value> > |
109 typename _Converter = DefaultConverter<typename _Map::Value> > |
110 class MapStorage : public MapStorageBase<_Item> { |
110 class MapStorage : public MapStorageBase<_Item> { |
111 public: |
111 public: |
112 typedef _Map Map; |
112 typedef _Map Map; |
113 typedef _Converter Converter; |
113 typedef _Converter Converter; |
114 typedef _Item Item; |
114 typedef _Item Item; |
115 |
115 |
116 private: |
116 private: |
117 const Map& _map; |
117 const Map& _map; |
118 Converter _converter; |
118 Converter _converter; |
119 |
119 |
120 public: |
120 public: |
121 MapStorage(const Map& map, const Converter& converter = Converter()) |
121 MapStorage(const Map& map, const Converter& converter = Converter()) |
122 : _map(map), _converter(converter) {} |
122 : _map(map), _converter(converter) {} |
123 virtual ~MapStorage() {} |
123 virtual ~MapStorage() {} |
124 |
124 |
125 virtual std::string get(const Item& item) { |
125 virtual std::string get(const Item& item) { |
126 return _converter(_map[item]); |
126 return _converter(_map[item]); |
127 } |
127 } |
128 virtual void sort(std::vector<Item>& items) { |
128 virtual void sort(std::vector<Item>& items) { |
129 MapLess<Map> less(_map); |
129 MapLess<Map> less(_map); |
130 std::sort(items.begin(), items.end(), less); |
130 std::sort(items.begin(), items.end(), less); |
131 } |
131 } |
132 }; |
132 }; |
133 |
133 |
134 template <typename _Graph, bool _dir, typename _Map, |
134 template <typename _Graph, bool _dir, typename _Map, |
135 typename _Converter = DefaultConverter<typename _Map::Value> > |
135 typename _Converter = DefaultConverter<typename _Map::Value> > |
136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { |
136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { |
137 public: |
137 public: |
138 typedef _Map Map; |
138 typedef _Map Map; |
139 typedef _Converter Converter; |
139 typedef _Converter Converter; |
140 typedef _Graph Graph; |
140 typedef _Graph Graph; |
141 typedef typename Graph::Edge Item; |
141 typedef typename Graph::Edge Item; |
142 static const bool dir = _dir; |
142 static const bool dir = _dir; |
143 |
143 |
144 private: |
144 private: |
145 const Graph& _graph; |
145 const Graph& _graph; |
146 const Map& _map; |
146 const Map& _map; |
147 Converter _converter; |
147 Converter _converter; |
148 |
148 |
149 public: |
149 public: |
150 GraphArcMapStorage(const Graph& graph, const Map& map, |
150 GraphArcMapStorage(const Graph& graph, const Map& map, |
151 const Converter& converter = Converter()) |
151 const Converter& converter = Converter()) |
152 : _graph(graph), _map(map), _converter(converter) {} |
152 : _graph(graph), _map(map), _converter(converter) {} |
153 virtual ~GraphArcMapStorage() {} |
153 virtual ~GraphArcMapStorage() {} |
154 |
154 |
155 virtual std::string get(const Item& item) { |
155 virtual std::string get(const Item& item) { |
156 return _converter(_map[_graph.direct(item, dir)]); |
156 return _converter(_map[_graph.direct(item, dir)]); |
157 } |
157 } |
158 virtual void sort(std::vector<Item>& items) { |
158 virtual void sort(std::vector<Item>& items) { |
159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map); |
159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map); |
160 std::sort(items.begin(), items.end(), less); |
160 std::sort(items.begin(), items.end(), less); |
161 } |
161 } |
162 }; |
162 }; |
163 |
163 |
164 class ValueStorageBase { |
164 class ValueStorageBase { |
165 public: |
165 public: |
166 ValueStorageBase() {} |
166 ValueStorageBase() {} |
167 virtual ~ValueStorageBase() {} |
167 virtual ~ValueStorageBase() {} |
168 |
168 |
169 virtual std::string get() = 0; |
169 virtual std::string get() = 0; |
170 }; |
170 }; |
171 |
171 |
172 template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
172 template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
173 class ValueStorage : public ValueStorageBase { |
173 class ValueStorage : public ValueStorageBase { |
174 public: |
174 public: |
179 const Value& _value; |
179 const Value& _value; |
180 Converter _converter; |
180 Converter _converter; |
181 |
181 |
182 public: |
182 public: |
183 ValueStorage(const Value& value, const Converter& converter = Converter()) |
183 ValueStorage(const Value& value, const Converter& converter = Converter()) |
184 : _value(value), _converter(converter) {} |
184 : _value(value), _converter(converter) {} |
185 |
185 |
186 virtual std::string get() { |
186 virtual std::string get() { |
187 return _converter(_value); |
187 return _converter(_value); |
188 } |
188 } |
189 }; |
189 }; |
190 |
190 |
191 template <typename Value> |
191 template <typename Value> |
192 struct MapLookUpConverter { |
192 struct MapLookUpConverter { |
193 const std::map<Value, std::string>& _map; |
193 const std::map<Value, std::string>& _map; |
194 |
194 |
195 MapLookUpConverter(const std::map<Value, std::string>& map) |
195 MapLookUpConverter(const std::map<Value, std::string>& map) |
196 : _map(map) {} |
196 : _map(map) {} |
197 |
197 |
198 std::string operator()(const Value& str) { |
198 std::string operator()(const Value& str) { |
199 typename std::map<Value, std::string>::const_iterator it = |
199 typename std::map<Value, std::string>::const_iterator it = |
200 _map.find(str); |
200 _map.find(str); |
201 if (it == _map.end()) { |
201 if (it == _map.end()) { |
202 throw DataFormatError("Item not found"); |
202 throw DataFormatError("Item not found"); |
203 } |
203 } |
204 return it->second; |
204 return it->second; |
205 } |
205 } |
206 }; |
206 }; |
207 |
207 |
208 template <typename Graph> |
208 template <typename Graph> |
209 struct GraphArcLookUpConverter { |
209 struct GraphArcLookUpConverter { |
210 const Graph& _graph; |
210 const Graph& _graph; |
211 const std::map<typename Graph::Edge, std::string>& _map; |
211 const std::map<typename Graph::Edge, std::string>& _map; |
212 |
212 |
213 GraphArcLookUpConverter(const Graph& graph, |
213 GraphArcLookUpConverter(const Graph& graph, |
214 const std::map<typename Graph::Edge, |
214 const std::map<typename Graph::Edge, |
215 std::string>& map) |
215 std::string>& map) |
216 : _graph(graph), _map(map) {} |
216 : _graph(graph), _map(map) {} |
217 |
217 |
218 std::string operator()(const typename Graph::Arc& val) { |
218 std::string operator()(const typename Graph::Arc& val) { |
219 typename std::map<typename Graph::Edge, std::string> |
219 typename std::map<typename Graph::Edge, std::string> |
220 ::const_iterator it = _map.find(val); |
220 ::const_iterator it = _map.find(val); |
221 if (it == _map.end()) { |
221 if (it == _map.end()) { |
222 throw DataFormatError("Item not found"); |
222 throw DataFormatError("Item not found"); |
223 } |
223 } |
224 return (_graph.direction(val) ? '+' : '-') + it->second; |
224 return (_graph.direction(val) ? '+' : '-') + it->second; |
225 } |
225 } |
226 }; |
226 }; |
227 |
227 |
228 inline bool isWhiteSpace(char c) { |
228 inline bool isWhiteSpace(char c) { |
229 return c == ' ' || c == '\t' || c == '\v' || |
229 return c == ' ' || c == '\t' || c == '\v' || |
230 c == '\n' || c == '\r' || c == '\f'; |
230 c == '\n' || c == '\r' || c == '\f'; |
231 } |
231 } |
232 |
232 |
233 inline bool isEscaped(char c) { |
233 inline bool isEscaped(char c) { |
234 return c == '\\' || c == '\"' || c == '\'' || |
234 return c == '\\' || c == '\"' || c == '\'' || |
235 c == '\a' || c == '\b'; |
235 c == '\a' || c == '\b'; |
236 } |
236 } |
237 |
237 |
238 inline static void writeEscape(std::ostream& os, char c) { |
238 inline static void writeEscape(std::ostream& os, char c) { |
239 switch (c) { |
239 switch (c) { |
240 case '\\': |
240 case '\\': |
241 os << "\\\\"; |
241 os << "\\\\"; |
242 return; |
242 return; |
243 case '\"': |
243 case '\"': |
244 os << "\\\""; |
244 os << "\\\""; |
245 return; |
245 return; |
246 case '\a': |
246 case '\a': |
247 os << "\\a"; |
247 os << "\\a"; |
248 return; |
248 return; |
249 case '\b': |
249 case '\b': |
250 os << "\\b"; |
250 os << "\\b"; |
251 return; |
251 return; |
252 case '\f': |
252 case '\f': |
253 os << "\\f"; |
253 os << "\\f"; |
254 return; |
254 return; |
255 case '\r': |
255 case '\r': |
256 os << "\\r"; |
256 os << "\\r"; |
257 return; |
257 return; |
258 case '\n': |
258 case '\n': |
259 os << "\\n"; |
259 os << "\\n"; |
260 return; |
260 return; |
261 case '\t': |
261 case '\t': |
262 os << "\\t"; |
262 os << "\\t"; |
263 return; |
263 return; |
264 case '\v': |
264 case '\v': |
265 os << "\\v"; |
265 os << "\\v"; |
266 return; |
266 return; |
267 default: |
267 default: |
268 if (c < 0x20) { |
268 if (c < 0x20) { |
269 std::ios::fmtflags flags = os.flags(); |
269 std::ios::fmtflags flags = os.flags(); |
270 os << '\\' << std::oct << static_cast<int>(c); |
270 os << '\\' << std::oct << static_cast<int>(c); |
271 os.flags(flags); |
271 os.flags(flags); |
272 } else { |
272 } else { |
273 os << c; |
273 os << c; |
274 } |
274 } |
275 return; |
275 return; |
276 } |
276 } |
277 } |
277 } |
278 |
278 |
279 inline bool requireEscape(const std::string& str) { |
279 inline bool requireEscape(const std::string& str) { |
280 if (str.empty() || str[0] == '@') return true; |
280 if (str.empty() || str[0] == '@') return true; |
281 std::istringstream is(str); |
281 std::istringstream is(str); |
282 char c; |
282 char c; |
283 while (is.get(c)) { |
283 while (is.get(c)) { |
284 if (isWhiteSpace(c) || isEscaped(c)) { |
284 if (isWhiteSpace(c) || isEscaped(c)) { |
285 return true; |
285 return true; |
286 } |
286 } |
287 } |
287 } |
288 return false; |
288 return false; |
289 } |
289 } |
290 |
290 |
291 inline std::ostream& writeToken(std::ostream& os, const std::string& str) { |
291 inline std::ostream& writeToken(std::ostream& os, const std::string& str) { |
292 |
292 |
293 if (requireEscape(str)) { |
293 if (requireEscape(str)) { |
294 os << '\"'; |
294 os << '\"'; |
295 for (std::string::const_iterator it = str.begin(); |
295 for (std::string::const_iterator it = str.begin(); |
296 it != str.end(); ++it) { |
296 it != str.end(); ++it) { |
297 writeEscape(os, *it); |
297 writeEscape(os, *it); |
298 } |
298 } |
299 os << '\"'; |
299 os << '\"'; |
300 } else { |
300 } else { |
301 os << str; |
301 os << str; |
302 } |
302 } |
303 return os; |
303 return os; |
304 } |
304 } |
305 |
305 |
306 } |
306 } |
307 |
307 |
308 template <typename Digraph> |
308 template <typename Digraph> |
309 class DigraphWriter; |
309 class DigraphWriter; |
310 |
310 |
311 template <typename Digraph> |
311 template <typename Digraph> |
312 DigraphWriter<Digraph> digraphWriter(std::ostream& os, |
312 DigraphWriter<Digraph> digraphWriter(std::ostream& os, |
313 const Digraph& digraph); |
313 const Digraph& digraph); |
314 |
314 |
315 template <typename Digraph> |
315 template <typename Digraph> |
316 DigraphWriter<Digraph> digraphWriter(const std::string& fn, |
316 DigraphWriter<Digraph> digraphWriter(const std::string& fn, |
317 const Digraph& digraph); |
317 const Digraph& digraph); |
318 |
318 |
319 template <typename Digraph> |
319 template <typename Digraph> |
320 DigraphWriter<Digraph> digraphWriter(const char *fn, |
320 DigraphWriter<Digraph> digraphWriter(const char *fn, |
321 const Digraph& digraph); |
321 const Digraph& digraph); |
322 |
322 |
323 /// \ingroup lemon_io |
323 /// \ingroup lemon_io |
324 /// |
324 /// |
325 /// \brief \ref lgf-format "LGF" writer for directed graphs |
325 /// \brief \ref lgf-format "LGF" writer for directed graphs |
326 /// |
326 /// |
327 /// This utility writes an \ref lgf-format "LGF" file. |
327 /// This utility writes an \ref lgf-format "LGF" file. |
328 /// |
328 /// |
329 /// The writing method does a batch processing. The user creates a |
329 /// The writing method does a batch processing. The user creates a |
407 |
407 |
408 /// \brief Constructor |
408 /// \brief Constructor |
409 /// |
409 /// |
410 /// Construct a directed graph writer, which writes to the given |
410 /// Construct a directed graph writer, which writes to the given |
411 /// output stream. |
411 /// output stream. |
412 DigraphWriter(std::ostream& is, const Digraph& digraph) |
412 DigraphWriter(std::ostream& is, const Digraph& digraph) |
413 : _os(&is), local_os(false), _digraph(digraph), |
413 : _os(&is), local_os(false), _digraph(digraph), |
414 _skip_nodes(false), _skip_arcs(false) {} |
414 _skip_nodes(false), _skip_arcs(false) {} |
415 |
415 |
416 /// \brief Constructor |
416 /// \brief Constructor |
417 /// |
417 /// |
418 /// Construct a directed graph writer, which writes to the given |
418 /// Construct a directed graph writer, which writes to the given |
419 /// output file. |
419 /// output file. |
420 DigraphWriter(const std::string& fn, const Digraph& digraph) |
420 DigraphWriter(const std::string& fn, const Digraph& digraph) |
421 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph), |
421 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph), |
422 _skip_nodes(false), _skip_arcs(false) {} |
422 _skip_nodes(false), _skip_arcs(false) {} |
423 |
423 |
424 /// \brief Constructor |
424 /// \brief Constructor |
425 /// |
425 /// |
426 /// Construct a directed graph writer, which writes to the given |
426 /// Construct a directed graph writer, which writes to the given |
427 /// output file. |
427 /// output file. |
428 DigraphWriter(const char* fn, const Digraph& digraph) |
428 DigraphWriter(const char* fn, const Digraph& digraph) |
429 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph), |
429 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph), |
430 _skip_nodes(false), _skip_arcs(false) {} |
430 _skip_nodes(false), _skip_arcs(false) {} |
431 |
431 |
432 /// \brief Destructor |
432 /// \brief Destructor |
433 ~DigraphWriter() { |
433 ~DigraphWriter() { |
434 for (typename NodeMaps::iterator it = _node_maps.begin(); |
434 for (typename NodeMaps::iterator it = _node_maps.begin(); |
435 it != _node_maps.end(); ++it) { |
435 it != _node_maps.end(); ++it) { |
436 delete it->second; |
436 delete it->second; |
437 } |
437 } |
438 |
438 |
439 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
439 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
440 it != _arc_maps.end(); ++it) { |
440 it != _arc_maps.end(); ++it) { |
441 delete it->second; |
441 delete it->second; |
442 } |
442 } |
443 |
443 |
444 for (typename Attributes::iterator it = _attributes.begin(); |
444 for (typename Attributes::iterator it = _attributes.begin(); |
445 it != _attributes.end(); ++it) { |
445 it != _attributes.end(); ++it) { |
446 delete it->second; |
446 delete it->second; |
447 } |
447 } |
448 |
448 |
449 if (local_os) { |
449 if (local_os) { |
450 delete _os; |
450 delete _os; |
451 } |
451 } |
452 } |
452 } |
453 |
453 |
454 private: |
454 private: |
455 |
455 |
456 friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os, |
456 friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os, |
457 const Digraph& digraph); |
457 const Digraph& digraph); |
458 friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn, |
458 friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn, |
459 const Digraph& digraph); |
459 const Digraph& digraph); |
460 friend DigraphWriter<Digraph> digraphWriter<>(const char *fn, |
460 friend DigraphWriter<Digraph> digraphWriter<>(const char *fn, |
461 const Digraph& digraph); |
461 const Digraph& digraph); |
462 |
462 |
463 DigraphWriter(DigraphWriter& other) |
463 DigraphWriter(DigraphWriter& other) |
464 : _os(other._os), local_os(other.local_os), _digraph(other._digraph), |
464 : _os(other._os), local_os(other.local_os), _digraph(other._digraph), |
465 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) { |
465 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) { |
466 |
466 |
467 other._os = 0; |
467 other._os = 0; |
468 other.local_os = false; |
468 other.local_os = false; |
469 |
469 |
470 _node_index.swap(other._node_index); |
470 _node_index.swap(other._node_index); |
476 |
476 |
477 _nodes_caption = other._nodes_caption; |
477 _nodes_caption = other._nodes_caption; |
478 _arcs_caption = other._arcs_caption; |
478 _arcs_caption = other._arcs_caption; |
479 _attributes_caption = other._attributes_caption; |
479 _attributes_caption = other._attributes_caption; |
480 } |
480 } |
481 |
481 |
482 DigraphWriter& operator=(const DigraphWriter&); |
482 DigraphWriter& operator=(const DigraphWriter&); |
483 |
483 |
484 public: |
484 public: |
485 |
485 |
486 /// \name Writing rules |
486 /// \name Writing rules |
487 /// @{ |
487 /// @{ |
488 |
488 |
489 /// \brief Node map writing rule |
489 /// \brief Node map writing rule |
490 /// |
490 /// |
491 /// Add a node map writing rule to the writer. |
491 /// Add a node map writing rule to the writer. |
492 template <typename Map> |
492 template <typename Map> |
493 DigraphWriter& nodeMap(const std::string& caption, const Map& map) { |
493 DigraphWriter& nodeMap(const std::string& caption, const Map& map) { |
494 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
494 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
495 _writer_bits::MapStorageBase<Node>* storage = |
495 _writer_bits::MapStorageBase<Node>* storage = |
496 new _writer_bits::MapStorage<Node, Map>(map); |
496 new _writer_bits::MapStorage<Node, Map>(map); |
497 _node_maps.push_back(std::make_pair(caption, storage)); |
497 _node_maps.push_back(std::make_pair(caption, storage)); |
498 return *this; |
498 return *this; |
499 } |
499 } |
500 |
500 |
501 /// \brief Node map writing rule |
501 /// \brief Node map writing rule |
502 /// |
502 /// |
503 /// Add a node map writing rule with specialized converter to the |
503 /// Add a node map writing rule with specialized converter to the |
504 /// writer. |
504 /// writer. |
505 template <typename Map, typename Converter> |
505 template <typename Map, typename Converter> |
506 DigraphWriter& nodeMap(const std::string& caption, const Map& map, |
506 DigraphWriter& nodeMap(const std::string& caption, const Map& map, |
507 const Converter& converter = Converter()) { |
507 const Converter& converter = Converter()) { |
508 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
508 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
509 _writer_bits::MapStorageBase<Node>* storage = |
509 _writer_bits::MapStorageBase<Node>* storage = |
510 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
510 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
511 _node_maps.push_back(std::make_pair(caption, storage)); |
511 _node_maps.push_back(std::make_pair(caption, storage)); |
512 return *this; |
512 return *this; |
513 } |
513 } |
514 |
514 |
515 /// \brief Arc map writing rule |
515 /// \brief Arc map writing rule |
516 /// |
516 /// |
517 /// Add an arc map writing rule to the writer. |
517 /// Add an arc map writing rule to the writer. |
518 template <typename Map> |
518 template <typename Map> |
519 DigraphWriter& arcMap(const std::string& caption, const Map& map) { |
519 DigraphWriter& arcMap(const std::string& caption, const Map& map) { |
520 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
520 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
521 _writer_bits::MapStorageBase<Arc>* storage = |
521 _writer_bits::MapStorageBase<Arc>* storage = |
522 new _writer_bits::MapStorage<Arc, Map>(map); |
522 new _writer_bits::MapStorage<Arc, Map>(map); |
523 _arc_maps.push_back(std::make_pair(caption, storage)); |
523 _arc_maps.push_back(std::make_pair(caption, storage)); |
524 return *this; |
524 return *this; |
525 } |
525 } |
526 |
526 |
527 /// \brief Arc map writing rule |
527 /// \brief Arc map writing rule |
528 /// |
528 /// |
529 /// Add an arc map writing rule with specialized converter to the |
529 /// Add an arc map writing rule with specialized converter to the |
530 /// writer. |
530 /// writer. |
531 template <typename Map, typename Converter> |
531 template <typename Map, typename Converter> |
532 DigraphWriter& arcMap(const std::string& caption, const Map& map, |
532 DigraphWriter& arcMap(const std::string& caption, const Map& map, |
533 const Converter& converter = Converter()) { |
533 const Converter& converter = Converter()) { |
534 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
534 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
535 _writer_bits::MapStorageBase<Arc>* storage = |
535 _writer_bits::MapStorageBase<Arc>* storage = |
536 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter); |
536 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter); |
537 _arc_maps.push_back(std::make_pair(caption, storage)); |
537 _arc_maps.push_back(std::make_pair(caption, storage)); |
538 return *this; |
538 return *this; |
539 } |
539 } |
540 |
540 |
541 /// \brief Attribute writing rule |
541 /// \brief Attribute writing rule |
542 /// |
542 /// |
543 /// Add an attribute writing rule to the writer. |
543 /// Add an attribute writing rule to the writer. |
544 template <typename Value> |
544 template <typename Value> |
545 DigraphWriter& attribute(const std::string& caption, const Value& value) { |
545 DigraphWriter& attribute(const std::string& caption, const Value& value) { |
546 _writer_bits::ValueStorageBase* storage = |
546 _writer_bits::ValueStorageBase* storage = |
547 new _writer_bits::ValueStorage<Value>(value); |
547 new _writer_bits::ValueStorage<Value>(value); |
548 _attributes.push_back(std::make_pair(caption, storage)); |
548 _attributes.push_back(std::make_pair(caption, storage)); |
549 return *this; |
549 return *this; |
550 } |
550 } |
551 |
551 |
552 /// \brief Attribute writing rule |
552 /// \brief Attribute writing rule |
553 /// |
553 /// |
554 /// Add an attribute writing rule with specialized converter to the |
554 /// Add an attribute writing rule with specialized converter to the |
555 /// writer. |
555 /// writer. |
556 template <typename Value, typename Converter> |
556 template <typename Value, typename Converter> |
557 DigraphWriter& attribute(const std::string& caption, const Value& value, |
557 DigraphWriter& attribute(const std::string& caption, const Value& value, |
558 const Converter& converter = Converter()) { |
558 const Converter& converter = Converter()) { |
559 _writer_bits::ValueStorageBase* storage = |
559 _writer_bits::ValueStorageBase* storage = |
560 new _writer_bits::ValueStorage<Value, Converter>(value, converter); |
560 new _writer_bits::ValueStorage<Value, Converter>(value, converter); |
561 _attributes.push_back(std::make_pair(caption, storage)); |
561 _attributes.push_back(std::make_pair(caption, storage)); |
562 return *this; |
562 return *this; |
563 } |
563 } |
564 |
564 |
565 /// \brief Node writing rule |
565 /// \brief Node writing rule |
566 /// |
566 /// |
567 /// Add a node writing rule to the writer. |
567 /// Add a node writing rule to the writer. |
568 DigraphWriter& node(const std::string& caption, const Node& node) { |
568 DigraphWriter& node(const std::string& caption, const Node& node) { |
569 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
569 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
570 Converter converter(_node_index); |
570 Converter converter(_node_index); |
571 _writer_bits::ValueStorageBase* storage = |
571 _writer_bits::ValueStorageBase* storage = |
572 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
572 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
573 _attributes.push_back(std::make_pair(caption, storage)); |
573 _attributes.push_back(std::make_pair(caption, storage)); |
574 return *this; |
574 return *this; |
575 } |
575 } |
576 |
576 |
577 /// \brief Arc writing rule |
577 /// \brief Arc writing rule |
578 /// |
578 /// |
579 /// Add an arc writing rule to writer. |
579 /// Add an arc writing rule to writer. |
580 DigraphWriter& arc(const std::string& caption, const Arc& arc) { |
580 DigraphWriter& arc(const std::string& caption, const Arc& arc) { |
581 typedef _writer_bits::MapLookUpConverter<Arc> Converter; |
581 typedef _writer_bits::MapLookUpConverter<Arc> Converter; |
582 Converter converter(_arc_index); |
582 Converter converter(_arc_index); |
583 _writer_bits::ValueStorageBase* storage = |
583 _writer_bits::ValueStorageBase* storage = |
584 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); |
584 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); |
585 _attributes.push_back(std::make_pair(caption, storage)); |
585 _attributes.push_back(std::make_pair(caption, storage)); |
586 return *this; |
586 return *this; |
587 } |
587 } |
588 |
588 |
589 /// \name Section captions |
589 /// \name Section captions |
639 private: |
639 private: |
640 |
640 |
641 void writeNodes() { |
641 void writeNodes() { |
642 _writer_bits::MapStorageBase<Node>* label = 0; |
642 _writer_bits::MapStorageBase<Node>* label = 0; |
643 for (typename NodeMaps::iterator it = _node_maps.begin(); |
643 for (typename NodeMaps::iterator it = _node_maps.begin(); |
644 it != _node_maps.end(); ++it) { |
644 it != _node_maps.end(); ++it) { |
645 if (it->first == "label") { |
645 if (it->first == "label") { |
646 label = it->second; |
646 label = it->second; |
647 break; |
647 break; |
648 } |
648 } |
649 } |
649 } |
650 |
650 |
651 *_os << "@nodes"; |
651 *_os << "@nodes"; |
652 if (!_nodes_caption.empty()) { |
652 if (!_nodes_caption.empty()) { |
653 _writer_bits::writeToken(*_os << ' ', _nodes_caption); |
653 _writer_bits::writeToken(*_os << ' ', _nodes_caption); |
654 } |
654 } |
655 *_os << std::endl; |
655 *_os << std::endl; |
656 |
656 |
657 if (label == 0) { |
657 if (label == 0) { |
658 *_os << "label" << '\t'; |
658 *_os << "label" << '\t'; |
659 } |
659 } |
660 for (typename NodeMaps::iterator it = _node_maps.begin(); |
660 for (typename NodeMaps::iterator it = _node_maps.begin(); |
661 it != _node_maps.end(); ++it) { |
661 it != _node_maps.end(); ++it) { |
662 _writer_bits::writeToken(*_os, it->first) << '\t'; |
662 _writer_bits::writeToken(*_os, it->first) << '\t'; |
663 } |
663 } |
664 *_os << std::endl; |
664 *_os << std::endl; |
665 |
665 |
666 std::vector<Node> nodes; |
666 std::vector<Node> nodes; |
667 for (NodeIt n(_digraph); n != INVALID; ++n) { |
667 for (NodeIt n(_digraph); n != INVALID; ++n) { |
668 nodes.push_back(n); |
668 nodes.push_back(n); |
669 } |
669 } |
670 |
670 |
671 if (label == 0) { |
671 if (label == 0) { |
672 IdMap<Digraph, Node> id_map(_digraph); |
672 IdMap<Digraph, Node> id_map(_digraph); |
673 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map); |
673 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map); |
674 std::sort(nodes.begin(), nodes.end(), id_less); |
674 std::sort(nodes.begin(), nodes.end(), id_less); |
675 } else { |
675 } else { |
676 label->sort(nodes); |
676 label->sort(nodes); |
677 } |
677 } |
678 |
678 |
679 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
679 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
680 Node n = nodes[i]; |
680 Node n = nodes[i]; |
681 if (label == 0) { |
681 if (label == 0) { |
682 std::ostringstream os; |
682 std::ostringstream os; |
683 os << _digraph.id(n); |
683 os << _digraph.id(n); |
684 _writer_bits::writeToken(*_os, os.str()); |
684 _writer_bits::writeToken(*_os, os.str()); |
685 *_os << '\t'; |
685 *_os << '\t'; |
686 _node_index.insert(std::make_pair(n, os.str())); |
686 _node_index.insert(std::make_pair(n, os.str())); |
687 } |
687 } |
688 for (typename NodeMaps::iterator it = _node_maps.begin(); |
688 for (typename NodeMaps::iterator it = _node_maps.begin(); |
689 it != _node_maps.end(); ++it) { |
689 it != _node_maps.end(); ++it) { |
690 std::string value = it->second->get(n); |
690 std::string value = it->second->get(n); |
691 _writer_bits::writeToken(*_os, value); |
691 _writer_bits::writeToken(*_os, value); |
692 if (it->first == "label") { |
692 if (it->first == "label") { |
693 _node_index.insert(std::make_pair(n, value)); |
693 _node_index.insert(std::make_pair(n, value)); |
694 } |
694 } |
695 *_os << '\t'; |
695 *_os << '\t'; |
696 } |
696 } |
697 *_os << std::endl; |
697 *_os << std::endl; |
698 } |
698 } |
699 } |
699 } |
700 |
700 |
701 void createNodeIndex() { |
701 void createNodeIndex() { |
702 _writer_bits::MapStorageBase<Node>* label = 0; |
702 _writer_bits::MapStorageBase<Node>* label = 0; |
703 for (typename NodeMaps::iterator it = _node_maps.begin(); |
703 for (typename NodeMaps::iterator it = _node_maps.begin(); |
704 it != _node_maps.end(); ++it) { |
704 it != _node_maps.end(); ++it) { |
705 if (it->first == "label") { |
705 if (it->first == "label") { |
706 label = it->second; |
706 label = it->second; |
707 break; |
707 break; |
708 } |
708 } |
709 } |
709 } |
710 |
710 |
711 if (label == 0) { |
711 if (label == 0) { |
712 for (NodeIt n(_digraph); n != INVALID; ++n) { |
712 for (NodeIt n(_digraph); n != INVALID; ++n) { |
713 std::ostringstream os; |
713 std::ostringstream os; |
714 os << _digraph.id(n); |
714 os << _digraph.id(n); |
715 _node_index.insert(std::make_pair(n, os.str())); |
715 _node_index.insert(std::make_pair(n, os.str())); |
716 } |
716 } |
717 } else { |
717 } else { |
718 for (NodeIt n(_digraph); n != INVALID; ++n) { |
718 for (NodeIt n(_digraph); n != INVALID; ++n) { |
719 std::string value = label->get(n); |
719 std::string value = label->get(n); |
720 _node_index.insert(std::make_pair(n, value)); |
720 _node_index.insert(std::make_pair(n, value)); |
721 } |
721 } |
722 } |
722 } |
723 } |
723 } |
724 |
724 |
725 void writeArcs() { |
725 void writeArcs() { |
726 _writer_bits::MapStorageBase<Arc>* label = 0; |
726 _writer_bits::MapStorageBase<Arc>* label = 0; |
727 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
727 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
728 it != _arc_maps.end(); ++it) { |
728 it != _arc_maps.end(); ++it) { |
729 if (it->first == "label") { |
729 if (it->first == "label") { |
730 label = it->second; |
730 label = it->second; |
731 break; |
731 break; |
732 } |
732 } |
733 } |
733 } |
734 |
734 |
735 *_os << "@arcs"; |
735 *_os << "@arcs"; |
736 if (!_arcs_caption.empty()) { |
736 if (!_arcs_caption.empty()) { |
737 _writer_bits::writeToken(*_os << ' ', _arcs_caption); |
737 _writer_bits::writeToken(*_os << ' ', _arcs_caption); |
738 } |
738 } |
739 *_os << std::endl; |
739 *_os << std::endl; |
740 |
740 |
741 *_os << '\t' << '\t'; |
741 *_os << '\t' << '\t'; |
742 if (label == 0) { |
742 if (label == 0) { |
743 *_os << "label" << '\t'; |
743 *_os << "label" << '\t'; |
744 } |
744 } |
745 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
745 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
746 it != _arc_maps.end(); ++it) { |
746 it != _arc_maps.end(); ++it) { |
747 _writer_bits::writeToken(*_os, it->first) << '\t'; |
747 _writer_bits::writeToken(*_os, it->first) << '\t'; |
748 } |
748 } |
749 *_os << std::endl; |
749 *_os << std::endl; |
750 |
750 |
751 std::vector<Arc> arcs; |
751 std::vector<Arc> arcs; |
752 for (ArcIt n(_digraph); n != INVALID; ++n) { |
752 for (ArcIt n(_digraph); n != INVALID; ++n) { |
753 arcs.push_back(n); |
753 arcs.push_back(n); |
754 } |
754 } |
755 |
755 |
756 if (label == 0) { |
756 if (label == 0) { |
757 IdMap<Digraph, Arc> id_map(_digraph); |
757 IdMap<Digraph, Arc> id_map(_digraph); |
758 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map); |
758 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map); |
759 std::sort(arcs.begin(), arcs.end(), id_less); |
759 std::sort(arcs.begin(), arcs.end(), id_less); |
760 } else { |
760 } else { |
761 label->sort(arcs); |
761 label->sort(arcs); |
762 } |
762 } |
763 |
763 |
764 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) { |
764 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) { |
765 Arc a = arcs[i]; |
765 Arc a = arcs[i]; |
766 _writer_bits::writeToken(*_os, _node_index. |
766 _writer_bits::writeToken(*_os, _node_index. |
767 find(_digraph.source(a))->second); |
767 find(_digraph.source(a))->second); |
768 *_os << '\t'; |
768 *_os << '\t'; |
769 _writer_bits::writeToken(*_os, _node_index. |
769 _writer_bits::writeToken(*_os, _node_index. |
770 find(_digraph.target(a))->second); |
770 find(_digraph.target(a))->second); |
771 *_os << '\t'; |
771 *_os << '\t'; |
772 if (label == 0) { |
772 if (label == 0) { |
773 std::ostringstream os; |
773 std::ostringstream os; |
774 os << _digraph.id(a); |
774 os << _digraph.id(a); |
775 _writer_bits::writeToken(*_os, os.str()); |
775 _writer_bits::writeToken(*_os, os.str()); |
776 *_os << '\t'; |
776 *_os << '\t'; |
777 _arc_index.insert(std::make_pair(a, os.str())); |
777 _arc_index.insert(std::make_pair(a, os.str())); |
778 } |
778 } |
779 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
779 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
780 it != _arc_maps.end(); ++it) { |
780 it != _arc_maps.end(); ++it) { |
781 std::string value = it->second->get(a); |
781 std::string value = it->second->get(a); |
782 _writer_bits::writeToken(*_os, value); |
782 _writer_bits::writeToken(*_os, value); |
783 if (it->first == "label") { |
783 if (it->first == "label") { |
784 _arc_index.insert(std::make_pair(a, value)); |
784 _arc_index.insert(std::make_pair(a, value)); |
785 } |
785 } |
786 *_os << '\t'; |
786 *_os << '\t'; |
787 } |
787 } |
788 *_os << std::endl; |
788 *_os << std::endl; |
789 } |
789 } |
790 } |
790 } |
791 |
791 |
792 void createArcIndex() { |
792 void createArcIndex() { |
793 _writer_bits::MapStorageBase<Arc>* label = 0; |
793 _writer_bits::MapStorageBase<Arc>* label = 0; |
794 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
794 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
795 it != _arc_maps.end(); ++it) { |
795 it != _arc_maps.end(); ++it) { |
796 if (it->first == "label") { |
796 if (it->first == "label") { |
797 label = it->second; |
797 label = it->second; |
798 break; |
798 break; |
799 } |
799 } |
800 } |
800 } |
801 |
801 |
802 if (label == 0) { |
802 if (label == 0) { |
803 for (ArcIt a(_digraph); a != INVALID; ++a) { |
803 for (ArcIt a(_digraph); a != INVALID; ++a) { |
804 std::ostringstream os; |
804 std::ostringstream os; |
805 os << _digraph.id(a); |
805 os << _digraph.id(a); |
806 _arc_index.insert(std::make_pair(a, os.str())); |
806 _arc_index.insert(std::make_pair(a, os.str())); |
807 } |
807 } |
808 } else { |
808 } else { |
809 for (ArcIt a(_digraph); a != INVALID; ++a) { |
809 for (ArcIt a(_digraph); a != INVALID; ++a) { |
810 std::string value = label->get(a); |
810 std::string value = label->get(a); |
811 _arc_index.insert(std::make_pair(a, value)); |
811 _arc_index.insert(std::make_pair(a, value)); |
812 } |
812 } |
813 } |
813 } |
814 } |
814 } |
815 |
815 |
816 void writeAttributes() { |
816 void writeAttributes() { |
817 if (_attributes.empty()) return; |
817 if (_attributes.empty()) return; |
818 *_os << "@attributes"; |
818 *_os << "@attributes"; |
819 if (!_attributes_caption.empty()) { |
819 if (!_attributes_caption.empty()) { |
820 _writer_bits::writeToken(*_os << ' ', _attributes_caption); |
820 _writer_bits::writeToken(*_os << ' ', _attributes_caption); |
821 } |
821 } |
822 *_os << std::endl; |
822 *_os << std::endl; |
823 for (typename Attributes::iterator it = _attributes.begin(); |
823 for (typename Attributes::iterator it = _attributes.begin(); |
824 it != _attributes.end(); ++it) { |
824 it != _attributes.end(); ++it) { |
825 _writer_bits::writeToken(*_os, it->first) << ' '; |
825 _writer_bits::writeToken(*_os, it->first) << ' '; |
826 _writer_bits::writeToken(*_os, it->second->get()); |
826 _writer_bits::writeToken(*_os, it->second->get()); |
827 *_os << std::endl; |
827 *_os << std::endl; |
828 } |
828 } |
829 } |
829 } |
830 |
830 |
831 public: |
831 public: |
832 |
832 |
833 /// \name Execution of the writer |
833 /// \name Execution of the writer |
834 /// @{ |
834 /// @{ |
835 |
835 |
836 /// \brief Start the batch processing |
836 /// \brief Start the batch processing |
837 /// |
837 /// |
838 /// This function starts the batch processing. |
838 /// This function starts the batch processing. |
839 void run() { |
839 void run() { |
840 if (!_skip_nodes) { |
840 if (!_skip_nodes) { |
841 writeNodes(); |
841 writeNodes(); |
842 } else { |
842 } else { |
843 createNodeIndex(); |
843 createNodeIndex(); |
844 } |
844 } |
845 if (!_skip_arcs) { |
845 if (!_skip_arcs) { |
846 writeArcs(); |
846 writeArcs(); |
847 } else { |
847 } else { |
848 createArcIndex(); |
848 createArcIndex(); |
849 } |
849 } |
850 writeAttributes(); |
850 writeAttributes(); |
851 } |
851 } |
852 |
852 |
853 /// \brief Give back the stream of the writer |
853 /// \brief Give back the stream of the writer |
859 |
859 |
860 /// @} |
860 /// @} |
861 }; |
861 }; |
862 |
862 |
863 /// \brief Return a \ref DigraphWriter class |
863 /// \brief Return a \ref DigraphWriter class |
864 /// |
864 /// |
865 /// This function just returns a \ref DigraphWriter class. |
865 /// This function just returns a \ref DigraphWriter class. |
866 /// \relates DigraphWriter |
866 /// \relates DigraphWriter |
867 template <typename Digraph> |
867 template <typename Digraph> |
868 DigraphWriter<Digraph> digraphWriter(std::ostream& os, |
868 DigraphWriter<Digraph> digraphWriter(std::ostream& os, |
869 const Digraph& digraph) { |
869 const Digraph& digraph) { |
870 DigraphWriter<Digraph> tmp(os, digraph); |
870 DigraphWriter<Digraph> tmp(os, digraph); |
871 return tmp; |
871 return tmp; |
872 } |
872 } |
873 |
873 |
874 /// \brief Return a \ref DigraphWriter class |
874 /// \brief Return a \ref DigraphWriter class |
875 /// |
875 /// |
876 /// This function just returns a \ref DigraphWriter class. |
876 /// This function just returns a \ref DigraphWriter class. |
877 /// \relates DigraphWriter |
877 /// \relates DigraphWriter |
878 template <typename Digraph> |
878 template <typename Digraph> |
879 DigraphWriter<Digraph> digraphWriter(const std::string& fn, |
879 DigraphWriter<Digraph> digraphWriter(const std::string& fn, |
880 const Digraph& digraph) { |
880 const Digraph& digraph) { |
881 DigraphWriter<Digraph> tmp(fn, digraph); |
881 DigraphWriter<Digraph> tmp(fn, digraph); |
882 return tmp; |
882 return tmp; |
883 } |
883 } |
884 |
884 |
885 /// \brief Return a \ref DigraphWriter class |
885 /// \brief Return a \ref DigraphWriter class |
886 /// |
886 /// |
887 /// This function just returns a \ref DigraphWriter class. |
887 /// This function just returns a \ref DigraphWriter class. |
888 /// \relates DigraphWriter |
888 /// \relates DigraphWriter |
889 template <typename Digraph> |
889 template <typename Digraph> |
890 DigraphWriter<Digraph> digraphWriter(const char* fn, |
890 DigraphWriter<Digraph> digraphWriter(const char* fn, |
891 const Digraph& digraph) { |
891 const Digraph& digraph) { |
892 DigraphWriter<Digraph> tmp(fn, digraph); |
892 DigraphWriter<Digraph> tmp(fn, digraph); |
893 return tmp; |
893 return tmp; |
894 } |
894 } |
895 |
895 |
896 template <typename Graph> |
896 template <typename Graph> |
897 class GraphWriter; |
897 class GraphWriter; |
898 |
898 |
899 template <typename Graph> |
899 template <typename Graph> |
900 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph); |
900 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph); |
901 |
901 |
902 template <typename Graph> |
902 template <typename Graph> |
903 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph); |
903 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph); |
904 |
904 |
905 template <typename Graph> |
905 template <typename Graph> |
906 GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph); |
906 GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph); |
907 |
907 |
908 /// \ingroup lemon_io |
908 /// \ingroup lemon_io |
909 /// |
909 /// |
910 /// \brief \ref lgf-format "LGF" writer for directed graphs |
910 /// \brief \ref lgf-format "LGF" writer for directed graphs |
911 /// |
911 /// |
912 /// This utility writes an \ref lgf-format "LGF" file. |
912 /// This utility writes an \ref lgf-format "LGF" file. |
913 /// |
913 /// |
914 /// It can be used almost the same way as \c DigraphWriter. |
914 /// It can be used almost the same way as \c DigraphWriter. |
963 |
963 |
964 /// \brief Constructor |
964 /// \brief Constructor |
965 /// |
965 /// |
966 /// Construct a directed graph writer, which writes to the given |
966 /// Construct a directed graph writer, which writes to the given |
967 /// output stream. |
967 /// output stream. |
968 GraphWriter(std::ostream& is, const Graph& graph) |
968 GraphWriter(std::ostream& is, const Graph& graph) |
969 : _os(&is), local_os(false), _graph(graph), |
969 : _os(&is), local_os(false), _graph(graph), |
970 _skip_nodes(false), _skip_edges(false) {} |
970 _skip_nodes(false), _skip_edges(false) {} |
971 |
971 |
972 /// \brief Constructor |
972 /// \brief Constructor |
973 /// |
973 /// |
974 /// Construct a directed graph writer, which writes to the given |
974 /// Construct a directed graph writer, which writes to the given |
975 /// output file. |
975 /// output file. |
976 GraphWriter(const std::string& fn, const Graph& graph) |
976 GraphWriter(const std::string& fn, const Graph& graph) |
977 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), |
977 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), |
978 _skip_nodes(false), _skip_edges(false) {} |
978 _skip_nodes(false), _skip_edges(false) {} |
979 |
979 |
980 /// \brief Constructor |
980 /// \brief Constructor |
981 /// |
981 /// |
982 /// Construct a directed graph writer, which writes to the given |
982 /// Construct a directed graph writer, which writes to the given |
983 /// output file. |
983 /// output file. |
984 GraphWriter(const char* fn, const Graph& graph) |
984 GraphWriter(const char* fn, const Graph& graph) |
985 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), |
985 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), |
986 _skip_nodes(false), _skip_edges(false) {} |
986 _skip_nodes(false), _skip_edges(false) {} |
987 |
987 |
988 /// \brief Destructor |
988 /// \brief Destructor |
989 ~GraphWriter() { |
989 ~GraphWriter() { |
990 for (typename NodeMaps::iterator it = _node_maps.begin(); |
990 for (typename NodeMaps::iterator it = _node_maps.begin(); |
991 it != _node_maps.end(); ++it) { |
991 it != _node_maps.end(); ++it) { |
992 delete it->second; |
992 delete it->second; |
993 } |
993 } |
994 |
994 |
995 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
995 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
996 it != _edge_maps.end(); ++it) { |
996 it != _edge_maps.end(); ++it) { |
997 delete it->second; |
997 delete it->second; |
998 } |
998 } |
999 |
999 |
1000 for (typename Attributes::iterator it = _attributes.begin(); |
1000 for (typename Attributes::iterator it = _attributes.begin(); |
1001 it != _attributes.end(); ++it) { |
1001 it != _attributes.end(); ++it) { |
1002 delete it->second; |
1002 delete it->second; |
1003 } |
1003 } |
1004 |
1004 |
1005 if (local_os) { |
1005 if (local_os) { |
1006 delete _os; |
1006 delete _os; |
1007 } |
1007 } |
1008 } |
1008 } |
1009 |
1009 |
1010 private: |
1010 private: |
1011 |
1011 |
1012 friend GraphWriter<Graph> graphWriter<>(std::ostream& os, |
1012 friend GraphWriter<Graph> graphWriter<>(std::ostream& os, |
1013 const Graph& graph); |
1013 const Graph& graph); |
1014 friend GraphWriter<Graph> graphWriter<>(const std::string& fn, |
1014 friend GraphWriter<Graph> graphWriter<>(const std::string& fn, |
1015 const Graph& graph); |
1015 const Graph& graph); |
1016 friend GraphWriter<Graph> graphWriter<>(const char *fn, |
1016 friend GraphWriter<Graph> graphWriter<>(const char *fn, |
1017 const Graph& graph); |
1017 const Graph& graph); |
1018 |
1018 |
1019 GraphWriter(GraphWriter& other) |
1019 GraphWriter(GraphWriter& other) |
1020 : _os(other._os), local_os(other.local_os), _graph(other._graph), |
1020 : _os(other._os), local_os(other.local_os), _graph(other._graph), |
1021 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { |
1021 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { |
1022 |
1022 |
1023 other._os = 0; |
1023 other._os = 0; |
1024 other.local_os = false; |
1024 other.local_os = false; |
1025 |
1025 |
1026 _node_index.swap(other._node_index); |
1026 _node_index.swap(other._node_index); |
1039 |
1039 |
1040 public: |
1040 public: |
1041 |
1041 |
1042 /// \name Writing rules |
1042 /// \name Writing rules |
1043 /// @{ |
1043 /// @{ |
1044 |
1044 |
1045 /// \brief Node map writing rule |
1045 /// \brief Node map writing rule |
1046 /// |
1046 /// |
1047 /// Add a node map writing rule to the writer. |
1047 /// Add a node map writing rule to the writer. |
1048 template <typename Map> |
1048 template <typename Map> |
1049 GraphWriter& nodeMap(const std::string& caption, const Map& map) { |
1049 GraphWriter& nodeMap(const std::string& caption, const Map& map) { |
1050 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1050 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1051 _writer_bits::MapStorageBase<Node>* storage = |
1051 _writer_bits::MapStorageBase<Node>* storage = |
1052 new _writer_bits::MapStorage<Node, Map>(map); |
1052 new _writer_bits::MapStorage<Node, Map>(map); |
1053 _node_maps.push_back(std::make_pair(caption, storage)); |
1053 _node_maps.push_back(std::make_pair(caption, storage)); |
1054 return *this; |
1054 return *this; |
1055 } |
1055 } |
1056 |
1056 |
1057 /// \brief Node map writing rule |
1057 /// \brief Node map writing rule |
1058 /// |
1058 /// |
1059 /// Add a node map writing rule with specialized converter to the |
1059 /// Add a node map writing rule with specialized converter to the |
1060 /// writer. |
1060 /// writer. |
1061 template <typename Map, typename Converter> |
1061 template <typename Map, typename Converter> |
1062 GraphWriter& nodeMap(const std::string& caption, const Map& map, |
1062 GraphWriter& nodeMap(const std::string& caption, const Map& map, |
1063 const Converter& converter = Converter()) { |
1063 const Converter& converter = Converter()) { |
1064 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1064 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1065 _writer_bits::MapStorageBase<Node>* storage = |
1065 _writer_bits::MapStorageBase<Node>* storage = |
1066 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1066 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1067 _node_maps.push_back(std::make_pair(caption, storage)); |
1067 _node_maps.push_back(std::make_pair(caption, storage)); |
1068 return *this; |
1068 return *this; |
1069 } |
1069 } |
1070 |
1070 |
1071 /// \brief Edge map writing rule |
1071 /// \brief Edge map writing rule |
1072 /// |
1072 /// |
1073 /// Add an edge map writing rule to the writer. |
1073 /// Add an edge map writing rule to the writer. |
1074 template <typename Map> |
1074 template <typename Map> |
1075 GraphWriter& edgeMap(const std::string& caption, const Map& map) { |
1075 GraphWriter& edgeMap(const std::string& caption, const Map& map) { |
1076 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
1076 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
1077 _writer_bits::MapStorageBase<Edge>* storage = |
1077 _writer_bits::MapStorageBase<Edge>* storage = |
1078 new _writer_bits::MapStorage<Edge, Map>(map); |
1078 new _writer_bits::MapStorage<Edge, Map>(map); |
1079 _edge_maps.push_back(std::make_pair(caption, storage)); |
1079 _edge_maps.push_back(std::make_pair(caption, storage)); |
1080 return *this; |
1080 return *this; |
1081 } |
1081 } |
1082 |
1082 |
1083 /// \brief Edge map writing rule |
1083 /// \brief Edge map writing rule |
1084 /// |
1084 /// |
1085 /// Add an edge map writing rule with specialized converter to the |
1085 /// Add an edge map writing rule with specialized converter to the |
1086 /// writer. |
1086 /// writer. |
1087 template <typename Map, typename Converter> |
1087 template <typename Map, typename Converter> |
1088 GraphWriter& edgeMap(const std::string& caption, const Map& map, |
1088 GraphWriter& edgeMap(const std::string& caption, const Map& map, |
1089 const Converter& converter = Converter()) { |
1089 const Converter& converter = Converter()) { |
1090 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
1090 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
1091 _writer_bits::MapStorageBase<Edge>* storage = |
1091 _writer_bits::MapStorageBase<Edge>* storage = |
1092 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); |
1092 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); |
1093 _edge_maps.push_back(std::make_pair(caption, storage)); |
1093 _edge_maps.push_back(std::make_pair(caption, storage)); |
1094 return *this; |
1094 return *this; |
1095 } |
1095 } |
1096 |
1096 |
1097 /// \brief Arc map writing rule |
1097 /// \brief Arc map writing rule |
1098 /// |
1098 /// |
1099 /// Add an arc map writing rule to the writer. |
1099 /// Add an arc map writing rule to the writer. |
1100 template <typename Map> |
1100 template <typename Map> |
1101 GraphWriter& arcMap(const std::string& caption, const Map& map) { |
1101 GraphWriter& arcMap(const std::string& caption, const Map& map) { |
1102 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
1102 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
1103 _writer_bits::MapStorageBase<Edge>* forward_storage = |
1103 _writer_bits::MapStorageBase<Edge>* forward_storage = |
1104 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); |
1104 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); |
1105 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
1105 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
1106 _writer_bits::MapStorageBase<Edge>* backward_storage = |
1106 _writer_bits::MapStorageBase<Edge>* backward_storage = |
1107 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); |
1107 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); |
1108 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
1108 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
1109 return *this; |
1109 return *this; |
1110 } |
1110 } |
1111 |
1111 |
1112 /// \brief Arc map writing rule |
1112 /// \brief Arc map writing rule |
1113 /// |
1113 /// |
1114 /// Add an arc map writing rule with specialized converter to the |
1114 /// Add an arc map writing rule with specialized converter to the |
1115 /// writer. |
1115 /// writer. |
1116 template <typename Map, typename Converter> |
1116 template <typename Map, typename Converter> |
1117 GraphWriter& arcMap(const std::string& caption, const Map& map, |
1117 GraphWriter& arcMap(const std::string& caption, const Map& map, |
1118 const Converter& converter = Converter()) { |
1118 const Converter& converter = Converter()) { |
1119 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
1119 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
1120 _writer_bits::MapStorageBase<Edge>* forward_storage = |
1120 _writer_bits::MapStorageBase<Edge>* forward_storage = |
1121 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter> |
1121 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter> |
1122 (_graph, map, converter); |
1122 (_graph, map, converter); |
1123 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
1123 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
1124 _writer_bits::MapStorageBase<Edge>* backward_storage = |
1124 _writer_bits::MapStorageBase<Edge>* backward_storage = |
1125 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter> |
1125 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter> |
1126 (_graph, map, converter); |
1126 (_graph, map, converter); |
1127 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
1127 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
1128 return *this; |
1128 return *this; |
1129 } |
1129 } |
1130 |
1130 |
1131 /// \brief Attribute writing rule |
1131 /// \brief Attribute writing rule |
1132 /// |
1132 /// |
1133 /// Add an attribute writing rule to the writer. |
1133 /// Add an attribute writing rule to the writer. |
1134 template <typename Value> |
1134 template <typename Value> |
1135 GraphWriter& attribute(const std::string& caption, const Value& value) { |
1135 GraphWriter& attribute(const std::string& caption, const Value& value) { |
1136 _writer_bits::ValueStorageBase* storage = |
1136 _writer_bits::ValueStorageBase* storage = |
1137 new _writer_bits::ValueStorage<Value>(value); |
1137 new _writer_bits::ValueStorage<Value>(value); |
1138 _attributes.push_back(std::make_pair(caption, storage)); |
1138 _attributes.push_back(std::make_pair(caption, storage)); |
1139 return *this; |
1139 return *this; |
1140 } |
1140 } |
1141 |
1141 |
1142 /// \brief Attribute writing rule |
1142 /// \brief Attribute writing rule |
1143 /// |
1143 /// |
1144 /// Add an attribute writing rule with specialized converter to the |
1144 /// Add an attribute writing rule with specialized converter to the |
1145 /// writer. |
1145 /// writer. |
1146 template <typename Value, typename Converter> |
1146 template <typename Value, typename Converter> |
1147 GraphWriter& attribute(const std::string& caption, const Value& value, |
1147 GraphWriter& attribute(const std::string& caption, const Value& value, |
1148 const Converter& converter = Converter()) { |
1148 const Converter& converter = Converter()) { |
1149 _writer_bits::ValueStorageBase* storage = |
1149 _writer_bits::ValueStorageBase* storage = |
1150 new _writer_bits::ValueStorage<Value, Converter>(value, converter); |
1150 new _writer_bits::ValueStorage<Value, Converter>(value, converter); |
1151 _attributes.push_back(std::make_pair(caption, storage)); |
1151 _attributes.push_back(std::make_pair(caption, storage)); |
1152 return *this; |
1152 return *this; |
1153 } |
1153 } |
1154 |
1154 |
1155 /// \brief Node writing rule |
1155 /// \brief Node writing rule |
1156 /// |
1156 /// |
1157 /// Add a node writing rule to the writer. |
1157 /// Add a node writing rule to the writer. |
1158 GraphWriter& node(const std::string& caption, const Node& node) { |
1158 GraphWriter& node(const std::string& caption, const Node& node) { |
1159 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
1159 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
1160 Converter converter(_node_index); |
1160 Converter converter(_node_index); |
1161 _writer_bits::ValueStorageBase* storage = |
1161 _writer_bits::ValueStorageBase* storage = |
1162 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
1162 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
1163 _attributes.push_back(std::make_pair(caption, storage)); |
1163 _attributes.push_back(std::make_pair(caption, storage)); |
1164 return *this; |
1164 return *this; |
1165 } |
1165 } |
1166 |
1166 |
1167 /// \brief Edge writing rule |
1167 /// \brief Edge writing rule |
1168 /// |
1168 /// |
1169 /// Add an edge writing rule to writer. |
1169 /// Add an edge writing rule to writer. |
1170 GraphWriter& edge(const std::string& caption, const Edge& edge) { |
1170 GraphWriter& edge(const std::string& caption, const Edge& edge) { |
1171 typedef _writer_bits::MapLookUpConverter<Edge> Converter; |
1171 typedef _writer_bits::MapLookUpConverter<Edge> Converter; |
1172 Converter converter(_edge_index); |
1172 Converter converter(_edge_index); |
1173 _writer_bits::ValueStorageBase* storage = |
1173 _writer_bits::ValueStorageBase* storage = |
1174 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); |
1174 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); |
1175 _attributes.push_back(std::make_pair(caption, storage)); |
1175 _attributes.push_back(std::make_pair(caption, storage)); |
1176 return *this; |
1176 return *this; |
1177 } |
1177 } |
1178 |
1178 |
1179 /// \brief Arc writing rule |
1179 /// \brief Arc writing rule |
1180 /// |
1180 /// |
1181 /// Add an arc writing rule to writer. |
1181 /// Add an arc writing rule to writer. |
1182 GraphWriter& arc(const std::string& caption, const Arc& arc) { |
1182 GraphWriter& arc(const std::string& caption, const Arc& arc) { |
1183 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter; |
1183 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter; |
1184 Converter converter(_graph, _edge_index); |
1184 Converter converter(_graph, _edge_index); |
1185 _writer_bits::ValueStorageBase* storage = |
1185 _writer_bits::ValueStorageBase* storage = |
1186 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); |
1186 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); |
1187 _attributes.push_back(std::make_pair(caption, storage)); |
1187 _attributes.push_back(std::make_pair(caption, storage)); |
1188 return *this; |
1188 return *this; |
1189 } |
1189 } |
1190 |
1190 |
1191 /// \name Section captions |
1191 /// \name Section captions |
1241 private: |
1241 private: |
1242 |
1242 |
1243 void writeNodes() { |
1243 void writeNodes() { |
1244 _writer_bits::MapStorageBase<Node>* label = 0; |
1244 _writer_bits::MapStorageBase<Node>* label = 0; |
1245 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1245 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1246 it != _node_maps.end(); ++it) { |
1246 it != _node_maps.end(); ++it) { |
1247 if (it->first == "label") { |
1247 if (it->first == "label") { |
1248 label = it->second; |
1248 label = it->second; |
1249 break; |
1249 break; |
1250 } |
1250 } |
1251 } |
1251 } |
1252 |
1252 |
1253 *_os << "@nodes"; |
1253 *_os << "@nodes"; |
1254 if (!_nodes_caption.empty()) { |
1254 if (!_nodes_caption.empty()) { |
1255 _writer_bits::writeToken(*_os << ' ', _nodes_caption); |
1255 _writer_bits::writeToken(*_os << ' ', _nodes_caption); |
1256 } |
1256 } |
1257 *_os << std::endl; |
1257 *_os << std::endl; |
1258 |
1258 |
1259 if (label == 0) { |
1259 if (label == 0) { |
1260 *_os << "label" << '\t'; |
1260 *_os << "label" << '\t'; |
1261 } |
1261 } |
1262 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1262 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1263 it != _node_maps.end(); ++it) { |
1263 it != _node_maps.end(); ++it) { |
1264 _writer_bits::writeToken(*_os, it->first) << '\t'; |
1264 _writer_bits::writeToken(*_os, it->first) << '\t'; |
1265 } |
1265 } |
1266 *_os << std::endl; |
1266 *_os << std::endl; |
1267 |
1267 |
1268 std::vector<Node> nodes; |
1268 std::vector<Node> nodes; |
1269 for (NodeIt n(_graph); n != INVALID; ++n) { |
1269 for (NodeIt n(_graph); n != INVALID; ++n) { |
1270 nodes.push_back(n); |
1270 nodes.push_back(n); |
1271 } |
1271 } |
1272 |
1272 |
1273 if (label == 0) { |
1273 if (label == 0) { |
1274 IdMap<Graph, Node> id_map(_graph); |
1274 IdMap<Graph, Node> id_map(_graph); |
1275 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map); |
1275 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map); |
1276 std::sort(nodes.begin(), nodes.end(), id_less); |
1276 std::sort(nodes.begin(), nodes.end(), id_less); |
1277 } else { |
1277 } else { |
1278 label->sort(nodes); |
1278 label->sort(nodes); |
1279 } |
1279 } |
1280 |
1280 |
1281 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
1281 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
1282 Node n = nodes[i]; |
1282 Node n = nodes[i]; |
1283 if (label == 0) { |
1283 if (label == 0) { |
1284 std::ostringstream os; |
1284 std::ostringstream os; |
1285 os << _graph.id(n); |
1285 os << _graph.id(n); |
1286 _writer_bits::writeToken(*_os, os.str()); |
1286 _writer_bits::writeToken(*_os, os.str()); |
1287 *_os << '\t'; |
1287 *_os << '\t'; |
1288 _node_index.insert(std::make_pair(n, os.str())); |
1288 _node_index.insert(std::make_pair(n, os.str())); |
1289 } |
1289 } |
1290 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1290 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1291 it != _node_maps.end(); ++it) { |
1291 it != _node_maps.end(); ++it) { |
1292 std::string value = it->second->get(n); |
1292 std::string value = it->second->get(n); |
1293 _writer_bits::writeToken(*_os, value); |
1293 _writer_bits::writeToken(*_os, value); |
1294 if (it->first == "label") { |
1294 if (it->first == "label") { |
1295 _node_index.insert(std::make_pair(n, value)); |
1295 _node_index.insert(std::make_pair(n, value)); |
1296 } |
1296 } |
1297 *_os << '\t'; |
1297 *_os << '\t'; |
1298 } |
1298 } |
1299 *_os << std::endl; |
1299 *_os << std::endl; |
1300 } |
1300 } |
1301 } |
1301 } |
1302 |
1302 |
1303 void createNodeIndex() { |
1303 void createNodeIndex() { |
1304 _writer_bits::MapStorageBase<Node>* label = 0; |
1304 _writer_bits::MapStorageBase<Node>* label = 0; |
1305 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1305 for (typename NodeMaps::iterator it = _node_maps.begin(); |
1306 it != _node_maps.end(); ++it) { |
1306 it != _node_maps.end(); ++it) { |
1307 if (it->first == "label") { |
1307 if (it->first == "label") { |
1308 label = it->second; |
1308 label = it->second; |
1309 break; |
1309 break; |
1310 } |
1310 } |
1311 } |
1311 } |
1312 |
1312 |
1313 if (label == 0) { |
1313 if (label == 0) { |
1314 for (NodeIt n(_graph); n != INVALID; ++n) { |
1314 for (NodeIt n(_graph); n != INVALID; ++n) { |
1315 std::ostringstream os; |
1315 std::ostringstream os; |
1316 os << _graph.id(n); |
1316 os << _graph.id(n); |
1317 _node_index.insert(std::make_pair(n, os.str())); |
1317 _node_index.insert(std::make_pair(n, os.str())); |
1318 } |
1318 } |
1319 } else { |
1319 } else { |
1320 for (NodeIt n(_graph); n != INVALID; ++n) { |
1320 for (NodeIt n(_graph); n != INVALID; ++n) { |
1321 std::string value = label->get(n); |
1321 std::string value = label->get(n); |
1322 _node_index.insert(std::make_pair(n, value)); |
1322 _node_index.insert(std::make_pair(n, value)); |
1323 } |
1323 } |
1324 } |
1324 } |
1325 } |
1325 } |
1326 |
1326 |
1327 void writeEdges() { |
1327 void writeEdges() { |
1328 _writer_bits::MapStorageBase<Edge>* label = 0; |
1328 _writer_bits::MapStorageBase<Edge>* label = 0; |
1329 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1329 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1330 it != _edge_maps.end(); ++it) { |
1330 it != _edge_maps.end(); ++it) { |
1331 if (it->first == "label") { |
1331 if (it->first == "label") { |
1332 label = it->second; |
1332 label = it->second; |
1333 break; |
1333 break; |
1334 } |
1334 } |
1335 } |
1335 } |
1336 |
1336 |
1337 *_os << "@edges"; |
1337 *_os << "@edges"; |
1338 if (!_edges_caption.empty()) { |
1338 if (!_edges_caption.empty()) { |
1339 _writer_bits::writeToken(*_os << ' ', _edges_caption); |
1339 _writer_bits::writeToken(*_os << ' ', _edges_caption); |
1340 } |
1340 } |
1341 *_os << std::endl; |
1341 *_os << std::endl; |
1342 |
1342 |
1343 *_os << '\t' << '\t'; |
1343 *_os << '\t' << '\t'; |
1344 if (label == 0) { |
1344 if (label == 0) { |
1345 *_os << "label" << '\t'; |
1345 *_os << "label" << '\t'; |
1346 } |
1346 } |
1347 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1347 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1348 it != _edge_maps.end(); ++it) { |
1348 it != _edge_maps.end(); ++it) { |
1349 _writer_bits::writeToken(*_os, it->first) << '\t'; |
1349 _writer_bits::writeToken(*_os, it->first) << '\t'; |
1350 } |
1350 } |
1351 *_os << std::endl; |
1351 *_os << std::endl; |
1352 |
1352 |
1353 std::vector<Edge> edges; |
1353 std::vector<Edge> edges; |
1354 for (EdgeIt n(_graph); n != INVALID; ++n) { |
1354 for (EdgeIt n(_graph); n != INVALID; ++n) { |
1355 edges.push_back(n); |
1355 edges.push_back(n); |
1356 } |
1356 } |
1357 |
1357 |
1358 if (label == 0) { |
1358 if (label == 0) { |
1359 IdMap<Graph, Edge> id_map(_graph); |
1359 IdMap<Graph, Edge> id_map(_graph); |
1360 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map); |
1360 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map); |
1361 std::sort(edges.begin(), edges.end(), id_less); |
1361 std::sort(edges.begin(), edges.end(), id_less); |
1362 } else { |
1362 } else { |
1363 label->sort(edges); |
1363 label->sort(edges); |
1364 } |
1364 } |
1365 |
1365 |
1366 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { |
1366 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { |
1367 Edge e = edges[i]; |
1367 Edge e = edges[i]; |
1368 _writer_bits::writeToken(*_os, _node_index. |
1368 _writer_bits::writeToken(*_os, _node_index. |
1369 find(_graph.u(e))->second); |
1369 find(_graph.u(e))->second); |
1370 *_os << '\t'; |
1370 *_os << '\t'; |
1371 _writer_bits::writeToken(*_os, _node_index. |
1371 _writer_bits::writeToken(*_os, _node_index. |
1372 find(_graph.v(e))->second); |
1372 find(_graph.v(e))->second); |
1373 *_os << '\t'; |
1373 *_os << '\t'; |
1374 if (label == 0) { |
1374 if (label == 0) { |
1375 std::ostringstream os; |
1375 std::ostringstream os; |
1376 os << _graph.id(e); |
1376 os << _graph.id(e); |
1377 _writer_bits::writeToken(*_os, os.str()); |
1377 _writer_bits::writeToken(*_os, os.str()); |
1378 *_os << '\t'; |
1378 *_os << '\t'; |
1379 _edge_index.insert(std::make_pair(e, os.str())); |
1379 _edge_index.insert(std::make_pair(e, os.str())); |
1380 } |
1380 } |
1381 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1381 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1382 it != _edge_maps.end(); ++it) { |
1382 it != _edge_maps.end(); ++it) { |
1383 std::string value = it->second->get(e); |
1383 std::string value = it->second->get(e); |
1384 _writer_bits::writeToken(*_os, value); |
1384 _writer_bits::writeToken(*_os, value); |
1385 if (it->first == "label") { |
1385 if (it->first == "label") { |
1386 _edge_index.insert(std::make_pair(e, value)); |
1386 _edge_index.insert(std::make_pair(e, value)); |
1387 } |
1387 } |
1388 *_os << '\t'; |
1388 *_os << '\t'; |
1389 } |
1389 } |
1390 *_os << std::endl; |
1390 *_os << std::endl; |
1391 } |
1391 } |
1392 } |
1392 } |
1393 |
1393 |
1394 void createEdgeIndex() { |
1394 void createEdgeIndex() { |
1395 _writer_bits::MapStorageBase<Edge>* label = 0; |
1395 _writer_bits::MapStorageBase<Edge>* label = 0; |
1396 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1396 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
1397 it != _edge_maps.end(); ++it) { |
1397 it != _edge_maps.end(); ++it) { |
1398 if (it->first == "label") { |
1398 if (it->first == "label") { |
1399 label = it->second; |
1399 label = it->second; |
1400 break; |
1400 break; |
1401 } |
1401 } |
1402 } |
1402 } |
1403 |
1403 |
1404 if (label == 0) { |
1404 if (label == 0) { |
1405 for (EdgeIt e(_graph); e != INVALID; ++e) { |
1405 for (EdgeIt e(_graph); e != INVALID; ++e) { |
1406 std::ostringstream os; |
1406 std::ostringstream os; |
1407 os << _graph.id(e); |
1407 os << _graph.id(e); |
1408 _edge_index.insert(std::make_pair(e, os.str())); |
1408 _edge_index.insert(std::make_pair(e, os.str())); |
1409 } |
1409 } |
1410 } else { |
1410 } else { |
1411 for (EdgeIt e(_graph); e != INVALID; ++e) { |
1411 for (EdgeIt e(_graph); e != INVALID; ++e) { |
1412 std::string value = label->get(e); |
1412 std::string value = label->get(e); |
1413 _edge_index.insert(std::make_pair(e, value)); |
1413 _edge_index.insert(std::make_pair(e, value)); |
1414 } |
1414 } |
1415 } |
1415 } |
1416 } |
1416 } |
1417 |
1417 |
1418 void writeAttributes() { |
1418 void writeAttributes() { |
1419 if (_attributes.empty()) return; |
1419 if (_attributes.empty()) return; |
1420 *_os << "@attributes"; |
1420 *_os << "@attributes"; |
1421 if (!_attributes_caption.empty()) { |
1421 if (!_attributes_caption.empty()) { |
1422 _writer_bits::writeToken(*_os << ' ', _attributes_caption); |
1422 _writer_bits::writeToken(*_os << ' ', _attributes_caption); |
1423 } |
1423 } |
1424 *_os << std::endl; |
1424 *_os << std::endl; |
1425 for (typename Attributes::iterator it = _attributes.begin(); |
1425 for (typename Attributes::iterator it = _attributes.begin(); |
1426 it != _attributes.end(); ++it) { |
1426 it != _attributes.end(); ++it) { |
1427 _writer_bits::writeToken(*_os, it->first) << ' '; |
1427 _writer_bits::writeToken(*_os, it->first) << ' '; |
1428 _writer_bits::writeToken(*_os, it->second->get()); |
1428 _writer_bits::writeToken(*_os, it->second->get()); |
1429 *_os << std::endl; |
1429 *_os << std::endl; |
1430 } |
1430 } |
1431 } |
1431 } |
1432 |
1432 |
1433 public: |
1433 public: |
1434 |
1434 |
1435 /// \name Execution of the writer |
1435 /// \name Execution of the writer |
1436 /// @{ |
1436 /// @{ |
1437 |
1437 |
1438 /// \brief Start the batch processing |
1438 /// \brief Start the batch processing |
1439 /// |
1439 /// |
1440 /// This function starts the batch processing. |
1440 /// This function starts the batch processing. |
1441 void run() { |
1441 void run() { |
1442 if (!_skip_nodes) { |
1442 if (!_skip_nodes) { |
1443 writeNodes(); |
1443 writeNodes(); |
1444 } else { |
1444 } else { |
1445 createNodeIndex(); |
1445 createNodeIndex(); |
1446 } |
1446 } |
1447 if (!_skip_edges) { |
1447 if (!_skip_edges) { |
1448 writeEdges(); |
1448 writeEdges(); |
1449 } else { |
1449 } else { |
1450 createEdgeIndex(); |
1450 createEdgeIndex(); |
1451 } |
1451 } |
1452 writeAttributes(); |
1452 writeAttributes(); |
1453 } |
1453 } |
1454 |
1454 |
1455 /// \brief Give back the stream of the writer |
1455 /// \brief Give back the stream of the writer |