src/work/deba/graph_writer.h
changeset 1080 568ce2be7fe0
child 1115 444f69240539
equal deleted inserted replaced
-1:000000000000 0:0b89fa58c5ed
       
     1 /* -*- C++ -*-
       
     2  * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
       
     3  *
       
     4  * Copyright (C) 2004 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 gio
       
    18 ///\file
       
    19 ///\brief Graph writer.
       
    20 
       
    21 
       
    22 #include <iostream>
       
    23 #include <sstream>
       
    24 
       
    25 #include <map>
       
    26 #include <vector>
       
    27 
       
    28 #include <memory>
       
    29 
       
    30 #include <lemon/invalid.h>
       
    31 #include <lemon/error.h>
       
    32 
       
    33 
       
    34 namespace lemon {
       
    35 
       
    36   struct DefaultWriterTraits {
       
    37 
       
    38     template <typename _Value>
       
    39     struct Writer {
       
    40       typedef _Value Value;
       
    41 
       
    42       void write(std::ostream& os, const Value& value) {
       
    43 	os << value << '\t';
       
    44       }
       
    45     };
       
    46 
       
    47   };
       
    48 
       
    49 
       
    50   class QuotedStringWriter {
       
    51   public:
       
    52     typedef std::string Value;
       
    53 
       
    54     QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
       
    55 
       
    56     void write(std::ostream& os, const std::string& value) {
       
    57       char c;
       
    58       os << "\"";
       
    59       if (escaped) {
       
    60 	ostringstream ls;
       
    61 	for (int i = 0; i < value.size(); ++i) {
       
    62 	  writeEscape(ls, value[i]);
       
    63 	}
       
    64 	os << ls.str();
       
    65       } else {
       
    66 	os << value;
       
    67       }
       
    68       os << "\"";
       
    69     }
       
    70 
       
    71   private:
       
    72     
       
    73     static void writeEscape(std::ostream& os, char c) {
       
    74       switch (c) {
       
    75       case '\\':
       
    76 	os << "\\\\";
       
    77 	return;
       
    78       case '\"':
       
    79 	os << "\\\"";
       
    80 	return;
       
    81       case '\'':
       
    82 	os << "\\\'";
       
    83 	return;
       
    84       case '\?':
       
    85 	os << "\\\?";
       
    86 	return;
       
    87       case '\a':
       
    88 	os << "\\a";
       
    89 	return;
       
    90       case '\b':
       
    91 	os << "\\b";
       
    92 	return;
       
    93       case '\f':
       
    94 	os << "\\f";
       
    95 	return;
       
    96       case '\r':
       
    97 	os << "\\r";
       
    98 	return;
       
    99       case '\n':
       
   100 	os << "\\n";
       
   101 	return;
       
   102       case '\t':
       
   103 	os << "\\t";
       
   104 	return;
       
   105       case '\v':
       
   106 	os << "\\v";
       
   107 	return;
       
   108       default:
       
   109 	if (c < 0x20) {
       
   110 	  os << '\\' << oct << (int)c;
       
   111 	} else {
       
   112 	  os << c;
       
   113 	}
       
   114 	return;
       
   115       }     
       
   116     }
       
   117   private:
       
   118     bool escaped;
       
   119   };
       
   120 
       
   121   // Graph writer
       
   122   
       
   123   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
       
   124   class GraphWriter {
       
   125   public:
       
   126     
       
   127     typedef _Graph Graph;
       
   128     typedef typename Graph::Node Node;
       
   129     typedef typename Graph::NodeIt NodeIt;
       
   130     typedef typename Graph::Edge Edge;
       
   131     typedef typename Graph::EdgeIt EdgeIt;
       
   132 
       
   133     typedef _WriterTraits WriterTraits;
       
   134 
       
   135     GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
       
   136 
       
   137 
       
   138     ~GraphWriter() {
       
   139 
       
   140       for (typename NodeMapWriters::iterator it = node_map_writers.begin(); it != node_map_writers.end(); ++it) {
       
   141 	delete it->second;
       
   142       }
       
   143 
       
   144       for (typename EdgeMapWriters::iterator it = edge_map_writers.begin(); it != edge_map_writers.end(); ++it) {
       
   145 	delete it->second;
       
   146       }
       
   147 
       
   148     }
       
   149 
       
   150     // Node map rules
       
   151 
       
   152     template <typename Map>
       
   153     GraphWriter& writeNodeMap(std::string name, const Map& map) {
       
   154       return writeNodeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
       
   155     }
       
   156 
       
   157     template <typename Writer, typename Map>
       
   158     GraphWriter& writeNodeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
       
   159       //      if (node_map_writers.find(name) != node_map_writers.end()) {
       
   160       //	throw Exception() << "Multiple write rule for node map: " << name;
       
   161       //      }
       
   162       node_map_writers.push_back(make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
       
   163       return *this;
       
   164     }
       
   165 
       
   166     // Edge map rules
       
   167 
       
   168     template <typename Map>
       
   169     GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
       
   170       return writeEdgeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
       
   171     }
       
   172 
       
   173 
       
   174     template <typename Writer, typename Map>
       
   175     GraphWriter& writeEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
       
   176       //      if (edge_map_writers.find(name) != edge_map_writers.end()) {
       
   177       //	throw Exception() << "Multiple write rule for edge map: " << name;
       
   178       //      }
       
   179       edge_map_writers.push_back(make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
       
   180       return *this;
       
   181     }
       
   182 
       
   183     // Node rules
       
   184     GraphWriter& writeNode(std::string name, const Node& node) {
       
   185       //      if (node_writers.find(name) != node_writers.end()) {
       
   186       //	throw Exception() << "Multiple write rule for node";
       
   187       //      }
       
   188       node_writers.push_back(make_pair(name, node));
       
   189     }
       
   190 
       
   191     // Edge rules
       
   192 
       
   193     GraphWriter& writeEdge(std::string name, const Edge& edge) {
       
   194       //      if (edge_writers.find(name) != edge_writers.end()) {
       
   195       //	throw Exception() << "Multiple write rule for edge";
       
   196       //      }
       
   197       edge_writers.push_back(make_pair(name, edge));
       
   198     }
       
   199 
       
   200     void write() {   
       
   201       writeNodeSet();
       
   202       writeEdgeSet();
       
   203       writeNodes();
       
   204       writeEdges();
       
   205       os << "@end" << std::endl;
       
   206     }
       
   207 
       
   208   private:
       
   209 
       
   210     void writeNodeSet() {
       
   211       if (node_map_writers.size() == 0) return;
       
   212       os << "@nodeset" << std::endl;
       
   213       for (int i = 0; i < node_map_writers.size(); ++i) {
       
   214 	os << node_map_writers[i].first << '\t';
       
   215       } 
       
   216       os << std::endl;
       
   217       for (NodeIt it(graph); it != INVALID; ++it) {
       
   218 	for (int i = 0; i < node_map_writers.size(); ++i) {
       
   219 	  node_map_writers[i].second->write(os, it);
       
   220 	}
       
   221 	os << std::endl;
       
   222       }
       
   223 
       
   224     }
       
   225 
       
   226     void writeEdgeSet() {
       
   227       if (edge_map_writers.size() == 0) return;
       
   228       if (node_map_writers.size() == 0) {
       
   229 	throw Exception() << "Missing node id map";
       
   230       }
       
   231       os << "@edgeset" << std::endl;
       
   232       os << "\t\t";
       
   233       for (int i = 0; i < edge_map_writers.size(); ++i) {
       
   234 	os << edge_map_writers[i].first << '\t';
       
   235       } 
       
   236       os << std::endl;
       
   237       for (EdgeIt it(graph); it != INVALID; ++it) {
       
   238 	node_map_writers[0].second->write(os, graph.source(it));
       
   239 	node_map_writers[0].second->write(os, graph.target(it));
       
   240 	for (int i = 0; i < edge_map_writers.size(); ++i) {
       
   241 	  edge_map_writers[i].second->write(os, it);
       
   242 	}
       
   243 	os << std::endl;
       
   244       }
       
   245     }
       
   246 
       
   247     void writeNodes() {
       
   248       if (node_writers.size() == 0) return;
       
   249       if (node_map_writers.size() == 0) {
       
   250 	throw Exception() << "Missing node id map";
       
   251       }
       
   252       os << "@nodes" << std::endl;
       
   253       for (int i = 0; i < node_writers.size(); ++i) {
       
   254 	os << node_writers[i].first << '\t';
       
   255 	node_map_writers[0].second->write(os, node_writers[i].second);
       
   256 	os << std::endl;
       
   257       } 
       
   258     }
       
   259 
       
   260     void writeEdges() {
       
   261       if (edge_writers.size() == 0) return;
       
   262       if (edge_map_writers.size() == 0) {
       
   263 	throw Exception() << "Missing edge id map";
       
   264       }
       
   265       os << "@edges" << std::endl;
       
   266       for (int i = 0; i < edge_writers.size(); ++i) {
       
   267 	os << edge_writers[i].first << '\t';
       
   268 	edge_map_writers[0].second->write(os, edge_writers[i].second);
       
   269 	os << std::endl;
       
   270       } 
       
   271     }
       
   272     
       
   273     // Writers
       
   274 
       
   275     template <class _Item>
       
   276     class WriterBase {
       
   277     public:
       
   278       typedef _Item Item;
       
   279       virtual void write(std::ostream&, const Item&) = 0;
       
   280     };
       
   281 
       
   282     template <class _Item, typename _Map, typename _Writer>
       
   283     class MapWriter : public WriterBase<_Item> {
       
   284     public:
       
   285       typedef _Map Map;
       
   286       typedef _Writer Writer;
       
   287       typedef typename Writer::Value Value;
       
   288       typedef _Item Item;
       
   289       
       
   290       const Map& map;
       
   291       Writer writer;
       
   292 
       
   293       MapWriter(const Map& _map, const Writer& _writer) 
       
   294 	: map(_map), writer(_writer) {}
       
   295 
       
   296 
       
   297       virtual void write(std::ostream& os, const Item& item) {
       
   298 	Value value;
       
   299 	writer.write(os, map[item]);
       
   300       }
       
   301 
       
   302     };
       
   303 
       
   304 
       
   305 
       
   306     typedef std::vector< std::pair<std::string, WriterBase<Node>*> > NodeMapWriters;
       
   307     NodeMapWriters node_map_writers;
       
   308 
       
   309     typedef std::vector< std::pair<std::string, WriterBase<Edge>*> > EdgeMapWriters;
       
   310     EdgeMapWriters edge_map_writers;
       
   311 
       
   312     typedef std::vector<std::pair<std::string, Node> > NodeWriters;
       
   313     NodeWriters node_writers;
       
   314 
       
   315     typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
       
   316     EdgeWriters edge_writers;
       
   317 
       
   318     std::ostream& os;
       
   319     Graph& graph;
       
   320 
       
   321   };
       
   322 
       
   323 
       
   324 }