00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00020
00021
00022 #include <iostream>
00023 #include <sstream>
00024
00025 #include <map>
00026 #include <vector>
00027
00028 #include <memory>
00029
00030 #include <lemon/invalid.h>
00031 #include <lemon/error.h>
00032
00033
00034 namespace lemon {
00035
00040 struct DefaultWriterTraits {
00041
00045 template <typename _Value>
00046 struct Writer {
00048 typedef _Value Value;
00049
00053 void write(std::ostream& os, const Value& value) {
00054 os << value << '\t';
00055 }
00056 };
00057
00058 };
00059
00060
00065 class QuotedStringWriter {
00066 public:
00067 typedef std::string Value;
00068
00073 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
00074
00078 void write(std::ostream& os, const std::string& value) {
00079 os << "\"";
00080 if (escaped) {
00081 ostringstream ls;
00082 for (int i = 0; i < (int)value.size(); ++i) {
00083 writeEscape(ls, value[i]);
00084 }
00085 os << ls.str();
00086 } else {
00087 os << value;
00088 }
00089 os << "\"";
00090 }
00091
00092 private:
00093
00094 static void writeEscape(std::ostream& os, char c) {
00095 switch (c) {
00096 case '\\':
00097 os << "\\\\";
00098 return;
00099 case '\"':
00100 os << "\\\"";
00101 return;
00102 case '\'':
00103 os << "\\\'";
00104 return;
00105 case '\?':
00106 os << "\\\?";
00107 return;
00108 case '\a':
00109 os << "\\a";
00110 return;
00111 case '\b':
00112 os << "\\b";
00113 return;
00114 case '\f':
00115 os << "\\f";
00116 return;
00117 case '\r':
00118 os << "\\r";
00119 return;
00120 case '\n':
00121 os << "\\n";
00122 return;
00123 case '\t':
00124 os << "\\t";
00125 return;
00126 case '\v':
00127 os << "\\v";
00128 return;
00129 default:
00130 if (c < 0x20) {
00131 os << '\\' << oct << (int)c;
00132 } else {
00133 os << c;
00134 }
00135 return;
00136 }
00137 }
00138 private:
00139 bool escaped;
00140 };
00141
00142
00148 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
00149 class GraphWriter {
00150 public:
00151
00152 typedef _Graph Graph;
00153 typedef typename Graph::Node Node;
00154 typedef typename Graph::NodeIt NodeIt;
00155 typedef typename Graph::Edge Edge;
00156 typedef typename Graph::EdgeIt EdgeIt;
00157
00158 typedef _WriterTraits WriterTraits;
00159
00165 GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
00166
00167
00171 ~GraphWriter() {
00172 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
00173 it != node_map_writers.end(); ++it) {
00174 delete it->second;
00175 }
00176
00177 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
00178 it != edge_map_writers.end(); ++it) {
00179 delete it->second;
00180 }
00181
00182 }
00183
00184
00185
00189 template <typename Map>
00190 GraphWriter& addNodeMap(std::string name, const Map& map) {
00191 return addNodeMap<typename WriterTraits::template Writer<
00192 typename Map::Value>, Map>(name, map);
00193 }
00194
00198 template <typename Writer, typename Map>
00199 GraphWriter& addNodeMap(std::string name, const Map& map,
00200 const Writer& writer = Writer()) {
00201 node_map_writers.push_back(
00202 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
00203 return *this;
00204 }
00205
00206
00207
00211 template <typename Map>
00212 GraphWriter& addEdgeMap(std::string name, const Map& map) {
00213 return addEdgeMap<typename WriterTraits::template Writer<
00214 typename Map::Value>, Map>(name, map);
00215 }
00216
00217
00221 template <typename Writer, typename Map>
00222 GraphWriter& addEdgeMap(std::string name,
00223 const Map& map, const Writer& writer = Writer()) {
00224 edge_map_writers.push_back(make_pair(name,
00225 new MapWriter<Edge, Map, Writer>(map, writer)));
00226 return *this;
00227 }
00228
00232 GraphWriter& addNode(std::string name, const Node& node) {
00233 node_writers.push_back(make_pair(name, node));
00234 return *this;
00235 }
00236
00240 GraphWriter& addEdge(std::string name, const Edge& edge) {
00241 edge_writers.push_back(make_pair(name, edge));
00242 return *this;
00243 }
00244
00248 void run() {
00249 writeNodeSet();
00250 writeEdgeSet();
00251 writeNodes();
00252 writeEdges();
00253 os << "@end" << std::endl;
00254 }
00255
00256 private:
00257
00258 void writeNodeSet() {
00259 if (node_map_writers.size() == 0) return;
00260 os << "@nodeset" << std::endl;
00261 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
00262 os << node_map_writers[i].first << '\t';
00263 }
00264 os << std::endl;
00265 for (NodeIt it(graph); it != INVALID; ++it) {
00266 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
00267 node_map_writers[i].second->write(os, it);
00268 }
00269 os << std::endl;
00270 }
00271
00272 }
00273
00274 void writeEdgeSet() {
00275 if (edge_map_writers.size() == 0) return;
00276 if (node_map_writers.size() == 0) {
00277 throw Exception() << "Missing node id map";
00278 }
00279 os << "@edgeset" << std::endl;
00280 os << "\t\t";
00281 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
00282 os << edge_map_writers[i].first << '\t';
00283 }
00284 os << std::endl;
00285 for (EdgeIt it(graph); it != INVALID; ++it) {
00286 node_map_writers[0].second->write(os, graph.source(it));
00287 node_map_writers[0].second->write(os, graph.target(it));
00288 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
00289 edge_map_writers[i].second->write(os, it);
00290 }
00291 os << std::endl;
00292 }
00293 }
00294
00295 void writeNodes() {
00296 if (node_writers.size() == 0) return;
00297 if (node_map_writers.size() == 0) {
00298 throw Exception() << "Missing node id map";
00299 }
00300 os << "@nodes" << std::endl;
00301 for (int i = 0; i < (int)node_writers.size(); ++i) {
00302 os << node_writers[i].first << '\t';
00303 node_map_writers[0].second->write(os, node_writers[i].second);
00304 os << std::endl;
00305 }
00306 }
00307
00308 void writeEdges() {
00309 if (edge_writers.size() == 0) return;
00310 if (edge_map_writers.size() == 0) {
00311 throw Exception() << "Missing edge id map";
00312 }
00313 os << "@edges" << std::endl;
00314 for (int i = 0; i < (int)edge_writers.size(); ++i) {
00315 os << edge_writers[i].first << '\t';
00316 edge_map_writers[0].second->write(os, edge_writers[i].second);
00317 os << std::endl;
00318 }
00319 }
00320
00321
00322
00323 template <class _Item>
00324 class WriterBase {
00325 public:
00326 typedef _Item Item;
00327 virtual void write(std::ostream&, const Item&) = 0;
00328 };
00329
00330 template <class _Item, typename _Map, typename _Writer>
00331 class MapWriter : public WriterBase<_Item> {
00332 public:
00333 typedef _Map Map;
00334 typedef _Writer Writer;
00335 typedef typename Writer::Value Value;
00336 typedef _Item Item;
00337
00338 const Map& map;
00339 Writer writer;
00340
00341 MapWriter(const Map& _map, const Writer& _writer)
00342 : map(_map), writer(_writer) {}
00343
00344
00345 virtual void write(std::ostream& os, const Item& item) {
00346 writer.write(os, map[item]);
00347 }
00348
00349 };
00350
00351
00352
00353 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
00354 NodeMapWriters;
00355 NodeMapWriters node_map_writers;
00356
00357 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
00358 EdgeMapWriters;
00359 EdgeMapWriters edge_map_writers;
00360
00361 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
00362 NodeWriters node_writers;
00363
00364 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
00365 EdgeWriters edge_writers;
00366
00367 std::ostream& os;
00368 Graph& graph;
00369
00370 };
00371
00372
00373 }