A little has been done. Some important questions arised.
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 Combinatorial Optimization Research Group, 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 (nodeWriter == 0) {
386 throw DataFormatError("Cannot find node id map");
388 os << "@edgeset" << std::endl;
390 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
391 const std::string& id = edge_map_writers[i].first;
393 if (WriterTraits::idMapName(id) && edgeWriter == 0) {
394 edgeWriter = edge_map_writers[i].second;
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);
408 void writeNodes(WriterBase<Node>* nodeWriter) {
409 if (nodeWriter == 0) {
410 throw DataFormatError("Cannot find node id map");
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);
420 void writeEdges(WriterBase<Edge>* edgeWriter) {
421 if (edgeWriter == 0) {
422 throw DataFormatError("Cannot find node id map");
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);
435 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
437 NodeMapWriters node_map_writers;
439 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
441 EdgeMapWriters edge_map_writers;
443 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
444 NodeWriters node_writers;
446 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
447 EdgeWriters edge_writers;
454 /// \brief Write a graph to the output.
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.
463 template<typename Graph, typename CapacityMap, typename CostMap>
464 void writeGraph(std::ostream& os, const Graph &g,
465 const CapacityMap& capacity, const typename Graph::Node &s,
466 const typename Graph::Node &t, const CostMap& cost) {
467 GraphWriter<Graph> reader(os, g);
468 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
469 reader.addNodeMap("id", nodeIdMap);
470 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
471 reader.addEdgeMap("id", edgeIdMap);
472 reader.addEdgeMap("capacity", capacity);
473 reader.addEdgeMap("cost", cost);
474 reader.addNode("source", s);
475 reader.addNode("target", t);
479 /// \brief Write a graph to the output.
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.
487 template<typename Graph, typename CapacityMap>
488 void writeGraph(std::ostream& os, const Graph &g,
489 const CapacityMap& capacity, const typename Graph::Node &s,
490 const typename Graph::Node &t) {
491 GraphWriter<Graph> reader(os, g);
492 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
493 reader.addNodeMap("id", nodeIdMap);
494 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
495 reader.addEdgeMap("id", edgeIdMap);
496 reader.addEdgeMap("capacity", capacity);
497 reader.addNode("source", s);
498 reader.addNode("target", t);
502 /// \brief Write a graph to the output.
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.
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 GraphWriter<Graph> reader(os, g);
513 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
514 reader.addNodeMap("id", nodeIdMap);
515 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
516 reader.addEdgeMap("id", edgeIdMap);
517 reader.addEdgeMap("capacity", capacity);
518 reader.addNode("source", s);
522 /// \brief Write a graph to the output.
524 /// Write a graph to the output.
525 /// \param os The output stream.
526 /// \param g The graph.
527 /// \param capacity The capacity map.
528 template<typename Graph, typename CapacityMap>
529 void writeGraph(std::ostream& os, const Graph &g,
530 const CapacityMap& capacity) {
531 GraphWriter<Graph> reader(os, g);
532 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
533 reader.addNodeMap("id", nodeIdMap);
534 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
535 reader.addEdgeMap("id", edgeIdMap);
536 reader.addEdgeMap("capacity", capacity);
540 /// \brief Write a graph to the output.
542 /// Write a graph to the output.
543 /// \param os The output stream.
544 /// \param g The graph.
545 template<typename Graph>
546 void writeGraph(std::ostream& os, const Graph &g) {
547 GraphWriter<Graph> reader(os, g);
548 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
549 reader.addNodeMap("id", nodeIdMap);
550 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
551 reader.addEdgeMap("id", edgeIdMap);