src/lemon/graph_writer.h
changeset 1333 2640cf6547ff
parent 1311 b810a07248a0
child 1343 a81f9cfc9775
equal deleted inserted replaced
8:411524653e75 9:c8bbf2f05176
    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