1.1 --- a/src/lemon/graph_writer.h Mon May 09 11:24:26 2005 +0000
1.2 +++ b/src/lemon/graph_writer.h Wed May 11 11:50:13 2005 +0000
1.3 @@ -22,146 +22,15 @@
1.4 #define LEMON_GRAPH_WRITER_H
1.5
1.6 #include <iostream>
1.7 -#include <sstream>
1.8
1.9 -#include <map>
1.10 -#include <vector>
1.11 -
1.12 -#include <memory>
1.13 -
1.14 -#include <lemon/graph_utils.h>
1.15 -
1.16 -#include <lemon/invalid.h>
1.17 #include <lemon/error.h>
1.18 -
1.19 +#include <lemon/lemon_writer.h>
1.20
1.21 namespace lemon {
1.22
1.23 /// \addtogroup io_group
1.24 /// @{
1.25
1.26 - /// \brief Standard WriterTraits for the GraphWriter class.
1.27 - ///
1.28 - /// Standard WriterTraits for the GraphWriter class.
1.29 - /// It defines standard writing method for all type of value.
1.30 - /// \author Balazs Dezso
1.31 - struct DefaultWriterTraits {
1.32 -
1.33 - /// \brief Template class for writing an value.
1.34 - ///
1.35 - /// Template class for writing an value.
1.36 - /// \author Balazs Dezso
1.37 - template <typename _Value>
1.38 - struct Writer {
1.39 - /// The value type.
1.40 - typedef _Value Value;
1.41 -
1.42 - /// \brief Writes a value to the given stream.
1.43 - ///
1.44 - /// Writes a value to the given stream.
1.45 - void write(std::ostream& os, const Value& value) {
1.46 - os << value << '\t';
1.47 - }
1.48 - };
1.49 -
1.50 - /// \brief Returns wheter this name is an ID map name.
1.51 - ///
1.52 - /// Returns wheter this name is an ID map name.
1.53 - static bool idMapName(const std::string& name) {
1.54 - return name == "id";
1.55 - }
1.56 -
1.57 - };
1.58 -
1.59 -
1.60 - /// \brief Writer class for quoted strings.
1.61 - ///
1.62 - /// Writer class for quoted strings. It can process the escape
1.63 - /// sequences in the string.
1.64 - /// \author Balazs Dezso
1.65 - class QuotedStringWriter {
1.66 - public:
1.67 - typedef std::string Value;
1.68 -
1.69 - /// \brief Constructor for the writer.
1.70 - ///
1.71 - /// Constructor for the writer. If the given parameter is true
1.72 - /// the writer creates escape sequences from special characters.
1.73 - QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
1.74 -
1.75 - /// \brief Writes a quoted string to the given stream.
1.76 - ///
1.77 - /// Writes a quoted string to the given stream.
1.78 - void write(std::ostream& os, const std::string& value) {
1.79 - os << "\"";
1.80 - if (escaped) {
1.81 - std::ostringstream ls;
1.82 - for (int i = 0; i < (int)value.size(); ++i) {
1.83 - writeEscape(ls, value[i]);
1.84 - }
1.85 - os << ls.str();
1.86 - } else {
1.87 - os << value;
1.88 - }
1.89 - os << "\"";
1.90 - }
1.91 -
1.92 - private:
1.93 -
1.94 - static void writeEscape(std::ostream& os, char c) {
1.95 - switch (c) {
1.96 - case '\\':
1.97 - os << "\\\\";
1.98 - return;
1.99 - case '\"':
1.100 - os << "\\\"";
1.101 - return;
1.102 - case '\'':
1.103 - os << "\\\'";
1.104 - return;
1.105 - case '\?':
1.106 - os << "\\\?";
1.107 - return;
1.108 - case '\a':
1.109 - os << "\\a";
1.110 - return;
1.111 - case '\b':
1.112 - os << "\\b";
1.113 - return;
1.114 - case '\f':
1.115 - os << "\\f";
1.116 - return;
1.117 - case '\r':
1.118 - os << "\\r";
1.119 - return;
1.120 - case '\n':
1.121 - os << "\\n";
1.122 - return;
1.123 - case '\t':
1.124 - os << "\\t";
1.125 - return;
1.126 - case '\v':
1.127 - os << "\\v";
1.128 - return;
1.129 - default:
1.130 - if (c < 0x20) {
1.131 - os << '\\' << std::oct << (int)c;
1.132 - } else {
1.133 - os << c;
1.134 - }
1.135 - return;
1.136 - }
1.137 - }
1.138 - private:
1.139 - bool escaped;
1.140 - };
1.141 -
1.142 - class GUIWriter {
1.143 - public:
1.144 - virtual void write(std::ostream& os) = 0;
1.145 - };
1.146 -
1.147 -
1.148 /// \brief The graph writer class.
1.149 ///
1.150 /// The \c GraphWriter class provides the graph output. To write a graph
1.151 @@ -231,46 +100,64 @@
1.152
1.153 typedef _Graph Graph;
1.154 typedef typename Graph::Node Node;
1.155 - typedef typename Graph::NodeIt NodeIt;
1.156 typedef typename Graph::Edge Edge;
1.157 - typedef typename Graph::EdgeIt EdgeIt;
1.158
1.159 typedef _WriterTraits WriterTraits;
1.160 -
1.161 +
1.162 /// \brief Construct a new GraphWriter.
1.163 ///
1.164 - /// Construct a new GraphWriter. It writes from the given map,
1.165 - /// it constructs the given map and it use the given writer as the
1.166 - /// default skipper.
1.167 + /// Construct a new GraphWriter. It writes the given graph
1.168 + /// to the given stream.
1.169 GraphWriter(std::ostream& _os, const Graph& _graph)
1.170 - : gui_writer(0), os(_os), graph(_graph){}
1.171 + : writer(new LemonWriter(_os)), own_writer(true),
1.172 + graph(_graph),
1.173 + nodeset_writer(*writer, graph, std::string()),
1.174 + edgeset_writer(*writer, graph, nodeset_writer, std::string()),
1.175 + node_writer(*writer, nodeset_writer, std::string()),
1.176 + edge_writer(*writer, edgeset_writer, std::string()),
1.177 + attribute_writer(*writer, std::string()) {}
1.178
1.179 + /// \brief Construct a new GraphWriter.
1.180 + ///
1.181 + /// Construct a new GraphWriter. It writes into the given graph
1.182 + /// to the given file.
1.183 + GraphWriter(const std::string& _filename, const Graph& _graph)
1.184 + : writer(new LemonWriter(_filename)), own_writer(true),
1.185 + graph(_graph),
1.186 + nodeset_writer(*writer, graph, std::string(), skipper),
1.187 + edgeset_writer(*writer, graph, nodeset_writer, std::string(), skipper),
1.188 + node_writer(*writer, nodeset_writer, std::string()),
1.189 + edge_writer(*writer, edgeset_writer, std::string()),
1.190 + attribute_writer(*writer, std::string()) {}
1.191 +
1.192 + /// \brief Construct a new GraphWriter.
1.193 + ///
1.194 + /// Construct a new GraphWriter. It writes into the given graph
1.195 + /// to given LemonReader.
1.196 + GraphWriter(LemonWriter& _writer, const Graph& _graph)
1.197 + : writer(_writer), own_writer(false),
1.198 + graph(_graph),
1.199 + nodeset_writer(*writer, graph, std::string()),
1.200 + edgeset_writer(*writer, graph, nodeset_writer, std::string()),
1.201 + node_writer(*writer, nodeset_writer, std::string()),
1.202 + edge_writer(*writer, edgeset_writer, std::string()),
1.203 + attribute_writer(*writer, std::string()) {}
1.204
1.205 /// \brief Destruct the graph writer.
1.206 ///
1.207 /// Destruct the graph writer.
1.208 ~GraphWriter() {
1.209 - for (typename NodeMapWriters::iterator it = node_map_writers.begin();
1.210 - it != node_map_writers.end(); ++it) {
1.211 - delete it->second;
1.212 - }
1.213 -
1.214 - for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
1.215 - it != edge_map_writers.end(); ++it) {
1.216 - delete it->second;
1.217 - }
1.218 -
1.219 + if (own_writer)
1.220 + delete writer;
1.221 }
1.222
1.223 - // Node map rules
1.224 -
1.225 /// \brief Add a new node map writer command for the writer.
1.226 ///
1.227 /// Add a new node map writer command for the writer.
1.228 template <typename Map>
1.229 GraphWriter& writeNodeMap(std::string name, const Map& map) {
1.230 - return writeNodeMap<typename WriterTraits::template Writer<
1.231 - typename Map::Value>, Map>(name, map);
1.232 + nodeset_writer.writeMap(name, map);
1.233 + return *this;
1.234 }
1.235
1.236 /// \brief Add a new node map writer command for the writer.
1.237 @@ -278,21 +165,19 @@
1.238 /// Add a new node map writer command for the writer.
1.239 template <typename Writer, typename Map>
1.240 GraphWriter& writeNodeMap(std::string name, const Map& map,
1.241 - const Writer& writer = Writer()) {
1.242 - node_map_writers.push_back(
1.243 - make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
1.244 + const Writer& writer = Writer()) {
1.245 + nodeset_writer.writeMap(name, map, writer);
1.246 return *this;
1.247 }
1.248
1.249 - // Edge map rules
1.250
1.251 /// \brief Add a new edge map writer command for the writer.
1.252 ///
1.253 /// Add a new edge map writer command for the writer.
1.254 template <typename Map>
1.255 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
1.256 - return writeEdgeMap<typename WriterTraits::template Writer<
1.257 - typename Map::Value>, Map>(name, map);
1.258 + edgeset_writer.writeMap(name, map);
1.259 + return *this;
1.260 }
1.261
1.262
1.263 @@ -300,10 +185,9 @@
1.264 ///
1.265 /// Add a new edge map writer command for the writer.
1.266 template <typename Writer, typename Map>
1.267 - GraphWriter& writeEdgeMap(std::string name,
1.268 - const Map& map, const Writer& writer = Writer()) {
1.269 - edge_map_writers.push_back(make_pair(name,
1.270 - new MapWriter<Edge, Map, Writer>(map, writer)));
1.271 + GraphWriter& writeEdgeMap(std::string name, const Map& map,
1.272 + const Writer& writer = Writer()) {
1.273 + edgeset_writer.writeMap(name, map, writer);
1.274 return *this;
1.275 }
1.276
1.277 @@ -311,7 +195,7 @@
1.278 ///
1.279 /// Add a new labeled node writer for the writer.
1.280 GraphWriter& writeNode(std::string name, const Node& node) {
1.281 - node_writers.push_back(make_pair(name, node));
1.282 + node_writer.writeNode(name, node);
1.283 return *this;
1.284 }
1.285
1.286 @@ -319,160 +203,62 @@
1.287 ///
1.288 /// Add a new labeled edge writer for the writer.
1.289 GraphWriter& writeEdge(std::string name, const Edge& edge) {
1.290 - edge_writers.push_back(make_pair(name, edge));
1.291 + edge_writer.writeEdge(name, edge);
1.292 + }
1.293 +
1.294 + /// \brief Add a new attribute writer command.
1.295 + ///
1.296 + /// Add a new attribute writer command.
1.297 + template <typename Value>
1.298 + GraphWriter& writeAttribute(std::string name, const Value& value) {
1.299 + attribute_writer.writeAttribute(name, value);
1.300 + return *this;
1.301 + }
1.302 +
1.303 + /// \brief Add a new attribute writer command.
1.304 + ///
1.305 + /// Add a new attribute writer command.
1.306 + template <typename Writer, typename Value>
1.307 + GraphWriter& writeAttribute(std::string name, const Value& value,
1.308 + const Writer& writer) {
1.309 + attribute_writer.writeAttribute<Writer>(name, value, writer);
1.310 return *this;
1.311 }
1.312
1.313 - GraphWriter& writeGUI(const GUIWriter& writer) {
1.314 - gui_writer = &writer;
1.315 + /// \brief Conversion operator to LemonWriter.
1.316 + ///
1.317 + /// Conversion operator to LemonWriter. It make possible
1.318 + /// to access the encapsulated \e LemonWriter, this way
1.319 + /// you can attach to this writer new instances of
1.320 + /// \e LemonWriter::SectionWriter.
1.321 + operator LemonWriter&() {
1.322 + return *writer;
1.323 }
1.324
1.325 /// \brief Executes the writer commands.
1.326 ///
1.327 /// Executes the writer commands.
1.328 - void run() {
1.329 - WriterBase<Node>* nodeWriter = 0;
1.330 - WriterBase<Edge>* edgeWriter = 0;
1.331 - writeNodeSet(nodeWriter);
1.332 - writeEdgeSet(nodeWriter, edgeWriter);
1.333 - writeNodes(nodeWriter);
1.334 - writeEdges(edgeWriter);
1.335 - writeGUI();
1.336 - os << "@end" << std::endl;
1.337 + void run() {
1.338 + writer->run();
1.339 }
1.340
1.341 private:
1.342
1.343 - template <class _Item>
1.344 - class WriterBase {
1.345 - public:
1.346 - typedef _Item Item;
1.347 - virtual void write(std::ostream&, const Item&) = 0;
1.348 - };
1.349 + LemonWriter* writer;
1.350 + bool own_writer;
1.351
1.352 - template <class _Item, typename _Map, typename _Writer>
1.353 - class MapWriter : public WriterBase<_Item> {
1.354 - public:
1.355 - typedef _Map Map;
1.356 - typedef _Writer Writer;
1.357 - typedef typename Writer::Value Value;
1.358 - typedef _Item Item;
1.359 -
1.360 - const Map& map;
1.361 - Writer writer;
1.362 -
1.363 - MapWriter(const Map& _map, const Writer& _writer)
1.364 - : map(_map), writer(_writer) {}
1.365 -
1.366 -
1.367 - virtual void write(std::ostream& os, const Item& item) {
1.368 - writer.write(os, map[item]);
1.369 - }
1.370 -
1.371 - };
1.372 -
1.373 - void writeNodeSet(WriterBase<Node>* & nodeWriter) {
1.374 - if (node_map_writers.size() == 0) return;
1.375 - os << "@nodeset" << std::endl;
1.376 - for (int i = 0; i < (int)node_map_writers.size(); ++i) {
1.377 - const std::string& id = node_map_writers[i].first;
1.378 - os << id << '\t';
1.379 - if (WriterTraits::idMapName(id) && nodeWriter == 0) {
1.380 - nodeWriter = node_map_writers[i].second;
1.381 - }
1.382 - }
1.383 - os << std::endl;
1.384 - for (NodeIt it(graph); it != INVALID; ++it) {
1.385 - for (int i = 0; i < (int)node_map_writers.size(); ++i) {
1.386 - node_map_writers[i].second->write(os, it);
1.387 - }
1.388 - os << std::endl;
1.389 - }
1.390 -
1.391 - }
1.392 -
1.393 - void writeEdgeSet(WriterBase<Node>* nodeWriter,
1.394 - WriterBase<Edge>* & edgeWriter) {
1.395 - if (edge_map_writers.size() == 0) return;
1.396 - if (nodeWriter == 0) {
1.397 - throw DataFormatError("Cannot find node id map");
1.398 - }
1.399 - os << "@edgeset" << std::endl;
1.400 - os << "\t\t";
1.401 - for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
1.402 - const std::string& id = edge_map_writers[i].first;
1.403 - os << id << '\t';
1.404 - if (WriterTraits::idMapName(id) && edgeWriter == 0) {
1.405 - edgeWriter = edge_map_writers[i].second;
1.406 - }
1.407 - }
1.408 - os << std::endl;
1.409 - for (EdgeIt it(graph); it != INVALID; ++it) {
1.410 - nodeWriter->write(os, graph.source(it));
1.411 - nodeWriter->write(os, graph.target(it));
1.412 - for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
1.413 - edge_map_writers[i].second->write(os, it);
1.414 - }
1.415 - os << std::endl;
1.416 - }
1.417 - }
1.418 -
1.419 - void writeNodes(WriterBase<Node>* nodeWriter) {
1.420 - if (node_writers.size() == 0) return;
1.421 - if (nodeWriter == 0) {
1.422 - throw DataFormatError("Cannot find node id map");
1.423 - }
1.424 - os << "@nodes" << std::endl;
1.425 - for (int i = 0; i < (int)node_writers.size(); ++i) {
1.426 - os << node_writers[i].first << '\t';
1.427 - nodeWriter->write(os, node_writers[i].second);
1.428 - os << std::endl;
1.429 - }
1.430 - }
1.431 -
1.432 - void writeEdges(WriterBase<Edge>* edgeWriter) {
1.433 - if (edge_writers.size() == 0) return;
1.434 - if (edgeWriter == 0) {
1.435 - throw DataFormatError("Cannot find node id map");
1.436 - }
1.437 - os << "@edges" << std::endl;
1.438 - for (int i = 0; i < (int)edge_writers.size(); ++i) {
1.439 - os << edge_writers[i].first << '\t';
1.440 - edgeWriter->write(os, edge_writers[i].second);
1.441 - os << std::endl;
1.442 - }
1.443 - }
1.444 -
1.445 - void writeGUI() {
1.446 - if (gui_writer) {
1.447 - os << "@gui" << std::endl;
1.448 - gui_writer->write(os);
1.449 - }
1.450 - }
1.451 -
1.452 -
1.453 -
1.454 - typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
1.455 - NodeMapWriters;
1.456 - NodeMapWriters node_map_writers;
1.457 -
1.458 - typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
1.459 - EdgeMapWriters;
1.460 - EdgeMapWriters edge_map_writers;
1.461 -
1.462 - typedef std::vector<std::pair<std::string, Node> > NodeWriters;
1.463 - NodeWriters node_writers;
1.464 -
1.465 - typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
1.466 - EdgeWriters edge_writers;
1.467 -
1.468 - GUIWriter* gui_writer;
1.469 -
1.470 - std::ostream& os;
1.471 const Graph& graph;
1.472
1.473 + NodeSetWriter<Graph, WriterTraits> nodeset_writer;
1.474 + EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
1.475 +
1.476 + NodeWriter<Graph> node_writer;
1.477 + EdgeWriter<Graph> edge_writer;
1.478 +
1.479 + AttributeWriter<WriterTraits> attribute_writer;
1.480 };
1.481
1.482 +
1.483 /// \brief Write a graph to the output.
1.484 ///
1.485 /// Write a graph to the output.