COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/graph_writer.h @ 1076:67a115cdade4

Last change on this file since 1076:67a115cdade4 was 1037:3eaff8d04171, checked in by Balazs Dezso, 20 years ago

graph_io under construction
This is a working version, but needs more improvments.

todo:

documention + fix the file format
improve the exception system

add some possible asserts

tutorials

File size: 7.8 KB
Line 
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
34namespace 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}
Note: See TracBrowser for help on using the repository browser.