COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/deba/graph_writer.h @ 1120:5d8d64bde9c5

Last change on this file since 1120:5d8d64bde9c5 was 1115:444f69240539, checked in by Balazs Dezso, 20 years ago

Some changes in the IO and map utilities.

File size: 7.9 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      os << "\"";
58      if (escaped) {
59        ostringstream ls;
60        for (int i = 0; i < (int)value.size(); ++i) {
61          writeEscape(ls, value[i]);
62        }
63        os << ls.str();
64      } else {
65        os << value;
66      }
67      os << "\"";
68    }
69
70  private:
71   
72    static void writeEscape(std::ostream& os, char c) {
73      switch (c) {
74      case '\\':
75        os << "\\\\";
76        return;
77      case '\"':
78        os << "\\\"";
79        return;
80      case '\'':
81        os << "\\\'";
82        return;
83      case '\?':
84        os << "\\\?";
85        return;
86      case '\a':
87        os << "\\a";
88        return;
89      case '\b':
90        os << "\\b";
91        return;
92      case '\f':
93        os << "\\f";
94        return;
95      case '\r':
96        os << "\\r";
97        return;
98      case '\n':
99        os << "\\n";
100        return;
101      case '\t':
102        os << "\\t";
103        return;
104      case '\v':
105        os << "\\v";
106        return;
107      default:
108        if (c < 0x20) {
109          os << '\\' << oct << (int)c;
110        } else {
111          os << c;
112        }
113        return;
114      }     
115    }
116  private:
117    bool escaped;
118  };
119
120  // Graph writer
121 
122  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
123  class GraphWriter {
124  public:
125   
126    typedef _Graph Graph;
127    typedef typename Graph::Node Node;
128    typedef typename Graph::NodeIt NodeIt;
129    typedef typename Graph::Edge Edge;
130    typedef typename Graph::EdgeIt EdgeIt;
131
132    typedef _WriterTraits WriterTraits;
133
134    GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
135
136
137    ~GraphWriter() {
138      for (typename NodeMapWriters::iterator it = node_map_writers.begin();
139           it != node_map_writers.end(); ++it) {
140        delete it->second;
141      }
142
143      for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
144           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& addNodeMap(std::string name, const Map& map) {
154      return addNodeMap<typename WriterTraits::template Writer<
155        typename Map::Value>, Map>(name, map);
156    }
157
158    template <typename Writer, typename Map>
159    GraphWriter& addNodeMap(std::string name, const Map& map,
160                              const Writer& writer = Writer()) {
161      //      if (node_map_writers.find(name) != node_map_writers.end()) {
162      //        throw Exception() << "Multiple write rule for node map: "
163      //        << name;
164      //      }
165      node_map_writers.push_back(
166        make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
167      return *this;
168    }
169
170    // Edge map rules
171
172    template <typename Map>
173    GraphWriter& addEdgeMap(std::string name, const Map& map) {
174      return addEdgeMap<typename WriterTraits::template Writer<typename Map::Value>, Map>(name, map);
175    }
176
177
178    template <typename Writer, typename Map>
179    GraphWriter& addEdgeMap(std::string name, const Map& map, const Writer& writer = Writer()) {
180      //      if (edge_map_writers.find(name) != edge_map_writers.end()) {
181      //        throw Exception() << "Multiple write rule for edge map: " << name;
182      //      }
183      edge_map_writers.push_back(make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
184      return *this;
185    }
186
187    // Node rules
188    GraphWriter& addNode(std::string name, const Node& node) {
189      //      if (node_writers.find(name) != node_writers.end()) {
190      //        throw Exception() << "Multiple write rule for node";
191      //      }
192      node_writers.push_back(make_pair(name, node));
193      return *this;
194    }
195
196    // Edge rules
197
198    GraphWriter& addEdge(std::string name, const Edge& edge) {
199      //      if (edge_writers.find(name) != edge_writers.end()) {
200      //        throw Exception() << "Multiple write rule for edge";
201      //      }
202      edge_writers.push_back(make_pair(name, edge));
203      return *this;
204    }
205
206    void write() {   
207      writeNodeSet();
208      writeEdgeSet();
209      writeNodes();
210      writeEdges();
211      os << "@end" << std::endl;
212    }
213
214  private:
215
216    void writeNodeSet() {
217      if (node_map_writers.size() == 0) return;
218      os << "@nodeset" << std::endl;
219      for (int i = 0; i < (int)node_map_writers.size(); ++i) {
220        os << node_map_writers[i].first << '\t';
221      }
222      os << std::endl;
223      for (NodeIt it(graph); it != INVALID; ++it) {
224        for (int i = 0; i < (int)node_map_writers.size(); ++i) {
225          node_map_writers[i].second->write(os, it);
226        }
227        os << std::endl;
228      }
229
230    }
231
232    void writeEdgeSet() {
233      if (edge_map_writers.size() == 0) return;
234      if (node_map_writers.size() == 0) {
235        throw Exception() << "Missing node id map";
236      }
237      os << "@edgeset" << std::endl;
238      os << "\t\t";
239      for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
240        os << edge_map_writers[i].first << '\t';
241      }
242      os << std::endl;
243      for (EdgeIt it(graph); it != INVALID; ++it) {
244        node_map_writers[0].second->write(os, graph.source(it));
245        node_map_writers[0].second->write(os, graph.target(it));
246        for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
247          edge_map_writers[i].second->write(os, it);
248        }
249        os << std::endl;
250      }
251    }
252
253    void writeNodes() {
254      if (node_writers.size() == 0) return;
255      if (node_map_writers.size() == 0) {
256        throw Exception() << "Missing node id map";
257      }
258      os << "@nodes" << std::endl;
259      for (int i = 0; i < (int)node_writers.size(); ++i) {
260        os << node_writers[i].first << '\t';
261        node_map_writers[0].second->write(os, node_writers[i].second);
262        os << std::endl;
263      }
264    }
265
266    void writeEdges() {
267      if (edge_writers.size() == 0) return;
268      if (edge_map_writers.size() == 0) {
269        throw Exception() << "Missing edge id map";
270      }
271      os << "@edges" << std::endl;
272      for (int i = 0; i < (int)edge_writers.size(); ++i) {
273        os << edge_writers[i].first << '\t';
274        edge_map_writers[0].second->write(os, edge_writers[i].second);
275        os << std::endl;
276      }
277    }
278   
279    // Writers
280
281    template <class _Item>
282    class WriterBase {
283    public:
284      typedef _Item Item;
285      virtual void write(std::ostream&, const Item&) = 0;
286    };
287
288    template <class _Item, typename _Map, typename _Writer>
289    class MapWriter : public WriterBase<_Item> {
290    public:
291      typedef _Map Map;
292      typedef _Writer Writer;
293      typedef typename Writer::Value Value;
294      typedef _Item Item;
295     
296      const Map& map;
297      Writer writer;
298
299      MapWriter(const Map& _map, const Writer& _writer)
300        : map(_map), writer(_writer) {}
301
302
303      virtual void write(std::ostream& os, const Item& item) {
304        writer.write(os, map[item]);
305      }
306
307    };
308
309
310
311    typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
312      NodeMapWriters;
313    NodeMapWriters node_map_writers;
314
315    typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
316      EdgeMapWriters;
317    EdgeMapWriters edge_map_writers;
318
319    typedef std::vector<std::pair<std::string, Node> > NodeWriters;
320    NodeWriters node_writers;
321
322    typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
323    EdgeWriters edge_writers;
324
325    std::ostream& os;
326    Graph& graph;
327
328  };
329
330
331}
Note: See TracBrowser for help on using the repository browser.