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;
160 /// \brief The graph writer class.
162 /// The \c GraphWriter class provides the graph output. To write a graph
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
168 /// GraphWriter<ListGraph> writer(std::cout, graph);
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.
177 /// IdMap<ListGraph, Node> nodeIdMap;
178 /// writer.addNodeMap("id", nodeIdMap);
180 /// writer.addNodeMap("x-coord", xCoordMap);
181 /// writer.addNodeMap("y-coord", yCoordMap);
182 /// writer.addNodeMap("color", colorMap);
185 /// With the \c addEdgeMap() member function you can give an edge map
186 /// writing command similar to the NodeMaps.
189 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
190 /// edgeDescMap(graph);
191 /// writer.addEdgeMap("descriptor", edgeDescMap);
193 /// writer.addEdgeMap("weight", weightMap);
194 /// writer.addEdgeMap("label", labelMap);
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
202 /// writer.addNode("source", sourceNode);
203 /// writer.addNode("target", targetNode);
205 /// writer.addEdge("observed", edge);
208 /// After you give all write commands you must call the \c run() member
209 /// function, which execute all the writer commands.
215 /// \see DefaultWriterTraits
216 /// \see QuotedStringWriter
218 /// \see DescriptorMap
219 /// \see \ref GraphReader
220 /// \see \ref graph-io-page
221 /// \author Balazs Dezso
222 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
226 typedef _Graph Graph;
227 typedef typename Graph::Node Node;
228 typedef typename Graph::NodeIt NodeIt;
229 typedef typename Graph::Edge Edge;
230 typedef typename Graph::EdgeIt EdgeIt;
232 typedef _WriterTraits WriterTraits;
234 /// \brief Construct a new GraphWriter.
236 /// Construct a new GraphWriter. It writes from the given map,
237 /// it constructs the given map and it use the given writer as the
239 GraphWriter(std::ostream& _os, const Graph& _graph)
240 : os(_os), graph(_graph) {}
243 /// \brief Destruct the graph writer.
245 /// Destruct the graph writer.
247 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
248 it != node_map_writers.end(); ++it) {
252 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
253 it != edge_map_writers.end(); ++it) {
261 /// \brief Add a new node map writer command for the writer.
263 /// Add a new node map writer command for the writer.
264 template <typename Map>
265 GraphWriter& addNodeMap(std::string name, const Map& map) {
266 return addNodeMap<typename WriterTraits::template Writer<
267 typename Map::Value>, Map>(name, map);
270 /// \brief Add a new node map writer command for the writer.
272 /// Add a new node map writer command for the writer.
273 template <typename Writer, typename Map>
274 GraphWriter& addNodeMap(std::string name, const Map& map,
275 const Writer& writer = Writer()) {
276 node_map_writers.push_back(
277 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
283 /// \brief Add a new edge map writer command for the writer.
285 /// Add a new edge map writer command for the writer.
286 template <typename Map>
287 GraphWriter& addEdgeMap(std::string name, const Map& map) {
288 return addEdgeMap<typename WriterTraits::template Writer<
289 typename Map::Value>, Map>(name, map);
293 /// \brief Add a new edge map writer command for the writer.
295 /// Add a new edge map writer command for the writer.
296 template <typename Writer, typename Map>
297 GraphWriter& addEdgeMap(std::string name,
298 const Map& map, const Writer& writer = Writer()) {
299 edge_map_writers.push_back(make_pair(name,
300 new MapWriter<Edge, Map, Writer>(map, writer)));
304 /// \brief Add a new labeled node writer for the writer.
306 /// Add a new labeled node writer for the writer.
307 GraphWriter& addNode(std::string name, const Node& node) {
308 node_writers.push_back(make_pair(name, node));
312 /// \brief Add a new labeled edge writer for the writer.
314 /// Add a new labeled edge writer for the writer.
315 GraphWriter& addEdge(std::string name, const Edge& edge) {
316 edge_writers.push_back(make_pair(name, edge));
320 /// \brief Executes the writer commands.
322 /// Executes the writer commands.
324 WriterBase<Node>* nodeWriter = 0;
325 WriterBase<Edge>* edgeWriter = 0;
326 writeNodeSet(nodeWriter);
327 writeEdgeSet(nodeWriter, edgeWriter);
328 writeNodes(nodeWriter);
329 writeEdges(edgeWriter);
330 os << "@end" << std::endl;
335 template <class _Item>
339 virtual void write(std::ostream&, const Item&) = 0;
342 template <class _Item, typename _Map, typename _Writer>
343 class MapWriter : public WriterBase<_Item> {
346 typedef _Writer Writer;
347 typedef typename Writer::Value Value;
353 MapWriter(const Map& _map, const Writer& _writer)
354 : map(_map), writer(_writer) {}
357 virtual void write(std::ostream& os, const Item& item) {
358 writer.write(os, map[item]);
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;
369 if (WriterTraits::idMapName(id) && nodeWriter == 0) {
370 nodeWriter = node_map_writers[i].second;
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);
383 void writeEdgeSet(WriterBase<Node>* nodeWriter,
384 WriterBase<Edge>* & edgeWriter) {
385 if (edge_map_writers.size() == 0) return;
386 if (nodeWriter == 0) {
387 throw DataFormatError("Cannot find node id map");
389 os << "@edgeset" << std::endl;
391 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
392 const std::string& id = edge_map_writers[i].first;
394 if (WriterTraits::idMapName(id) && edgeWriter == 0) {
395 edgeWriter = edge_map_writers[i].second;
399 for (EdgeIt it(graph); it != INVALID; ++it) {
400 nodeWriter->write(os, graph.source(it));
401 nodeWriter->write(os, graph.target(it));
402 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
403 edge_map_writers[i].second->write(os, it);
409 void writeNodes(WriterBase<Node>* nodeWriter) {
410 if (node_writers.size() == 0) return;
411 if (nodeWriter == 0) {
412 throw DataFormatError("Cannot find node id map");
414 os << "@nodes" << std::endl;
415 for (int i = 0; i < (int)node_writers.size(); ++i) {
416 os << node_writers[i].first << '\t';
417 nodeWriter->write(os, node_writers[i].second);
422 void writeEdges(WriterBase<Edge>* edgeWriter) {
423 if (edge_writers.size() == 0) return;
424 if (edgeWriter == 0) {
425 throw DataFormatError("Cannot find node id map");
427 os << "@edges" << std::endl;
428 for (int i = 0; i < (int)edge_writers.size(); ++i) {
429 os << edge_writers[i].first << '\t';
430 edgeWriter->write(os, edge_writers[i].second);
438 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
440 NodeMapWriters node_map_writers;
442 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
444 EdgeMapWriters edge_map_writers;
446 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
447 NodeWriters node_writers;
449 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
450 EdgeWriters edge_writers;
457 /// \brief Write a graph to the output.
459 /// Write a graph to the output.
460 /// \param os The output stream.
461 /// \param g The graph.
462 /// \param capacity The capacity map.
463 /// \param s The source node.
464 /// \param t The target node.
465 /// \param cost The cost map.
466 template<typename Graph, typename CapacityMap, typename CostMap>
467 void writeGraph(std::ostream& os, const Graph &g,
468 const CapacityMap& capacity, const typename Graph::Node &s,
469 const typename Graph::Node &t, const CostMap& cost) {
470 GraphWriter<Graph> reader(os, g);
471 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
472 reader.addNodeMap("id", nodeIdMap);
473 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
474 reader.addEdgeMap("id", edgeIdMap);
475 reader.addEdgeMap("capacity", capacity);
476 reader.addEdgeMap("cost", cost);
477 reader.addNode("source", s);
478 reader.addNode("target", t);
482 /// \brief Write a graph to the output.
484 /// Write a graph to the output.
485 /// \param os The output stream.
486 /// \param g The graph.
487 /// \param capacity The capacity map.
488 /// \param s The source node.
489 /// \param t The target node.
490 template<typename Graph, typename CapacityMap>
491 void writeGraph(std::ostream& os, const Graph &g,
492 const CapacityMap& capacity, const typename Graph::Node &s,
493 const typename Graph::Node &t) {
494 GraphWriter<Graph> reader(os, g);
495 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
496 reader.addNodeMap("id", nodeIdMap);
497 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
498 reader.addEdgeMap("id", edgeIdMap);
499 reader.addEdgeMap("capacity", capacity);
500 reader.addNode("source", s);
501 reader.addNode("target", t);
505 /// \brief Write a graph to the output.
507 /// Write a graph to the output.
508 /// \param os The output stream.
509 /// \param g The graph.
510 /// \param capacity The capacity map.
511 /// \param s The source node.
512 template<typename Graph, typename CapacityMap>
513 void writeGraph(std::ostream& os, const Graph &g,
514 const CapacityMap& capacity, const typename Graph::Node &s) {
515 GraphWriter<Graph> reader(os, g);
516 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
517 reader.addNodeMap("id", nodeIdMap);
518 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
519 reader.addEdgeMap("id", edgeIdMap);
520 reader.addEdgeMap("capacity", capacity);
521 reader.addNode("source", s);
525 /// \brief Write a graph to the output.
527 /// Write a graph to the output.
528 /// \param os The output stream.
529 /// \param g The graph.
530 /// \param capacity The capacity map.
531 template<typename Graph, typename CapacityMap>
532 void writeGraph(std::ostream& os, const Graph &g,
533 const CapacityMap& capacity) {
534 GraphWriter<Graph> reader(os, g);
535 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
536 reader.addNodeMap("id", nodeIdMap);
537 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
538 reader.addEdgeMap("id", edgeIdMap);
539 reader.addEdgeMap("capacity", capacity);
543 /// \brief Write a graph to the output.
545 /// Write a graph to the output.
546 /// \param os The output stream.
547 /// \param g The graph.
548 template<typename Graph>
549 void writeGraph(std::ostream& os, const Graph &g) {
550 GraphWriter<Graph> reader(os, g);
551 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
552 reader.addNodeMap("id", nodeIdMap);
553 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
554 reader.addEdgeMap("id", edgeIdMap);