COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_writer.h @ 1281:164ca6938d09

Last change on this file since 1281:164ca6938d09 was 1214:39993ada11c7, checked in by Balazs Dezso, 19 years ago

Changing exception names.
Compile sentry fix.

File size: 12.2 KB
Line 
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 gio
18///\file
19///\brief Graph 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
38namespace 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        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 << '\\' << 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  /// The writer class for the graph output.
150  /// \see \ref GraphReader
151  /// \see \ref graph-io-page
152  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
153  class GraphWriter {
154  public:
155   
156    typedef _Graph Graph;
157    typedef typename Graph::Node Node;
158    typedef typename Graph::NodeIt NodeIt;
159    typedef typename Graph::Edge Edge;
160    typedef typename Graph::EdgeIt EdgeIt;
161
162    typedef _WriterTraits WriterTraits;
163 
164    /// \brief Construct a new GraphWriter.
165    ///
166    /// Construct a new GraphWriter. It writes from the given map,
167    /// it constructs the given map and it use the given writer as the
168    /// default skipper.
169    GraphWriter(std::ostream& _os, const Graph& _graph)
170      : os(_os), graph(_graph) {}
171
172
173    /// \brief Destruct the graph writer.
174    ///
175    /// Destruct the graph writer.
176    ~GraphWriter() {
177      for (typename NodeMapWriters::iterator it = node_map_writers.begin();
178           it != node_map_writers.end(); ++it) {
179        delete it->second;
180      }
181
182      for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
183           it != edge_map_writers.end(); ++it) {
184        delete it->second;
185      }
186
187    }
188
189    // Node map rules
190
191    /// \brief Add a new node map writer command for the writer.
192    ///
193    /// Add a new node map writer command for the writer.
194    template <typename Map>
195    GraphWriter& addNodeMap(std::string name, const Map& map) {
196      return addNodeMap<typename WriterTraits::template Writer<
197        typename Map::Value>, Map>(name, map);
198    }
199
200    /// \brief Add a new node map writer command for the writer.
201    ///
202    /// Add a new node map writer command for the writer.
203    template <typename Writer, typename Map>
204    GraphWriter& addNodeMap(std::string name, const Map& map,
205                              const Writer& writer = Writer()) {
206      node_map_writers.push_back(
207        make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
208      return *this;
209    }
210
211    // Edge map rules
212
213    /// \brief Add a new edge map writer command for the writer.
214    ///
215    /// Add a new edge map writer command for the writer.
216    template <typename Map>
217    GraphWriter& addEdgeMap(std::string name, const Map& map) {
218      return addEdgeMap<typename WriterTraits::template Writer<
219        typename Map::Value>, Map>(name, map);
220    }
221
222
223    /// \brief Add a new edge map writer command for the writer.
224    ///
225    /// Add a new edge map writer command for the writer.
226    template <typename Writer, typename Map>
227    GraphWriter& addEdgeMap(std::string name,
228                            const Map& map, const Writer& writer = Writer()) {
229      edge_map_writers.push_back(make_pair(name,
230        new MapWriter<Edge, Map, Writer>(map, writer)));
231      return *this;
232    }
233
234    /// \brief Add a new labeled node writer for the writer.
235    ///
236    /// Add a new labeled node writer for the writer.
237    GraphWriter& addNode(std::string name, const Node& node) {
238      node_writers.push_back(make_pair(name, node));
239      return *this;
240    }
241
242    /// \brief Add a new labeled edge writer for the writer.
243    ///
244    /// Add a new labeled edge writer for the writer.
245    GraphWriter& addEdge(std::string name, const Edge& edge) {
246      edge_writers.push_back(make_pair(name, edge));
247      return *this;
248    }
249
250    /// \brief Executes the writer commands.
251    ///
252    /// Executes the writer commands.
253    void run() {   
254      writeNodeSet();
255      writeEdgeSet();
256      writeNodes();
257      writeEdges();
258      os << "@end" << std::endl;
259    }
260
261  private:
262
263    void writeNodeSet() {
264      if (node_map_writers.size() == 0) return;
265      os << "@nodeset" << std::endl;
266      for (int i = 0; i < (int)node_map_writers.size(); ++i) {
267        os << node_map_writers[i].first << '\t';
268      }
269      os << std::endl;
270      for (NodeIt it(graph); it != INVALID; ++it) {
271        for (int i = 0; i < (int)node_map_writers.size(); ++i) {
272          node_map_writers[i].second->write(os, it);
273        }
274        os << std::endl;
275      }
276
277    }
278
279    void writeEdgeSet() {
280      if (edge_map_writers.size() == 0) return;
281      if (node_map_writers.size() == 0) {
282        //      ErrorMessage message;
283        //      message << "Missing node id map";
284        //      throw IOLogicError(message);
285      }
286      os << "@edgeset" << std::endl;
287      os << "\t\t";
288      for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
289        os << edge_map_writers[i].first << '\t';
290      }
291      os << std::endl;
292      for (EdgeIt it(graph); it != INVALID; ++it) {
293        node_map_writers[0].second->write(os, graph.source(it));
294        node_map_writers[0].second->write(os, graph.target(it));
295        for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
296          edge_map_writers[i].second->write(os, it);
297        }
298        os << std::endl;
299      }
300    }
301
302    void writeNodes() {
303      if (node_writers.size() == 0) return;
304      if (node_map_writers.size() == 0) {
305        //      throw Exception() << "Missing node id map";
306      }
307      os << "@nodes" << std::endl;
308      for (int i = 0; i < (int)node_writers.size(); ++i) {
309        os << node_writers[i].first << '\t';
310        node_map_writers[0].second->write(os, node_writers[i].second);
311        os << std::endl;
312      }
313    }
314
315    void writeEdges() {
316      if (edge_writers.size() == 0) return;
317      if (edge_map_writers.size() == 0) {
318        //      throw Exception() << "Missing edge id map";
319      }
320      os << "@edges" << std::endl;
321      for (int i = 0; i < (int)edge_writers.size(); ++i) {
322        os << edge_writers[i].first << '\t';
323        edge_map_writers[0].second->write(os, edge_writers[i].second);
324        os << std::endl;
325      }
326    }
327   
328    // Writers
329
330    template <class _Item>
331    class WriterBase {
332    public:
333      typedef _Item Item;
334      virtual void write(std::ostream&, const Item&) = 0;
335    };
336
337    template <class _Item, typename _Map, typename _Writer>
338    class MapWriter : public WriterBase<_Item> {
339    public:
340      typedef _Map Map;
341      typedef _Writer Writer;
342      typedef typename Writer::Value Value;
343      typedef _Item Item;
344     
345      const Map& map;
346      Writer writer;
347
348      MapWriter(const Map& _map, const Writer& _writer)
349        : map(_map), writer(_writer) {}
350
351
352      virtual void write(std::ostream& os, const Item& item) {
353        writer.write(os, map[item]);
354      }
355
356    };
357
358
359
360    typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
361      NodeMapWriters;
362    NodeMapWriters node_map_writers;
363
364    typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
365      EdgeMapWriters;
366    EdgeMapWriters edge_map_writers;
367
368    typedef std::vector<std::pair<std::string, Node> > NodeWriters;
369    NodeWriters node_writers;
370
371    typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
372    EdgeWriters edge_writers;
373
374    std::ostream& os;
375    const Graph& graph;
376
377  };
378
379  /// Ready to use writer function. 
380  template<typename Graph, typename CapacityMap, typename CostMap>
381  void writeGraph(std::ostream& os, const Graph &g,
382                  const CapacityMap& capacity, const typename Graph::Node &s,
383                  const typename Graph::Node &t, const CostMap& cost) {
384    GraphWriter<Graph> reader(os, g);
385    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
386    reader.addNodeMap("id", nodeIdMap);
387    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
388    reader.addEdgeMap("id", edgeIdMap);
389    reader.addEdgeMap("capacity", capacity);
390    reader.addEdgeMap("cost", cost);
391    reader.addNode("source", s);
392    reader.addNode("target", t);
393    reader.run();
394  }
395
396  /// Ready to use writer function. 
397  template<typename Graph, typename CapacityMap, typename CostMap>
398  void writeGraph(std::ostream& os, const Graph &g,
399                  const CapacityMap& capacity, const typename Graph::Node &s,
400                  const typename Graph::Node &t) {
401    GraphWriter<Graph> reader(os, g);
402    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
403    reader.addNodeMap("id", nodeIdMap);
404    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
405    reader.addEdgeMap("id", edgeIdMap);
406    reader.addEdgeMap("capacity", capacity);
407    reader.addNode("source", s);
408    reader.addNode("target", t);
409    reader.run();
410  }
411
412  /// Ready to use writer function. 
413  template<typename Graph, typename CapacityMap>
414  void writeGraph(std::ostream& os, const Graph &g,
415                  const CapacityMap& capacity, const typename Graph::Node &s) {
416    GraphWriter<Graph> reader(os, g);
417    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
418    reader.addNodeMap("id", nodeIdMap);
419    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
420    reader.addEdgeMap("id", edgeIdMap);
421    reader.addEdgeMap("capacity", capacity);
422    reader.addNode("source", s);
423    reader.run();
424  }
425  /// Ready to use writer function. 
426  template<typename Graph, typename CapacityMap>
427  void writeGraph(std::ostream& os, const Graph &g,
428                  const CapacityMap& capacity) {
429    GraphWriter<Graph> reader(os, g);
430    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
431    reader.addNodeMap("id", nodeIdMap);
432    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
433    reader.addEdgeMap("id", edgeIdMap);
434    reader.addEdgeMap("capacity", capacity);
435    reader.run();
436  }
437  /// Ready to use writer function. 
438  template<typename Graph>
439  void writeGraph(std::ostream& os, const Graph &g) {
440    GraphWriter<Graph> reader(os, g);
441    IdMap<Graph, typename Graph::Node> nodeIdMap(g);
442    reader.addNodeMap("id", nodeIdMap);
443    IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
444    reader.addEdgeMap("id", edgeIdMap);
445    reader.run();
446  }
447
448
449}
450
451#endif
Note: See TracBrowser for help on using the repository browser.