COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_writer.h @ 1297:fde0d12545c1

Last change on this file since 1297:fde0d12545c1 was 1297:fde0d12545c1, checked in by Balazs Dezso, 15 years ago

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