diff -r 8d066154b66a -r 83a48cfd8553 src/lemon/graph_writer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lemon/graph_writer.h Mon Feb 07 11:29:25 2005 +0000 @@ -0,0 +1,372 @@ +/* -*- C++ -*- + * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Combinatorial Optimization Research Group, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup gio +///\file +///\brief Graph writer. + + +#include +#include + +#include +#include + +#include + +#include +#include + + +namespace lemon { + + /// \brief Standard WriterTraits for the GraphWriter class. + /// + /// Standard WriterTraits for the GraphWriter class. + /// It defines standard writing method for all type of value. + struct DefaultWriterTraits { + + /// \brief Template class for writing an value. + /// + /// Template class for writing an value. + template + struct Writer { + /// The value type. + typedef _Value Value; + + /// \brief Writes a value from the given stream. + /// + /// Writes a value from the given stream. + void write(std::ostream& os, const Value& value) { + os << value << '\t'; + } + }; + + }; + + + /// \brief Writer class for quoted strings. + /// + /// Writer class for quoted strings. It can process the escape + /// sequences in the string. + class QuotedStringWriter { + public: + typedef std::string Value; + + /// \brief Constructor for the writer. + /// + /// Constructor for the writer. If the given parameter is true + /// the writer creates escape sequences from special characters. + QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {} + + /// \brief Writes a quoted string from the given stream. + /// + /// Writes a quoted string from the given stream. + void write(std::ostream& os, const std::string& value) { + os << "\""; + if (escaped) { + ostringstream ls; + for (int i = 0; i < (int)value.size(); ++i) { + writeEscape(ls, value[i]); + } + os << ls.str(); + } else { + os << value; + } + os << "\""; + } + + private: + + static void writeEscape(std::ostream& os, char c) { + switch (c) { + case '\\': + os << "\\\\"; + return; + case '\"': + os << "\\\""; + return; + case '\'': + os << "\\\'"; + return; + case '\?': + os << "\\\?"; + return; + case '\a': + os << "\\a"; + return; + case '\b': + os << "\\b"; + return; + case '\f': + os << "\\f"; + return; + case '\r': + os << "\\r"; + return; + case '\n': + os << "\\n"; + return; + case '\t': + os << "\\t"; + return; + case '\v': + os << "\\v"; + return; + default: + if (c < 0x20) { + os << '\\' << oct << (int)c; + } else { + os << c; + } + return; + } + } + private: + bool escaped; + }; + + + /// \brief The graph writer class. + /// + /// The writer class for the graph output. + /// \see graph-io-page + template + class GraphWriter { + public: + + typedef _Graph Graph; + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Edge Edge; + typedef typename Graph::EdgeIt EdgeIt; + + typedef _WriterTraits WriterTraits; + + /// \brief Construct a new GraphWriter. + /// + /// Construct a new GraphWriter. It writes from the given map, + /// it constructs the given map and it use the given writer as the + /// default skipper. + GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {} + + + /// \brief Destruct the graph writer. + /// + /// Destruct the graph writer. + ~GraphWriter() { + for (typename NodeMapWriters::iterator it = node_map_writers.begin(); + it != node_map_writers.end(); ++it) { + delete it->second; + } + + for (typename EdgeMapWriters::iterator it = edge_map_writers.begin(); + it != edge_map_writers.end(); ++it) { + delete it->second; + } + + } + + // Node map rules + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + GraphWriter& addNodeMap(std::string name, const Map& map) { + return addNodeMap, Map>(name, map); + } + + /// \brief Add a new node map writer command for the writer. + /// + /// Add a new node map writer command for the writer. + template + GraphWriter& addNodeMap(std::string name, const Map& map, + const Writer& writer = Writer()) { + node_map_writers.push_back( + make_pair(name, new MapWriter(map, writer))); + return *this; + } + + // Edge map rules + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + GraphWriter& addEdgeMap(std::string name, const Map& map) { + return addEdgeMap, Map>(name, map); + } + + + /// \brief Add a new edge map writer command for the writer. + /// + /// Add a new edge map writer command for the writer. + template + GraphWriter& addEdgeMap(std::string name, + const Map& map, const Writer& writer = Writer()) { + edge_map_writers.push_back(make_pair(name, + new MapWriter(map, writer))); + return *this; + } + + /// \brief Add a new labeled node writer for the writer. + /// + /// Add a new labeled node writer for the writer. + GraphWriter& addNode(std::string name, const Node& node) { + node_writers.push_back(make_pair(name, node)); + return *this; + } + + /// \brief Add a new labeled edge writer for the writer. + /// + /// Add a new labeled edge writer for the writer. + GraphWriter& addEdge(std::string name, const Edge& edge) { + edge_writers.push_back(make_pair(name, edge)); + return *this; + } + + /// \brief Executes the writer commands. + /// + /// Executes the writer commands. + void run() { + writeNodeSet(); + writeEdgeSet(); + writeNodes(); + writeEdges(); + os << "@end" << std::endl; + } + + private: + + void writeNodeSet() { + if (node_map_writers.size() == 0) return; + os << "@nodeset" << std::endl; + for (int i = 0; i < (int)node_map_writers.size(); ++i) { + os << node_map_writers[i].first << '\t'; + } + os << std::endl; + for (NodeIt it(graph); it != INVALID; ++it) { + for (int i = 0; i < (int)node_map_writers.size(); ++i) { + node_map_writers[i].second->write(os, it); + } + os << std::endl; + } + + } + + void writeEdgeSet() { + if (edge_map_writers.size() == 0) return; + if (node_map_writers.size() == 0) { + throw Exception() << "Missing node id map"; + } + os << "@edgeset" << std::endl; + os << "\t\t"; + for (int i = 0; i < (int)edge_map_writers.size(); ++i) { + os << edge_map_writers[i].first << '\t'; + } + os << std::endl; + for (EdgeIt it(graph); it != INVALID; ++it) { + node_map_writers[0].second->write(os, graph.source(it)); + node_map_writers[0].second->write(os, graph.target(it)); + for (int i = 0; i < (int)edge_map_writers.size(); ++i) { + edge_map_writers[i].second->write(os, it); + } + os << std::endl; + } + } + + void writeNodes() { + if (node_writers.size() == 0) return; + if (node_map_writers.size() == 0) { + throw Exception() << "Missing node id map"; + } + os << "@nodes" << std::endl; + for (int i = 0; i < (int)node_writers.size(); ++i) { + os << node_writers[i].first << '\t'; + node_map_writers[0].second->write(os, node_writers[i].second); + os << std::endl; + } + } + + void writeEdges() { + if (edge_writers.size() == 0) return; + if (edge_map_writers.size() == 0) { + throw Exception() << "Missing edge id map"; + } + os << "@edges" << std::endl; + for (int i = 0; i < (int)edge_writers.size(); ++i) { + os << edge_writers[i].first << '\t'; + edge_map_writers[0].second->write(os, edge_writers[i].second); + os << std::endl; + } + } + + // Writers + + template + class WriterBase { + public: + typedef _Item Item; + virtual void write(std::ostream&, const Item&) = 0; + }; + + template + class MapWriter : public WriterBase<_Item> { + public: + typedef _Map Map; + typedef _Writer Writer; + typedef typename Writer::Value Value; + typedef _Item Item; + + const Map& map; + Writer writer; + + MapWriter(const Map& _map, const Writer& _writer) + : map(_map), writer(_writer) {} + + + virtual void write(std::ostream& os, const Item& item) { + writer.write(os, map[item]); + } + + }; + + + + typedef std::vector< std::pair*> > + NodeMapWriters; + NodeMapWriters node_map_writers; + + typedef std::vector< std::pair*> > + EdgeMapWriters; + EdgeMapWriters edge_map_writers; + + typedef std::vector > NodeWriters; + NodeWriters node_writers; + + typedef std::vector > EdgeWriters; + EdgeWriters edge_writers; + + std::ostream& os; + Graph& graph; + + }; + + +}