src/lemon/graph_writer.h
author alpar
Fri, 08 Apr 2005 14:02:43 +0000
changeset 1324 eca073533990
parent 1297 fde0d12545c1
child 1333 2640cf6547ff
permissions -rw-r--r--
Only lp_xyz's are linked against -lglpk
     1 /* -*- C++ -*-
     2  * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     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.
    10  *
    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
    13  * purpose.
    14  *
    15  */
    16 
    17 ///\ingroup io_group
    18 ///\file
    19 ///\brief Lemon Graph Format writer.
    20 
    21 #ifndef LEMON_GRAPH_WRITER_H
    22 #define LEMON_GRAPH_WRITER_H
    23 
    24 #include <iostream>
    25 #include <sstream>
    26 
    27 #include <map>
    28 #include <vector>
    29 
    30 #include <memory>
    31 
    32 #include <lemon/map_utils.h>
    33 
    34 #include <lemon/invalid.h>
    35 #include <lemon/error.h>
    36 
    37 
    38 namespace lemon {
    39 
    40   /// \brief Standard WriterTraits for the GraphWriter class.
    41   ///
    42   /// Standard WriterTraits for the GraphWriter class.
    43   /// It defines standard writing method for all type of value. 
    44   struct DefaultWriterTraits {
    45 
    46     /// \brief Template class for writing an value.
    47     ///
    48     /// Template class for writing an value.
    49     template <typename _Value>
    50     struct Writer {
    51       /// The value type.
    52       typedef _Value Value;
    53 
    54       /// \brief Writes a value to the given stream.
    55       ///
    56       /// Writes a value to the given stream.
    57       void write(std::ostream& os, const Value& value) {
    58 	os << value << '\t';
    59       }
    60     };
    61 
    62   };
    63 
    64 
    65   /// \brief Writer class for quoted strings.
    66   ///
    67   /// Writer class for quoted strings. It can process the escape
    68   /// sequences in the string.
    69   class QuotedStringWriter {
    70   public:
    71     typedef std::string Value;
    72 
    73     /// \brief Constructor for the writer.
    74     ///
    75     /// Constructor for the writer. If the given parameter is true
    76     /// the writer creates escape sequences from special characters.
    77     QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
    78 
    79     /// \brief Writes a quoted string to the given stream.
    80     ///
    81     /// Writes a quoted string to the given stream.
    82     void write(std::ostream& os, const std::string& value) {
    83       os << "\"";
    84       if (escaped) {
    85 	std::ostringstream ls;
    86 	for (int i = 0; i < (int)value.size(); ++i) {
    87 	  writeEscape(ls, value[i]);
    88 	}
    89 	os << ls.str();
    90       } else {
    91 	os << value;
    92       }
    93       os << "\"";
    94     }
    95 
    96   private:
    97     
    98     static void writeEscape(std::ostream& os, char c) {
    99       switch (c) {
   100       case '\\':
   101 	os << "\\\\";
   102 	return;
   103       case '\"':
   104 	os << "\\\"";
   105 	return;
   106       case '\'':
   107 	os << "\\\'";
   108 	return;
   109       case '\?':
   110 	os << "\\\?";
   111 	return;
   112       case '\a':
   113 	os << "\\a";
   114 	return;
   115       case '\b':
   116 	os << "\\b";
   117 	return;
   118       case '\f':
   119 	os << "\\f";
   120 	return;
   121       case '\r':
   122 	os << "\\r";
   123 	return;
   124       case '\n':
   125 	os << "\\n";
   126 	return;
   127       case '\t':
   128 	os << "\\t";
   129 	return;
   130       case '\v':
   131 	os << "\\v";
   132 	return;
   133       default:
   134 	if (c < 0x20) {
   135 	  os << '\\' << std::oct << (int)c;
   136 	} else {
   137 	  os << c;
   138 	}
   139 	return;
   140       }     
   141     }
   142   private:
   143     bool escaped;
   144   };
   145 
   146   
   147   /// \brief The graph writer class.
   148   ///
   149   ///\ingroup io_group
   150   /// The writer class for the graph output.
   151   /// \see DefaultWriterTraits
   152   /// \see QuotedStringWriter
   153   /// \see \ref GraphReader
   154   /// \see \ref graph-io-page
   155   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   156   class GraphWriter {
   157   public:
   158     
   159     typedef _Graph Graph;
   160     typedef typename Graph::Node Node;
   161     typedef typename Graph::NodeIt NodeIt;
   162     typedef typename Graph::Edge Edge;
   163     typedef typename Graph::EdgeIt EdgeIt;
   164 
   165     typedef _WriterTraits WriterTraits;
   166  
   167     /// \brief Construct a new GraphWriter.
   168     ///
   169     /// Construct a new GraphWriter. It writes from the given map,
   170     /// it constructs the given map and it use the given writer as the
   171     /// default skipper.
   172     GraphWriter(std::ostream& _os, const Graph& _graph) 
   173       : os(_os), graph(_graph) {}
   174 
   175 
   176     /// \brief Destruct the graph writer.
   177     ///
   178     /// Destruct the graph writer.
   179     ~GraphWriter() {
   180       for (typename NodeMapWriters::iterator it = node_map_writers.begin(); 
   181 	   it != node_map_writers.end(); ++it) {
   182 	delete it->second;
   183       }
   184 
   185       for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
   186 	   it != edge_map_writers.end(); ++it) {
   187 	delete it->second;
   188       }
   189 
   190     }
   191 
   192     // Node map rules
   193 
   194     /// \brief Add a new node map writer command for the writer.
   195     ///
   196     /// Add a new node map writer command for the writer.
   197     template <typename Map>
   198     GraphWriter& addNodeMap(std::string name, const Map& map) {
   199       return addNodeMap<typename WriterTraits::template Writer<
   200 	typename Map::Value>, Map>(name, map);
   201     }
   202 
   203     /// \brief Add a new node map writer command for the writer.
   204     ///
   205     /// Add a new node map writer command for the writer.
   206     template <typename Writer, typename Map>
   207     GraphWriter& addNodeMap(std::string name, const Map& map, 
   208 			      const Writer& writer = Writer()) {
   209       node_map_writers.push_back(
   210         make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
   211       return *this;
   212     }
   213 
   214     // Edge map rules
   215 
   216     /// \brief Add a new edge map writer command for the writer.
   217     ///
   218     /// Add a new edge map writer command for the writer.
   219     template <typename Map>
   220     GraphWriter& addEdgeMap(std::string name, const Map& map) { 
   221       return addEdgeMap<typename WriterTraits::template Writer<
   222         typename Map::Value>, Map>(name, map);
   223     }
   224 
   225 
   226     /// \brief Add a new edge map writer command for the writer.
   227     ///
   228     /// Add a new edge map writer command for the writer.
   229     template <typename Writer, typename Map>
   230     GraphWriter& addEdgeMap(std::string name, 
   231 			    const Map& map, const Writer& writer = Writer()) {
   232       edge_map_writers.push_back(make_pair(name, 
   233 	new MapWriter<Edge, Map, Writer>(map, writer)));
   234       return *this;
   235     }
   236 
   237     /// \brief Add a new labeled node writer for the writer.
   238     ///
   239     /// Add a new labeled node writer for the writer.
   240     GraphWriter& addNode(std::string name, const Node& node) {
   241       node_writers.push_back(make_pair(name, node));
   242       return *this;
   243     }
   244 
   245     /// \brief Add a new labeled edge writer for the writer.
   246     ///
   247     /// Add a new labeled edge writer for the writer.
   248     GraphWriter& addEdge(std::string name, const Edge& edge) {
   249       edge_writers.push_back(make_pair(name, edge));
   250       return *this;
   251     }
   252 
   253     /// \brief Executes the writer commands.
   254     ///
   255     /// Executes the writer commands.
   256     void run() {   
   257       writeNodeSet();
   258       writeEdgeSet();
   259       writeNodes();
   260       writeEdges();
   261       os << "@end" << std::endl;
   262     }
   263 
   264   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 
   333     template <class _Item>
   334     class WriterBase {
   335     public:
   336       typedef _Item Item;
   337       virtual void write(std::ostream&, const Item&) = 0;
   338     };
   339 
   340     template <class _Item, typename _Map, typename _Writer>
   341     class MapWriter : public WriterBase<_Item> {
   342     public:
   343       typedef _Map Map;
   344       typedef _Writer Writer;
   345       typedef typename Writer::Value Value;
   346       typedef _Item Item;
   347       
   348       const Map& map;
   349       Writer writer;
   350 
   351       MapWriter(const Map& _map, const Writer& _writer) 
   352 	: map(_map), writer(_writer) {}
   353 
   354 
   355       virtual void write(std::ostream& os, const Item& item) {
   356 	writer.write(os, map[item]);
   357       }
   358 
   359     };
   360 
   361 
   362 
   363     typedef std::vector< std::pair<std::string, WriterBase<Node>*> > 
   364       NodeMapWriters;
   365     NodeMapWriters node_map_writers;
   366 
   367     typedef std::vector< std::pair<std::string, WriterBase<Edge>*> > 
   368       EdgeMapWriters;
   369     EdgeMapWriters edge_map_writers;
   370 
   371     typedef std::vector<std::pair<std::string, Node> > NodeWriters;
   372     NodeWriters node_writers;
   373 
   374     typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
   375     EdgeWriters edge_writers;
   376 
   377     std::ostream& os;
   378     const Graph& graph;
   379 
   380   };
   381 
   382   /// Ready to use writer function.  
   383   template<typename Graph, typename CapacityMap, typename CostMap>
   384   void writeGraph(std::ostream& os, const Graph &g, 
   385 		  const CapacityMap& capacity, const typename Graph::Node &s,
   386 		  const typename Graph::Node &t, const CostMap& cost) {
   387     GraphWriter<Graph> reader(os, g);
   388     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   389     reader.addNodeMap("id", nodeIdMap);
   390     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   391     reader.addEdgeMap("id", edgeIdMap);
   392     reader.addEdgeMap("capacity", capacity);
   393     reader.addEdgeMap("cost", cost);
   394     reader.addNode("source", s);
   395     reader.addNode("target", t);
   396     reader.run();
   397   }
   398 
   399   /// Ready to use writer function.  
   400   template<typename Graph, typename CapacityMap>
   401   void writeGraph(std::ostream& os, const Graph &g, 
   402 		  const CapacityMap& capacity, const typename Graph::Node &s,
   403 		  const typename Graph::Node &t) {
   404     GraphWriter<Graph> reader(os, g);
   405     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   406     reader.addNodeMap("id", nodeIdMap);
   407     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   408     reader.addEdgeMap("id", edgeIdMap);
   409     reader.addEdgeMap("capacity", capacity);
   410     reader.addNode("source", s);
   411     reader.addNode("target", t);
   412     reader.run();
   413   }
   414 
   415   /// Ready to use writer function.  
   416   template<typename Graph, typename CapacityMap>
   417   void writeGraph(std::ostream& os, const Graph &g, 
   418 		  const CapacityMap& capacity, const typename Graph::Node &s) {
   419     GraphWriter<Graph> reader(os, g);
   420     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   421     reader.addNodeMap("id", nodeIdMap);
   422     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   423     reader.addEdgeMap("id", edgeIdMap);
   424     reader.addEdgeMap("capacity", capacity);
   425     reader.addNode("source", s);
   426     reader.run();
   427   }
   428   /// Ready to use writer function.  
   429   template<typename Graph, typename CapacityMap>
   430   void writeGraph(std::ostream& os, const Graph &g, 
   431 		  const CapacityMap& capacity) {
   432     GraphWriter<Graph> reader(os, g);
   433     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   434     reader.addNodeMap("id", nodeIdMap);
   435     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   436     reader.addEdgeMap("id", edgeIdMap);
   437     reader.addEdgeMap("capacity", capacity);
   438     reader.run();
   439   }
   440   /// Ready to use writer function.  
   441   template<typename Graph>
   442   void writeGraph(std::ostream& os, const Graph &g) {
   443     GraphWriter<Graph> reader(os, g);
   444     IdMap<Graph, typename Graph::Node> nodeIdMap(g);
   445     reader.addNodeMap("id", nodeIdMap);
   446     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   447     reader.addEdgeMap("id", edgeIdMap);
   448     reader.run();
   449   }
   450 
   451 
   452 }
   453 
   454 #endif