COIN-OR::LEMON - Graph Library

Changeset 1409:d2d1f8fa187b in lemon-0.x for src/lemon/graph_writer.h


Ignore:
Timestamp:
05/11/05 13:50:13 (19 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1876
Message:

LemonWriter? and GraphWriter?.
Little bit better documentation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/lemon/graph_writer.h

    r1402 r1409  
    2323
    2424#include <iostream>
    25 #include <sstream>
    26 
    27 #include <map>
    28 #include <vector>
    29 
    30 #include <memory>
    31 
    32 #include <lemon/graph_utils.h>
    33 
    34 #include <lemon/invalid.h>
     25
    3526#include <lemon/error.h>
    36 
     27#include <lemon/lemon_writer.h>
    3728
    3829namespace lemon {
     
    4132  /// @{
    4233
    43   /// \brief Standard WriterTraits for the GraphWriter class.
    44   ///
    45   /// Standard WriterTraits for the GraphWriter class.
    46   /// It defines standard writing method for all type of value.
    47   /// \author Balazs Dezso
    48   struct DefaultWriterTraits {
    49 
    50     /// \brief Template class for writing an value.
    51     ///
    52     /// Template class for writing an value.
    53     /// \author Balazs Dezso
    54     template <typename _Value>
    55     struct Writer {
    56       /// The value type.
    57       typedef _Value Value;
    58 
    59       /// \brief Writes a value to the given stream.
    60       ///
    61       /// Writes a value to the given stream.
    62       void write(std::ostream& os, const Value& value) {
    63         os << value << '\t';
    64       }
    65     };
    66 
    67     /// \brief Returns wheter this name is an ID map name.
    68     ///
    69     /// Returns wheter this name is an ID map name.
    70     static bool idMapName(const std::string& name) {
    71       return name == "id";
    72     }
    73 
    74   };
    75 
    76 
    77   /// \brief Writer class for quoted strings.
    78   ///
    79   /// Writer class for quoted strings. It can process the escape
    80   /// sequences in the string.
    81   /// \author Balazs Dezso
    82   class QuotedStringWriter {
    83   public:
    84     typedef std::string Value;
    85 
    86     /// \brief Constructor for the writer.
    87     ///
    88     /// Constructor for the writer. If the given parameter is true
    89     /// the writer creates escape sequences from special characters.
    90     QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
    91 
    92     /// \brief Writes a quoted string to the given stream.
    93     ///
    94     /// Writes a quoted string to the given stream.
    95     void write(std::ostream& os, const std::string& value) {
    96       os << "\"";
    97       if (escaped) {
    98         std::ostringstream ls;
    99         for (int i = 0; i < (int)value.size(); ++i) {
    100           writeEscape(ls, value[i]);
    101         }
    102         os << ls.str();
    103       } else {
    104         os << value;
    105       }
    106       os << "\"";
    107     }
    108 
    109   private:
    110    
    111     static void writeEscape(std::ostream& os, char c) {
    112       switch (c) {
    113       case '\\':
    114         os << "\\\\";
    115         return;
    116       case '\"':
    117         os << "\\\"";
    118         return;
    119       case '\'':
    120         os << "\\\'";
    121         return;
    122       case '\?':
    123         os << "\\\?";
    124         return;
    125       case '\a':
    126         os << "\\a";
    127         return;
    128       case '\b':
    129         os << "\\b";
    130         return;
    131       case '\f':
    132         os << "\\f";
    133         return;
    134       case '\r':
    135         os << "\\r";
    136         return;
    137       case '\n':
    138         os << "\\n";
    139         return;
    140       case '\t':
    141         os << "\\t";
    142         return;
    143       case '\v':
    144         os << "\\v";
    145         return;
    146       default:
    147         if (c < 0x20) {
    148           os << '\\' << std::oct << (int)c;
    149         } else {
    150           os << c;
    151         }
    152         return;
    153       }     
    154     }
    155   private:
    156     bool escaped;
    157   };
    158 
    159   class GUIWriter {
    160   public:
    161     virtual void write(std::ostream& os) = 0;
    162   };
    163 
    164  
    16534  /// \brief The graph writer class.
    16635  ///
     
    232101    typedef _Graph Graph;
    233102    typedef typename Graph::Node Node;
    234     typedef typename Graph::NodeIt NodeIt;
    235103    typedef typename Graph::Edge Edge;
    236     typedef typename Graph::EdgeIt EdgeIt;
    237104
    238105    typedef _WriterTraits WriterTraits;
    239  
     106
    240107    /// \brief Construct a new GraphWriter.
    241108    ///
    242     /// Construct a new GraphWriter. It writes from the given map,
    243     /// it constructs the given map and it use the given writer as the
    244     /// default skipper.
     109    /// Construct a new GraphWriter. It writes the given graph
     110    /// to the given stream.
    245111    GraphWriter(std::ostream& _os, const Graph& _graph)
    246       : gui_writer(0), os(_os), graph(_graph){}
    247 
     112      : writer(new LemonWriter(_os)), own_writer(true),
     113        graph(_graph),
     114        nodeset_writer(*writer, graph, std::string()),
     115        edgeset_writer(*writer, graph, nodeset_writer, std::string()),
     116        node_writer(*writer, nodeset_writer, std::string()),
     117        edge_writer(*writer, edgeset_writer, std::string()),
     118        attribute_writer(*writer, std::string()) {}
     119
     120    /// \brief Construct a new GraphWriter.
     121    ///
     122    /// Construct a new GraphWriter. It writes into the given graph
     123    /// to the given file.
     124    GraphWriter(const std::string& _filename, const Graph& _graph)
     125      : writer(new LemonWriter(_filename)), own_writer(true),
     126        graph(_graph),
     127        nodeset_writer(*writer, graph, std::string(), skipper),
     128        edgeset_writer(*writer, graph, nodeset_writer, std::string(), skipper),
     129        node_writer(*writer, nodeset_writer, std::string()),
     130        edge_writer(*writer, edgeset_writer, std::string()),
     131        attribute_writer(*writer, std::string()) {}
     132
     133    /// \brief Construct a new GraphWriter.
     134    ///
     135    /// Construct a new GraphWriter. It writes into the given graph
     136    /// to given LemonReader.
     137    GraphWriter(LemonWriter& _writer, const Graph& _graph)
     138      : writer(_writer), own_writer(false),
     139        graph(_graph),
     140        nodeset_writer(*writer, graph, std::string()),
     141        edgeset_writer(*writer, graph, nodeset_writer, std::string()),
     142        node_writer(*writer, nodeset_writer, std::string()),
     143        edge_writer(*writer, edgeset_writer, std::string()),
     144        attribute_writer(*writer, std::string()) {}
    248145
    249146    /// \brief Destruct the graph writer.
     
    251148    /// Destruct the graph writer.
    252149    ~GraphWriter() {
    253       for (typename NodeMapWriters::iterator it = node_map_writers.begin();
    254            it != node_map_writers.end(); ++it) {
    255         delete it->second;
    256       }
    257 
    258       for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
    259            it != edge_map_writers.end(); ++it) {
    260         delete it->second;
    261       }
    262 
    263     }
    264 
    265     // Node map rules
     150      if (own_writer)
     151        delete writer;
     152    }
    266153
    267154    /// \brief Add a new node map writer command for the writer.
     
    270157    template <typename Map>
    271158    GraphWriter& writeNodeMap(std::string name, const Map& map) {
    272       return writeNodeMap<typename WriterTraits::template Writer<
    273         typename Map::Value>, Map>(name, map);
     159      nodeset_writer.writeMap(name, map);
     160      return *this;
    274161    }
    275162
     
    279166    template <typename Writer, typename Map>
    280167    GraphWriter& writeNodeMap(std::string name, const Map& map,
    281                               const Writer& writer = Writer()) {
    282       node_map_writers.push_back(
    283         make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
    284       return *this;
    285     }
    286 
    287     // Edge map rules
     168                             const Writer& writer = Writer()) {
     169      nodeset_writer.writeMap(name, map, writer);
     170      return *this;
     171    }
     172
    288173
    289174    /// \brief Add a new edge map writer command for the writer.
     
    292177    template <typename Map>
    293178    GraphWriter& writeEdgeMap(std::string name, const Map& map) {
    294       return writeEdgeMap<typename WriterTraits::template Writer<
    295         typename Map::Value>, Map>(name, map);
     179      edgeset_writer.writeMap(name, map);
     180      return *this;
    296181    }
    297182
     
    301186    /// Add a new edge map writer command for the writer.
    302187    template <typename Writer, typename Map>
    303     GraphWriter& writeEdgeMap(std::string name,
    304                             const Map& map, const Writer& writer = Writer()) {
    305       edge_map_writers.push_back(make_pair(name,
    306         new MapWriter<Edge, Map, Writer>(map, writer)));
     188    GraphWriter& writeEdgeMap(std::string name, const Map& map,
     189                             const Writer& writer = Writer()) {
     190      edgeset_writer.writeMap(name, map, writer);
    307191      return *this;
    308192    }
     
    312196    /// Add a new labeled node writer for the writer.
    313197    GraphWriter& writeNode(std::string name, const Node& node) {
    314       node_writers.push_back(make_pair(name, node));
     198      node_writer.writeNode(name, node);
    315199      return *this;
    316200    }
     
    320204    /// Add a new labeled edge writer for the writer.
    321205    GraphWriter& writeEdge(std::string name, const Edge& edge) {
    322       edge_writers.push_back(make_pair(name, edge));
    323       return *this;
    324     }
    325 
    326     GraphWriter& writeGUI(const GUIWriter& writer) {
    327       gui_writer = &writer;
     206      edge_writer.writeEdge(name, edge);
     207    }
     208
     209    /// \brief Add a new attribute writer command.
     210    ///
     211    ///  Add a new attribute writer command.
     212    template <typename Value>
     213    GraphWriter& writeAttribute(std::string name, const Value& value) {
     214      attribute_writer.writeAttribute(name, value);
     215      return *this;
     216    }
     217   
     218    /// \brief Add a new attribute writer command.
     219    ///
     220    ///  Add a new attribute writer command.
     221    template <typename Writer, typename Value>
     222    GraphWriter& writeAttribute(std::string name, const Value& value,
     223                               const Writer& writer) {
     224      attribute_writer.writeAttribute<Writer>(name, value, writer);
     225      return *this;
     226    }
     227
     228    /// \brief Conversion operator to LemonWriter.
     229    ///
     230    /// Conversion operator to LemonWriter. It make possible
     231    /// to access the encapsulated \e LemonWriter, this way
     232    /// you can attach to this writer new instances of
     233    /// \e LemonWriter::SectionWriter.
     234    operator LemonWriter&() {
     235      return *writer;
    328236    }
    329237
     
    331239    ///
    332240    /// Executes the writer commands.
    333     void run() {   
    334       WriterBase<Node>* nodeWriter = 0;
    335       WriterBase<Edge>* edgeWriter = 0;
    336       writeNodeSet(nodeWriter);
    337       writeEdgeSet(nodeWriter, edgeWriter);
    338       writeNodes(nodeWriter);
    339       writeEdges(edgeWriter);
    340       writeGUI();
    341       os << "@end" << std::endl;
     241    void run() {
     242      writer->run();
    342243    }
    343244
    344245  private:
    345246
    346     template <class _Item>
    347     class WriterBase {
    348     public:
    349       typedef _Item Item;
    350       virtual void write(std::ostream&, const Item&) = 0;
    351     };
    352 
    353     template <class _Item, typename _Map, typename _Writer>
    354     class MapWriter : public WriterBase<_Item> {
    355     public:
    356       typedef _Map Map;
    357       typedef _Writer Writer;
    358       typedef typename Writer::Value Value;
    359       typedef _Item Item;
    360      
    361       const Map& map;
    362       Writer writer;
    363 
    364       MapWriter(const Map& _map, const Writer& _writer)
    365         : map(_map), writer(_writer) {}
    366 
    367 
    368       virtual void write(std::ostream& os, const Item& item) {
    369         writer.write(os, map[item]);
    370       }
    371 
    372     };
    373 
    374     void writeNodeSet(WriterBase<Node>* & nodeWriter) {
    375       if (node_map_writers.size() == 0) return;
    376       os << "@nodeset" << std::endl;
    377       for (int i = 0; i < (int)node_map_writers.size(); ++i) {
    378         const std::string& id = node_map_writers[i].first;
    379         os << id << '\t';
    380         if (WriterTraits::idMapName(id) && nodeWriter == 0) {
    381           nodeWriter = node_map_writers[i].second;
    382         }
    383       }
    384       os << std::endl;
    385       for (NodeIt it(graph); it != INVALID; ++it) {
    386         for (int i = 0; i < (int)node_map_writers.size(); ++i) {
    387           node_map_writers[i].second->write(os, it);
    388         }
    389         os << std::endl;
    390       }
    391 
    392     }
    393 
    394     void writeEdgeSet(WriterBase<Node>* nodeWriter,
    395                       WriterBase<Edge>* & edgeWriter) {
    396       if (edge_map_writers.size() == 0) return;
    397       if (nodeWriter == 0) {
    398         throw DataFormatError("Cannot find node id map");
    399       }
    400       os << "@edgeset" << std::endl;
    401       os << "\t\t";
    402       for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
    403         const std::string& id = edge_map_writers[i].first;
    404         os << id << '\t';
    405         if (WriterTraits::idMapName(id) && edgeWriter == 0) {
    406           edgeWriter = edge_map_writers[i].second;
    407         }
    408       }
    409       os << std::endl;
    410       for (EdgeIt it(graph); it != INVALID; ++it) {
    411         nodeWriter->write(os, graph.source(it));
    412         nodeWriter->write(os, graph.target(it));
    413         for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
    414           edge_map_writers[i].second->write(os, it);
    415         }
    416         os << std::endl;
    417       }
    418     }
    419 
    420     void writeNodes(WriterBase<Node>* nodeWriter) {
    421       if (node_writers.size() == 0) return;
    422       if (nodeWriter == 0) {
    423         throw DataFormatError("Cannot find node id map");
    424       }
    425       os << "@nodes" << std::endl;
    426       for (int i = 0; i < (int)node_writers.size(); ++i) {
    427         os << node_writers[i].first << '\t';
    428         nodeWriter->write(os, node_writers[i].second);
    429         os << std::endl;
    430       }
    431     }
    432 
    433     void writeEdges(WriterBase<Edge>* edgeWriter) {
    434       if (edge_writers.size() == 0) return;
    435       if (edgeWriter == 0) {
    436         throw DataFormatError("Cannot find node id map");
    437       }
    438       os << "@edges" << std::endl;
    439       for (int i = 0; i < (int)edge_writers.size(); ++i) {
    440         os << edge_writers[i].first << '\t';
    441         edgeWriter->write(os, edge_writers[i].second);
    442         os << std::endl;
    443       }
    444     }
     247    LemonWriter* writer;
     248    bool own_writer;
     249
     250    const Graph& graph;
     251
     252    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
     253    EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
     254
     255    NodeWriter<Graph> node_writer;
     256    EdgeWriter<Graph> edge_writer;
    445257   
    446     void writeGUI() {     
    447       if (gui_writer) {
    448         os << "@gui" << std::endl;
    449         gui_writer->write(os);
    450       }
    451     }
    452 
    453 
    454 
    455     typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
    456       NodeMapWriters;
    457     NodeMapWriters node_map_writers;
    458 
    459     typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
    460       EdgeMapWriters;
    461     EdgeMapWriters edge_map_writers;
    462 
    463     typedef std::vector<std::pair<std::string, Node> > NodeWriters;
    464     NodeWriters node_writers;
    465 
    466     typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
    467     EdgeWriters edge_writers;
    468 
    469     GUIWriter* gui_writer;
    470 
    471     std::ostream& os;
    472     const Graph& graph;
    473 
     258    AttributeWriter<WriterTraits> attribute_writer;
    474259  };
     260
    475261
    476262  /// \brief Write a graph to the output.
Note: See TracChangeset for help on using the changeset viewer.