35 #include <lemon/error.h> |
35 #include <lemon/error.h> |
36 |
36 |
37 |
37 |
38 namespace lemon { |
38 namespace lemon { |
39 |
39 |
|
40 /// \addtogroup io_group |
|
41 /// @{ |
|
42 |
40 /// \brief Standard WriterTraits for the GraphWriter class. |
43 /// \brief Standard WriterTraits for the GraphWriter class. |
41 /// |
44 /// |
42 /// Standard WriterTraits for the GraphWriter class. |
45 /// Standard WriterTraits for the GraphWriter class. |
43 /// It defines standard writing method for all type of value. |
46 /// It defines standard writing method for all type of value. |
|
47 /// \author Balazs Dezso |
44 struct DefaultWriterTraits { |
48 struct DefaultWriterTraits { |
45 |
49 |
46 /// \brief Template class for writing an value. |
50 /// \brief Template class for writing an value. |
47 /// |
51 /// |
48 /// Template class for writing an value. |
52 /// Template class for writing an value. |
|
53 /// \author Balazs Dezso |
49 template <typename _Value> |
54 template <typename _Value> |
50 struct Writer { |
55 struct Writer { |
51 /// The value type. |
56 /// The value type. |
52 typedef _Value Value; |
57 typedef _Value Value; |
53 |
58 |
57 void write(std::ostream& os, const Value& value) { |
62 void write(std::ostream& os, const Value& value) { |
58 os << value << '\t'; |
63 os << value << '\t'; |
59 } |
64 } |
60 }; |
65 }; |
61 |
66 |
|
67 /// \brief Returns wheter this name is an ID map name. |
|
68 /// |
|
69 /// Returns wheter this name is an ID map name. |
|
70 static bool idMapName(const std::string& name) { |
|
71 return name == "id"; |
|
72 } |
|
73 |
62 }; |
74 }; |
63 |
75 |
64 |
76 |
65 /// \brief Writer class for quoted strings. |
77 /// \brief Writer class for quoted strings. |
66 /// |
78 /// |
67 /// Writer class for quoted strings. It can process the escape |
79 /// Writer class for quoted strings. It can process the escape |
68 /// sequences in the string. |
80 /// sequences in the string. |
|
81 /// \author Balazs Dezso |
69 class QuotedStringWriter { |
82 class QuotedStringWriter { |
70 public: |
83 public: |
71 typedef std::string Value; |
84 typedef std::string Value; |
72 |
85 |
73 /// \brief Constructor for the writer. |
86 /// \brief Constructor for the writer. |
144 }; |
157 }; |
145 |
158 |
146 |
159 |
147 /// \brief The graph writer class. |
160 /// \brief The graph writer class. |
148 /// |
161 /// |
149 ///\ingroup io_group |
162 /// The \c GraphWriter class provides the graph output. To write a graph |
150 /// The writer class for the graph output. |
163 /// you should first give writing commands for the writer. You can declare |
|
164 /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and |
|
165 /// Edge writing. |
|
166 /// |
|
167 /// \code |
|
168 /// GraphWriter<ListGraph> writer(std::cout, graph); |
|
169 /// \endcode |
|
170 /// |
|
171 /// The \c addNodeMap() function declares a \c NodeMap writing command in the |
|
172 /// \c GraphWriter. You should give as parameter the name of the map and the |
|
173 /// map object. The NodeMap writing command with name "id" should write a |
|
174 /// unique map because it is regarded as ID map. |
|
175 /// |
|
176 /// \code |
|
177 /// IdMap<ListGraph, Node> nodeIdMap; |
|
178 /// writer.addNodeMap("id", nodeIdMap); |
|
179 /// |
|
180 /// writer.addNodeMap("x-coord", xCoordMap); |
|
181 /// writer.addNodeMap("y-coord", yCoordMap); |
|
182 /// writer.addNodeMap("color", colorMap); |
|
183 /// \endcode |
|
184 /// |
|
185 /// With the \c addEdgeMap() member function you can give an edge map |
|
186 /// writing command similar to the NodeMaps. |
|
187 /// |
|
188 /// \code |
|
189 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > |
|
190 /// edgeDescMap(graph); |
|
191 /// writer.addEdgeMap("descriptor", edgeDescMap); |
|
192 /// |
|
193 /// writer.addEdgeMap("weight", weightMap); |
|
194 /// writer.addEdgeMap("label", labelMap); |
|
195 /// \endcode |
|
196 /// |
|
197 /// With \c addNode() and \c addEdge() functions you can point out Nodes and |
|
198 /// Edges in the graph. By example, you can write out the source and target |
|
199 /// of the graph. |
|
200 /// |
|
201 /// \code |
|
202 /// writer.addNode("source", sourceNode); |
|
203 /// writer.addNode("target", targetNode); |
|
204 /// |
|
205 /// writer.addEdge("observed", edge); |
|
206 /// \endcode |
|
207 /// |
|
208 /// After you give all write commands you must call the \c run() member |
|
209 /// function, which execute all the writer commands. |
|
210 /// |
|
211 /// \code |
|
212 /// writer.run(); |
|
213 /// \endcode |
|
214 /// |
151 /// \see DefaultWriterTraits |
215 /// \see DefaultWriterTraits |
152 /// \see QuotedStringWriter |
216 /// \see QuotedStringWriter |
|
217 /// \see IdMap |
|
218 /// \see DescriptorMap |
153 /// \see \ref GraphReader |
219 /// \see \ref GraphReader |
154 /// \see \ref graph-io-page |
220 /// \see \ref graph-io-page |
|
221 /// \author Balazs Dezso |
155 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> |
222 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> |
156 class GraphWriter { |
223 class GraphWriter { |
157 public: |
224 public: |
158 |
225 |
159 typedef _Graph Graph; |
226 typedef _Graph Graph; |
252 |
319 |
253 /// \brief Executes the writer commands. |
320 /// \brief Executes the writer commands. |
254 /// |
321 /// |
255 /// Executes the writer commands. |
322 /// Executes the writer commands. |
256 void run() { |
323 void run() { |
257 writeNodeSet(); |
324 WriterBase<Node>* nodeWriter = 0; |
258 writeEdgeSet(); |
325 WriterBase<Edge>* edgeWriter = 0; |
259 writeNodes(); |
326 writeNodeSet(nodeWriter); |
260 writeEdges(); |
327 writeEdgeSet(nodeWriter, edgeWriter); |
|
328 writeNodes(nodeWriter); |
|
329 writeEdges(edgeWriter); |
261 os << "@end" << std::endl; |
330 os << "@end" << std::endl; |
262 } |
331 } |
263 |
332 |
264 private: |
333 private: |
265 |
|
266 void writeNodeSet() { |
|
267 if (node_map_writers.size() == 0) return; |
|
268 os << "@nodeset" << std::endl; |
|
269 for (int i = 0; i < (int)node_map_writers.size(); ++i) { |
|
270 os << node_map_writers[i].first << '\t'; |
|
271 } |
|
272 os << std::endl; |
|
273 for (NodeIt it(graph); it != INVALID; ++it) { |
|
274 for (int i = 0; i < (int)node_map_writers.size(); ++i) { |
|
275 node_map_writers[i].second->write(os, it); |
|
276 } |
|
277 os << std::endl; |
|
278 } |
|
279 |
|
280 } |
|
281 |
|
282 void writeEdgeSet() { |
|
283 if (edge_map_writers.size() == 0) return; |
|
284 if (node_map_writers.size() == 0) { |
|
285 // ErrorMessage message; |
|
286 // message << "Missing node id map"; |
|
287 // throw IOLogicError(message); |
|
288 } |
|
289 os << "@edgeset" << std::endl; |
|
290 os << "\t\t"; |
|
291 for (int i = 0; i < (int)edge_map_writers.size(); ++i) { |
|
292 os << edge_map_writers[i].first << '\t'; |
|
293 } |
|
294 os << std::endl; |
|
295 for (EdgeIt it(graph); it != INVALID; ++it) { |
|
296 node_map_writers[0].second->write(os, graph.source(it)); |
|
297 node_map_writers[0].second->write(os, graph.target(it)); |
|
298 for (int i = 0; i < (int)edge_map_writers.size(); ++i) { |
|
299 edge_map_writers[i].second->write(os, it); |
|
300 } |
|
301 os << std::endl; |
|
302 } |
|
303 } |
|
304 |
|
305 void writeNodes() { |
|
306 if (node_writers.size() == 0) return; |
|
307 if (node_map_writers.size() == 0) { |
|
308 // throw Exception() << "Missing node id map"; |
|
309 } |
|
310 os << "@nodes" << std::endl; |
|
311 for (int i = 0; i < (int)node_writers.size(); ++i) { |
|
312 os << node_writers[i].first << '\t'; |
|
313 node_map_writers[0].second->write(os, node_writers[i].second); |
|
314 os << std::endl; |
|
315 } |
|
316 } |
|
317 |
|
318 void writeEdges() { |
|
319 if (edge_writers.size() == 0) return; |
|
320 if (edge_map_writers.size() == 0) { |
|
321 // throw Exception() << "Missing edge id map"; |
|
322 } |
|
323 os << "@edges" << std::endl; |
|
324 for (int i = 0; i < (int)edge_writers.size(); ++i) { |
|
325 os << edge_writers[i].first << '\t'; |
|
326 edge_map_writers[0].second->write(os, edge_writers[i].second); |
|
327 os << std::endl; |
|
328 } |
|
329 } |
|
330 |
|
331 // Writers |
|
332 |
334 |
333 template <class _Item> |
335 template <class _Item> |
334 class WriterBase { |
336 class WriterBase { |
335 public: |
337 public: |
336 typedef _Item Item; |
338 typedef _Item Item; |
356 writer.write(os, map[item]); |
358 writer.write(os, map[item]); |
357 } |
359 } |
358 |
360 |
359 }; |
361 }; |
360 |
362 |
|
363 void writeNodeSet(WriterBase<Node>* & nodeWriter) { |
|
364 if (node_map_writers.size() == 0) return; |
|
365 os << "@nodeset" << std::endl; |
|
366 for (int i = 0; i < (int)node_map_writers.size(); ++i) { |
|
367 const std::string& id = node_map_writers[i].first; |
|
368 os << id << '\t'; |
|
369 if (WriterTraits::idMapName(id) && nodeWriter == 0) { |
|
370 nodeWriter = node_map_writers[i].second; |
|
371 } |
|
372 } |
|
373 os << std::endl; |
|
374 for (NodeIt it(graph); it != INVALID; ++it) { |
|
375 for (int i = 0; i < (int)node_map_writers.size(); ++i) { |
|
376 node_map_writers[i].second->write(os, it); |
|
377 } |
|
378 os << std::endl; |
|
379 } |
|
380 |
|
381 } |
|
382 |
|
383 void writeEdgeSet(WriterBase<Node>* nodeWriter, |
|
384 WriterBase<Edge>* & edgeWriter) { |
|
385 if (nodeWriter == 0) { |
|
386 throw DataFormatError("Cannot find node id map"); |
|
387 } |
|
388 os << "@edgeset" << std::endl; |
|
389 os << "\t\t"; |
|
390 for (int i = 0; i < (int)edge_map_writers.size(); ++i) { |
|
391 const std::string& id = edge_map_writers[i].first; |
|
392 os << id << '\t'; |
|
393 if (WriterTraits::idMapName(id) && edgeWriter == 0) { |
|
394 edgeWriter = edge_map_writers[i].second; |
|
395 } |
|
396 } |
|
397 os << std::endl; |
|
398 for (EdgeIt it(graph); it != INVALID; ++it) { |
|
399 nodeWriter->write(os, graph.source(it)); |
|
400 nodeWriter->write(os, graph.target(it)); |
|
401 for (int i = 0; i < (int)edge_map_writers.size(); ++i) { |
|
402 edge_map_writers[i].second->write(os, it); |
|
403 } |
|
404 os << std::endl; |
|
405 } |
|
406 } |
|
407 |
|
408 void writeNodes(WriterBase<Node>* nodeWriter) { |
|
409 if (nodeWriter == 0) { |
|
410 throw DataFormatError("Cannot find node id map"); |
|
411 } |
|
412 os << "@nodes" << std::endl; |
|
413 for (int i = 0; i < (int)node_writers.size(); ++i) { |
|
414 os << node_writers[i].first << '\t'; |
|
415 nodeWriter->write(os, node_writers[i].second); |
|
416 os << std::endl; |
|
417 } |
|
418 } |
|
419 |
|
420 void writeEdges(WriterBase<Edge>* edgeWriter) { |
|
421 if (edgeWriter == 0) { |
|
422 throw DataFormatError("Cannot find node id map"); |
|
423 } |
|
424 os << "@edges" << std::endl; |
|
425 for (int i = 0; i < (int)edge_writers.size(); ++i) { |
|
426 os << edge_writers[i].first << '\t'; |
|
427 edgeWriter->write(os, edge_writers[i].second); |
|
428 os << std::endl; |
|
429 } |
|
430 } |
|
431 |
|
432 |
361 |
433 |
362 |
434 |
363 typedef std::vector< std::pair<std::string, WriterBase<Node>*> > |
435 typedef std::vector< std::pair<std::string, WriterBase<Node>*> > |
364 NodeMapWriters; |
436 NodeMapWriters; |
365 NodeMapWriters node_map_writers; |
437 NodeMapWriters node_map_writers; |
377 std::ostream& os; |
449 std::ostream& os; |
378 const Graph& graph; |
450 const Graph& graph; |
379 |
451 |
380 }; |
452 }; |
381 |
453 |
382 /// Ready to use writer function. |
454 /// \brief Write a graph to the output. |
|
455 /// |
|
456 /// Write a graph to the output. |
|
457 /// \param os The output stream. |
|
458 /// \param g The graph. |
|
459 /// \param capacity The capacity map. |
|
460 /// \param s The source node. |
|
461 /// \param t The target node. |
|
462 /// \param cost The cost map. |
383 template<typename Graph, typename CapacityMap, typename CostMap> |
463 template<typename Graph, typename CapacityMap, typename CostMap> |
384 void writeGraph(std::ostream& os, const Graph &g, |
464 void writeGraph(std::ostream& os, const Graph &g, |
385 const CapacityMap& capacity, const typename Graph::Node &s, |
465 const CapacityMap& capacity, const typename Graph::Node &s, |
386 const typename Graph::Node &t, const CostMap& cost) { |
466 const typename Graph::Node &t, const CostMap& cost) { |
387 GraphWriter<Graph> reader(os, g); |
467 GraphWriter<Graph> reader(os, g); |
394 reader.addNode("source", s); |
474 reader.addNode("source", s); |
395 reader.addNode("target", t); |
475 reader.addNode("target", t); |
396 reader.run(); |
476 reader.run(); |
397 } |
477 } |
398 |
478 |
399 /// Ready to use writer function. |
479 /// \brief Write a graph to the output. |
|
480 /// |
|
481 /// Write a graph to the output. |
|
482 /// \param os The output stream. |
|
483 /// \param g The graph. |
|
484 /// \param capacity The capacity map. |
|
485 /// \param s The source node. |
|
486 /// \param t The target node. |
400 template<typename Graph, typename CapacityMap> |
487 template<typename Graph, typename CapacityMap> |
401 void writeGraph(std::ostream& os, const Graph &g, |
488 void writeGraph(std::ostream& os, const Graph &g, |
402 const CapacityMap& capacity, const typename Graph::Node &s, |
489 const CapacityMap& capacity, const typename Graph::Node &s, |
403 const typename Graph::Node &t) { |
490 const typename Graph::Node &t) { |
404 GraphWriter<Graph> reader(os, g); |
491 GraphWriter<Graph> reader(os, g); |
410 reader.addNode("source", s); |
497 reader.addNode("source", s); |
411 reader.addNode("target", t); |
498 reader.addNode("target", t); |
412 reader.run(); |
499 reader.run(); |
413 } |
500 } |
414 |
501 |
415 /// Ready to use writer function. |
502 /// \brief Write a graph to the output. |
|
503 /// |
|
504 /// Write a graph to the output. |
|
505 /// \param os The output stream. |
|
506 /// \param g The graph. |
|
507 /// \param capacity The capacity map. |
|
508 /// \param s The source node. |
416 template<typename Graph, typename CapacityMap> |
509 template<typename Graph, typename CapacityMap> |
417 void writeGraph(std::ostream& os, const Graph &g, |
510 void writeGraph(std::ostream& os, const Graph &g, |
418 const CapacityMap& capacity, const typename Graph::Node &s) { |
511 const CapacityMap& capacity, const typename Graph::Node &s) { |
419 GraphWriter<Graph> reader(os, g); |
512 GraphWriter<Graph> reader(os, g); |
420 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
513 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
423 reader.addEdgeMap("id", edgeIdMap); |
516 reader.addEdgeMap("id", edgeIdMap); |
424 reader.addEdgeMap("capacity", capacity); |
517 reader.addEdgeMap("capacity", capacity); |
425 reader.addNode("source", s); |
518 reader.addNode("source", s); |
426 reader.run(); |
519 reader.run(); |
427 } |
520 } |
428 /// Ready to use writer function. |
521 |
|
522 /// \brief Write a graph to the output. |
|
523 /// |
|
524 /// Write a graph to the output. |
|
525 /// \param os The output stream. |
|
526 /// \param g The graph. |
|
527 /// \param capacity The capacity map. |
429 template<typename Graph, typename CapacityMap> |
528 template<typename Graph, typename CapacityMap> |
430 void writeGraph(std::ostream& os, const Graph &g, |
529 void writeGraph(std::ostream& os, const Graph &g, |
431 const CapacityMap& capacity) { |
530 const CapacityMap& capacity) { |
432 GraphWriter<Graph> reader(os, g); |
531 GraphWriter<Graph> reader(os, g); |
433 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
532 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
435 IdMap<Graph, typename Graph::Edge> edgeIdMap(g); |
534 IdMap<Graph, typename Graph::Edge> edgeIdMap(g); |
436 reader.addEdgeMap("id", edgeIdMap); |
535 reader.addEdgeMap("id", edgeIdMap); |
437 reader.addEdgeMap("capacity", capacity); |
536 reader.addEdgeMap("capacity", capacity); |
438 reader.run(); |
537 reader.run(); |
439 } |
538 } |
440 /// Ready to use writer function. |
539 |
|
540 /// \brief Write a graph to the output. |
|
541 /// |
|
542 /// Write a graph to the output. |
|
543 /// \param os The output stream. |
|
544 /// \param g The graph. |
441 template<typename Graph> |
545 template<typename Graph> |
442 void writeGraph(std::ostream& os, const Graph &g) { |
546 void writeGraph(std::ostream& os, const Graph &g) { |
443 GraphWriter<Graph> reader(os, g); |
547 GraphWriter<Graph> reader(os, g); |
444 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
548 IdMap<Graph, typename Graph::Node> nodeIdMap(g); |
445 reader.addNodeMap("id", nodeIdMap); |
549 reader.addNodeMap("id", nodeIdMap); |
446 IdMap<Graph, typename Graph::Edge> edgeIdMap(g); |
550 IdMap<Graph, typename Graph::Edge> edgeIdMap(g); |
447 reader.addEdgeMap("id", edgeIdMap); |
551 reader.addEdgeMap("id", edgeIdMap); |
448 reader.run(); |
552 reader.run(); |
449 } |
553 } |
450 |
554 |
|
555 /// @} |
451 |
556 |
452 } |
557 } |
453 |
558 |
454 #endif |
559 #endif |