COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_writer.h @ 1138:f68cb8752d81

Last change on this file since 1138:f68cb8752d81 was 1138:f68cb8752d81, checked in by Alpar Juttner, 15 years ago

Fix wrong reference in the documentation.

File size: 9.4 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  /// \brief Standard WriterTraits for the GraphWriter class.
37  ///
38  /// Standard WriterTraits for the GraphWriter class.
39  /// It defines standard writing method for all type of value.
40  struct DefaultWriterTraits {
41
42    /// \brief Template class for writing an value.
43    ///
44    /// Template class for writing an value.
45    template <typename _Value>
46    struct Writer {
47      /// The value type.
48      typedef _Value Value;
49
50      /// \brief Writes a value from the given stream.
51      ///
52      /// Writes a value from the given stream.
53      void write(std::ostream& os, const Value& value) {
54        os << value << '\t';
55      }
56    };
57
58  };
59
60
61  /// \brief Writer class for quoted strings.
62  ///
63  /// Writer class for quoted strings. It can process the escape
64  /// sequences in the string.
65  class QuotedStringWriter {
66  public:
67    typedef std::string Value;
68
69    /// \brief Constructor for the writer.
70    ///
71    /// Constructor for the writer. If the given parameter is true
72    /// the writer creates escape sequences from special characters.
73    QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
74
75    /// \brief Writes a quoted string from the given stream.
76    ///
77    /// Writes a quoted string from the given stream.
78    void write(std::ostream& os, const std::string& value) {
79      os << "\"";
80      if (escaped) {
81        ostringstream ls;
82        for (int i = 0; i < (int)value.size(); ++i) {
83          writeEscape(ls, value[i]);
84        }
85        os << ls.str();
86      } else {
87        os << value;
88      }
89      os << "\"";
90    }
91
92  private:
93   
94    static void writeEscape(std::ostream& os, char c) {
95      switch (c) {
96      case '\\':
97        os << "\\\\";
98        return;
99      case '\"':
100        os << "\\\"";
101        return;
102      case '\'':
103        os << "\\\'";
104        return;
105      case '\?':
106        os << "\\\?";
107        return;
108      case '\a':
109        os << "\\a";
110        return;
111      case '\b':
112        os << "\\b";
113        return;
114      case '\f':
115        os << "\\f";
116        return;
117      case '\r':
118        os << "\\r";
119        return;
120      case '\n':
121        os << "\\n";
122        return;
123      case '\t':
124        os << "\\t";
125        return;
126      case '\v':
127        os << "\\v";
128        return;
129      default:
130        if (c < 0x20) {
131          os << '\\' << oct << (int)c;
132        } else {
133          os << c;
134        }
135        return;
136      }     
137    }
138  private:
139    bool escaped;
140  };
141
142 
143  /// \brief The graph writer class.
144  ///
145  /// The writer class for the graph output.
146  /// \see \ref GraphReader
147  /// \see \ref graph-io-page
148  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
149  class GraphWriter {
150  public:
151   
152    typedef _Graph Graph;
153    typedef typename Graph::Node Node;
154    typedef typename Graph::NodeIt NodeIt;
155    typedef typename Graph::Edge Edge;
156    typedef typename Graph::EdgeIt EdgeIt;
157
158    typedef _WriterTraits WriterTraits;
159 
160    /// \brief Construct a new GraphWriter.
161    ///
162    /// Construct a new GraphWriter. It writes from the given map,
163    /// it constructs the given map and it use the given writer as the
164    /// default skipper.
165    GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
166
167
168    /// \brief Destruct the graph writer.
169    ///
170    /// Destruct the graph writer.
171    ~GraphWriter() {
172      for (typename NodeMapWriters::iterator it = node_map_writers.begin();
173           it != node_map_writers.end(); ++it) {
174        delete it->second;
175      }
176
177      for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
178           it != edge_map_writers.end(); ++it) {
179        delete it->second;
180      }
181
182    }
183
184    // Node map rules
185
186    /// \brief Add a new node map writer command for the writer.
187    ///
188    /// Add a new node map writer command for the writer.
189    template <typename Map>
190    GraphWriter& addNodeMap(std::string name, const Map& map) {
191      return addNodeMap<typename WriterTraits::template Writer<
192        typename Map::Value>, Map>(name, map);
193    }
194
195    /// \brief Add a new node map writer command for the writer.
196    ///
197    /// Add a new node map writer command for the writer.
198    template <typename Writer, typename Map>
199    GraphWriter& addNodeMap(std::string name, const Map& map,
200                              const Writer& writer = Writer()) {
201      node_map_writers.push_back(
202        make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
203      return *this;
204    }
205
206    // Edge map rules
207
208    /// \brief Add a new edge map writer command for the writer.
209    ///
210    /// Add a new edge map writer command for the writer.
211    template <typename Map>
212    GraphWriter& addEdgeMap(std::string name, const Map& map) {
213      return addEdgeMap<typename WriterTraits::template Writer<
214        typename Map::Value>, Map>(name, map);
215    }
216
217
218    /// \brief Add a new edge map writer command for the writer.
219    ///
220    /// Add a new edge map writer command for the writer.
221    template <typename Writer, typename Map>
222    GraphWriter& addEdgeMap(std::string name,
223                            const Map& map, const Writer& writer = Writer()) {
224      edge_map_writers.push_back(make_pair(name,
225        new MapWriter<Edge, Map, Writer>(map, writer)));
226      return *this;
227    }
228
229    /// \brief Add a new labeled node writer for the writer.
230    ///
231    /// Add a new labeled node writer for the writer.
232    GraphWriter& addNode(std::string name, const Node& node) {
233      node_writers.push_back(make_pair(name, node));
234      return *this;
235    }
236
237    /// \brief Add a new labeled edge writer for the writer.
238    ///
239    /// Add a new labeled edge writer for the writer.
240    GraphWriter& addEdge(std::string name, const Edge& edge) {
241      edge_writers.push_back(make_pair(name, edge));
242      return *this;
243    }
244
245    /// \brief Executes the writer commands.
246    ///
247    /// Executes the writer commands.
248    void run() {   
249      writeNodeSet();
250      writeEdgeSet();
251      writeNodes();
252      writeEdges();
253      os << "@end" << std::endl;
254    }
255
256  private:
257
258    void writeNodeSet() {
259      if (node_map_writers.size() == 0) return;
260      os << "@nodeset" << std::endl;
261      for (int i = 0; i < (int)node_map_writers.size(); ++i) {
262        os << node_map_writers[i].first << '\t';
263      }
264      os << std::endl;
265      for (NodeIt it(graph); it != INVALID; ++it) {
266        for (int i = 0; i < (int)node_map_writers.size(); ++i) {
267          node_map_writers[i].second->write(os, it);
268        }
269        os << std::endl;
270      }
271
272    }
273
274    void writeEdgeSet() {
275      if (edge_map_writers.size() == 0) return;
276      if (node_map_writers.size() == 0) {
277        throw Exception() << "Missing node id map";
278      }
279      os << "@edgeset" << std::endl;
280      os << "\t\t";
281      for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
282        os << edge_map_writers[i].first << '\t';
283      }
284      os << std::endl;
285      for (EdgeIt it(graph); it != INVALID; ++it) {
286        node_map_writers[0].second->write(os, graph.source(it));
287        node_map_writers[0].second->write(os, graph.target(it));
288        for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
289          edge_map_writers[i].second->write(os, it);
290        }
291        os << std::endl;
292      }
293    }
294
295    void writeNodes() {
296      if (node_writers.size() == 0) return;
297      if (node_map_writers.size() == 0) {
298        throw Exception() << "Missing node id map";
299      }
300      os << "@nodes" << std::endl;
301      for (int i = 0; i < (int)node_writers.size(); ++i) {
302        os << node_writers[i].first << '\t';
303        node_map_writers[0].second->write(os, node_writers[i].second);
304        os << std::endl;
305      }
306    }
307
308    void writeEdges() {
309      if (edge_writers.size() == 0) return;
310      if (edge_map_writers.size() == 0) {
311        throw Exception() << "Missing edge id map";
312      }
313      os << "@edges" << std::endl;
314      for (int i = 0; i < (int)edge_writers.size(); ++i) {
315        os << edge_writers[i].first << '\t';
316        edge_map_writers[0].second->write(os, edge_writers[i].second);
317        os << std::endl;
318      }
319    }
320   
321    // Writers
322
323    template <class _Item>
324    class WriterBase {
325    public:
326      typedef _Item Item;
327      virtual void write(std::ostream&, const Item&) = 0;
328    };
329
330    template <class _Item, typename _Map, typename _Writer>
331    class MapWriter : public WriterBase<_Item> {
332    public:
333      typedef _Map Map;
334      typedef _Writer Writer;
335      typedef typename Writer::Value Value;
336      typedef _Item Item;
337     
338      const Map& map;
339      Writer writer;
340
341      MapWriter(const Map& _map, const Writer& _writer)
342        : map(_map), writer(_writer) {}
343
344
345      virtual void write(std::ostream& os, const Item& item) {
346        writer.write(os, map[item]);
347      }
348
349    };
350
351
352
353    typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
354      NodeMapWriters;
355    NodeMapWriters node_map_writers;
356
357    typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
358      EdgeMapWriters;
359    EdgeMapWriters edge_map_writers;
360
361    typedef std::vector<std::pair<std::string, Node> > NodeWriters;
362    NodeWriters node_writers;
363
364    typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
365    EdgeWriters edge_writers;
366
367    std::ostream& os;
368    Graph& graph;
369
370  };
371
372
373}
Note: See TracBrowser for help on using the repository browser.