Changeset 1409:d2d1f8fa187b in lemon-0.x for src/lemon/graph_writer.h
- Timestamp:
- 05/11/05 13:50:13 (20 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1876
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/lemon/graph_writer.h
r1402 r1409 23 23 24 24 #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 35 26 #include <lemon/error.h> 36 27 #include <lemon/lemon_writer.h> 37 28 38 29 namespace lemon { … … 41 32 /// @{ 42 33 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 Dezso48 struct DefaultWriterTraits {49 50 /// \brief Template class for writing an value.51 ///52 /// Template class for writing an value.53 /// \author Balazs Dezso54 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 escape80 /// sequences in the string.81 /// \author Balazs Dezso82 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 true89 /// 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 165 34 /// \brief The graph writer class. 166 35 /// … … 232 101 typedef _Graph Graph; 233 102 typedef typename Graph::Node Node; 234 typedef typename Graph::NodeIt NodeIt;235 103 typedef typename Graph::Edge Edge; 236 typedef typename Graph::EdgeIt EdgeIt;237 104 238 105 typedef _WriterTraits WriterTraits; 239 106 240 107 /// \brief Construct a new GraphWriter. 241 108 /// 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. 245 111 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()) {} 248 145 249 146 /// \brief Destruct the graph writer. … … 251 148 /// Destruct the graph writer. 252 149 ~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 } 266 153 267 154 /// \brief Add a new node map writer command for the writer. … … 270 157 template <typename Map> 271 158 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; 274 161 } 275 162 … … 279 166 template <typename Writer, typename Map> 280 167 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 288 173 289 174 /// \brief Add a new edge map writer command for the writer. … … 292 177 template <typename Map> 293 178 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; 296 181 } 297 182 … … 301 186 /// Add a new edge map writer command for the writer. 302 187 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); 307 191 return *this; 308 192 } … … 312 196 /// Add a new labeled node writer for the writer. 313 197 GraphWriter& writeNode(std::string name, const Node& node) { 314 node_writer s.push_back(make_pair(name, node));198 node_writer.writeNode(name, node); 315 199 return *this; 316 200 } … … 320 204 /// Add a new labeled edge writer for the writer. 321 205 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; 328 236 } 329 237 … … 331 239 /// 332 240 /// 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(); 342 243 } 343 244 344 245 private: 345 246 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; 445 257 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; 474 259 }; 260 475 261 476 262 /// \brief Write a graph to the output.
Note: See TracChangeset
for help on using the changeset viewer.