2 * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
19 ///\brief Lemon Graph Format writer.
21 #ifndef LEMON_GRAPH_WRITER_H
22 #define LEMON_GRAPH_WRITER_H
32 #include <lemon/map_utils.h>
34 #include <lemon/invalid.h>
35 #include <lemon/error.h>
40 /// \addtogroup io_group
43 /// \brief Standard WriterTraits for the GraphWriter class.
45 /// Standard WriterTraits for the GraphWriter class.
46 /// It defines standard writing method for all type of value.
47 /// \author Balazs Dezso
48 struct DefaultWriterTraits {
50 /// \brief Template class for writing an value.
52 /// Template class for writing an value.
53 /// \author Balazs Dezso
54 template <typename _Value>
59 /// \brief Writes a value to the given stream.
61 /// Writes a value to the given stream.
62 void write(std::ostream& os, const Value& value) {
67 /// \brief Returns wheter this name is an ID map name.
69 /// Returns wheter this name is an ID map name.
70 static bool idMapName(const std::string& name) {
77 /// \brief Writer class for quoted strings.
79 /// Writer class for quoted strings. It can process the escape
80 /// sequences in the string.
81 /// \author Balazs Dezso
82 class QuotedStringWriter {
84 typedef std::string Value;
86 /// \brief Constructor for the writer.
88 /// Constructor for the writer. If the given parameter is true
89 /// the writer creates escape sequences from special characters.
90 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
92 /// \brief Writes a quoted string to the given stream.
94 /// Writes a quoted string to the given stream.
95 void write(std::ostream& os, const std::string& value) {
98 std::ostringstream ls;
99 for (int i = 0; i < (int)value.size(); ++i) {
100 writeEscape(ls, value[i]);
111 static void writeEscape(std::ostream& os, char c) {
148 os << '\\' << std::oct << (int)c;
161 virtual void write(std::ostream& os) = 0;
165 /// \brief The graph writer class.
167 /// The \c GraphWriter class provides the graph output. To write a graph
168 /// you should first give writing commands for the writer. You can declare
169 /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and
173 /// GraphWriter<ListGraph> writer(std::cout, graph);
176 /// The \c writeNodeMap() function declares a \c NodeMap writing
177 /// command in the \c GraphWriter. You should give as parameter
178 /// the name of the map and the map object. The NodeMap writing
179 /// command with name "id" should write a unique map because it
180 /// is regarded as ID map.
183 /// IdMap<ListGraph, Node> nodeIdMap;
184 /// writer.writeNodeMap("id", nodeIdMap);
186 /// writer.writeNodeMap("x-coord", xCoordMap);
187 /// writer.writeNodeMap("y-coord", yCoordMap);
188 /// writer.writeNodeMap("color", colorMap);
191 /// With the \c writeEdgeMap() member function you can give an edge map
192 /// writing command similar to the NodeMaps.
195 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
196 /// edgeDescMap(graph);
197 /// writer.writeEdgeMap("descriptor", edgeDescMap);
199 /// writer.writeEdgeMap("weight", weightMap);
200 /// writer.writeEdgeMap("label", labelMap);
203 /// With \c writeNode() and \c writeEdge() functions you can
204 /// point out Nodes and Edges in the graph. By example, you can
205 /// write out the source and target of the graph.
208 /// writer.writeNode("source", sourceNode);
209 /// writer.writeNode("target", targetNode);
211 /// writer.writeEdge("observed", edge);
214 /// After you give all write commands you must call the \c run() member
215 /// function, which execute all the writer commands.
221 /// \see DefaultWriterTraits
222 /// \see QuotedStringWriter
224 /// \see DescriptorMap
225 /// \see \ref GraphWriter
226 /// \see \ref graph-io-page
227 /// \author Balazs Dezso
228 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
232 typedef _Graph Graph;
233 typedef typename Graph::Node Node;
234 typedef typename Graph::NodeIt NodeIt;
235 typedef typename Graph::Edge Edge;
236 typedef typename Graph::EdgeIt EdgeIt;
238 typedef _WriterTraits WriterTraits;
240 /// \brief Construct a new GraphWriter.
242 /// Construct a new GraphWriter. It writes from the given map,
243 /// it constructs the given map and it use the given writer as the
245 GraphWriter(std::ostream& _os, const Graph& _graph)
246 : gui_writer(0), os(_os), graph(_graph){}
249 /// \brief Destruct the graph writer.
251 /// Destruct the graph writer.
253 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
254 it != node_map_writers.end(); ++it) {
258 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
259 it != edge_map_writers.end(); ++it) {
267 /// \brief Add a new node map writer command for the writer.
269 /// Add a new node map writer command for the writer.
270 template <typename Map>
271 GraphWriter& writeNodeMap(std::string name, const Map& map) {
272 return writeNodeMap<typename WriterTraits::template Writer<
273 typename Map::Value>, Map>(name, map);
276 /// \brief Add a new node map writer command for the writer.
278 /// Add a new node map writer command for the writer.
279 template <typename Writer, typename Map>
280 GraphWriter& writeNodeMap(std::string name, const Map& map,
281 const Writer& writer = Writer()) {
282 node_map_writers.push_back(
283 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
289 /// \brief Add a new edge map writer command for the writer.
291 /// Add a new edge map writer command for the writer.
292 template <typename Map>
293 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
294 return writeEdgeMap<typename WriterTraits::template Writer<
295 typename Map::Value>, Map>(name, map);
299 /// \brief Add a new edge map writer command for the writer.
301 /// Add a new edge map writer command for the writer.
302 template <typename Writer, typename Map>
303 GraphWriter& writeEdgeMap(std::string name,
304 const Map& map, const Writer& writer = Writer()) {
305 edge_map_writers.push_back(make_pair(name,
306 new MapWriter<Edge, Map, Writer>(map, writer)));
310 /// \brief Add a new labeled node writer for the writer.
312 /// Add a new labeled node writer for the writer.
313 GraphWriter& writeNode(std::string name, const Node& node) {
314 node_writers.push_back(make_pair(name, node));
318 /// \brief Add a new labeled edge writer for the writer.
320 /// Add a new labeled edge writer for the writer.
321 GraphWriter& writeEdge(std::string name, const Edge& edge) {
322 edge_writers.push_back(make_pair(name, edge));
326 GraphWriter& writeGUI(const GUIWriter& writer) {
327 gui_writer = &writer;
330 /// \brief Executes the writer commands.
332 /// Executes the writer commands.
334 WriterBase<Node>* nodeWriter = 0;
335 WriterBase<Edge>* edgeWriter = 0;
336 writeNodeSet(nodeWriter);
337 writeEdgeSet(nodeWriter, edgeWriter);
338 writeNodes(nodeWriter);
339 writeEdges(edgeWriter);
341 os << "@end" << std::endl;
346 template <class _Item>
350 virtual void write(std::ostream&, const Item&) = 0;
353 template <class _Item, typename _Map, typename _Writer>
354 class MapWriter : public WriterBase<_Item> {
357 typedef _Writer Writer;
358 typedef typename Writer::Value Value;
364 MapWriter(const Map& _map, const Writer& _writer)
365 : map(_map), writer(_writer) {}
368 virtual void write(std::ostream& os, const Item& item) {
369 writer.write(os, map[item]);
374 void writeNodeSet(WriterBase<Node>* & nodeWriter) {
375 if (node_map_writers.size() == 0) return;
376 os << "@nodeset" << std::endl;
377 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
378 const std::string& id = node_map_writers[i].first;
380 if (WriterTraits::idMapName(id) && nodeWriter == 0) {
381 nodeWriter = node_map_writers[i].second;
385 for (NodeIt it(graph); it != INVALID; ++it) {
386 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
387 node_map_writers[i].second->write(os, it);
394 void writeEdgeSet(WriterBase<Node>* nodeWriter,
395 WriterBase<Edge>* & edgeWriter) {
396 if (edge_map_writers.size() == 0) return;
397 if (nodeWriter == 0) {
398 throw DataFormatError("Cannot find node id map");
400 os << "@edgeset" << std::endl;
402 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
403 const std::string& id = edge_map_writers[i].first;
405 if (WriterTraits::idMapName(id) && edgeWriter == 0) {
406 edgeWriter = edge_map_writers[i].second;
410 for (EdgeIt it(graph); it != INVALID; ++it) {
411 nodeWriter->write(os, graph.source(it));
412 nodeWriter->write(os, graph.target(it));
413 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
414 edge_map_writers[i].second->write(os, it);
420 void writeNodes(WriterBase<Node>* nodeWriter) {
421 if (node_writers.size() == 0) return;
422 if (nodeWriter == 0) {
423 throw DataFormatError("Cannot find node id map");
425 os << "@nodes" << std::endl;
426 for (int i = 0; i < (int)node_writers.size(); ++i) {
427 os << node_writers[i].first << '\t';
428 nodeWriter->write(os, node_writers[i].second);
433 void writeEdges(WriterBase<Edge>* edgeWriter) {
434 if (edge_writers.size() == 0) return;
435 if (edgeWriter == 0) {
436 throw DataFormatError("Cannot find node id map");
438 os << "@edges" << std::endl;
439 for (int i = 0; i < (int)edge_writers.size(); ++i) {
440 os << edge_writers[i].first << '\t';
441 edgeWriter->write(os, edge_writers[i].second);
448 os << "@gui" << std::endl;
449 gui_writer->write(os);
455 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
457 NodeMapWriters node_map_writers;
459 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
461 EdgeMapWriters edge_map_writers;
463 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
464 NodeWriters node_writers;
466 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
467 EdgeWriters edge_writers;
469 GUIWriter* gui_writer;
476 /// \brief Write a graph to the output.
478 /// Write a graph to the output.
479 /// \param os The output stream.
480 /// \param g The graph.
481 /// \param capacity The capacity map.
482 /// \param s The source node.
483 /// \param t The target node.
484 /// \param cost The cost map.
485 template<typename Graph, typename CapacityMap, typename CostMap>
486 void writeGraph(std::ostream& os, const Graph &g,
487 const CapacityMap& capacity, const typename Graph::Node &s,
488 const typename Graph::Node &t, const CostMap& cost) {
489 GraphWriter<Graph> writer(os, g);
490 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
491 writer.writeNodeMap("id", nodeIdMap);
492 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
493 writer.writeEdgeMap("id", edgeIdMap);
494 writer.writeEdgeMap("capacity", capacity);
495 writer.writeEdgeMap("cost", cost);
496 writer.writeNode("source", s);
497 writer.writeNode("target", t);
501 /// \brief Write a graph to the output.
503 /// Write a graph to the output.
504 /// \param os The output stream.
505 /// \param g The graph.
506 /// \param capacity The capacity map.
507 /// \param s The source node.
508 /// \param t The target node.
509 template<typename Graph, typename CapacityMap>
510 void writeGraph(std::ostream& os, const Graph &g,
511 const CapacityMap& capacity, const typename Graph::Node &s,
512 const typename Graph::Node &t) {
513 GraphWriter<Graph> writer(os, g);
514 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
515 writer.writeNodeMap("id", nodeIdMap);
516 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
517 writer.writeEdgeMap("id", edgeIdMap);
518 writer.writeEdgeMap("capacity", capacity);
519 writer.writeNode("source", s);
520 writer.writeNode("target", t);
524 /// \brief Write a graph to the output.
526 /// Write a graph to the output.
527 /// \param os The output stream.
528 /// \param g The graph.
529 /// \param capacity The capacity map.
530 /// \param s The source node.
531 template<typename Graph, typename CapacityMap>
532 void writeGraph(std::ostream& os, const Graph &g,
533 const CapacityMap& capacity, const typename Graph::Node &s) {
534 GraphWriter<Graph> writer(os, g);
535 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
536 writer.writeNodeMap("id", nodeIdMap);
537 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
538 writer.writeEdgeMap("id", edgeIdMap);
539 writer.writeEdgeMap("capacity", capacity);
540 writer.writeNode("source", s);
544 /// \brief Write a graph to the output.
546 /// Write a graph to the output.
547 /// \param os The output stream.
548 /// \param g The graph.
549 /// \param capacity The capacity map.
550 template<typename Graph, typename CapacityMap>
551 void writeGraph(std::ostream& os, const Graph &g,
552 const CapacityMap& capacity) {
553 GraphWriter<Graph> writer(os, g);
554 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
555 writer.writeNodeMap("id", nodeIdMap);
556 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
557 writer.writeEdgeMap("id", edgeIdMap);
558 writer.writeEdgeMap("capacity", capacity);
562 /// \brief Write a graph to the output.
564 /// Write a graph to the output.
565 /// \param os The output stream.
566 /// \param g The graph.
567 template<typename Graph>
568 void writeGraph(std::ostream& os, const Graph &g) {
569 GraphWriter<Graph> writer(os, g);
570 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
571 writer.writeNodeMap("id", nodeIdMap);
572 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
573 writer.writeEdgeMap("id", edgeIdMap);