229 class GraphWriter { |
98 class GraphWriter { |
230 public: |
99 public: |
231 |
100 |
232 typedef _Graph Graph; |
101 typedef _Graph Graph; |
233 typedef typename Graph::Node Node; |
102 typedef typename Graph::Node Node; |
234 typedef typename Graph::NodeIt NodeIt; |
|
235 typedef typename Graph::Edge Edge; |
103 typedef typename Graph::Edge Edge; |
236 typedef typename Graph::EdgeIt EdgeIt; |
|
237 |
104 |
238 typedef _WriterTraits WriterTraits; |
105 typedef _WriterTraits WriterTraits; |
239 |
106 |
240 /// \brief Construct a new GraphWriter. |
107 /// \brief Construct a new GraphWriter. |
241 /// |
108 /// |
242 /// Construct a new GraphWriter. It writes from the given map, |
109 /// Construct a new GraphWriter. It writes the given graph |
243 /// it constructs the given map and it use the given writer as the |
110 /// to the given stream. |
244 /// default skipper. |
|
245 GraphWriter(std::ostream& _os, const Graph& _graph) |
111 GraphWriter(std::ostream& _os, const Graph& _graph) |
246 : gui_writer(0), os(_os), graph(_graph){} |
112 : writer(new LemonWriter(_os)), own_writer(true), |
247 |
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 /// \brief Destruct the graph writer. |
146 /// \brief Destruct the graph writer. |
250 /// |
147 /// |
251 /// Destruct the graph writer. |
148 /// Destruct the graph writer. |
252 ~GraphWriter() { |
149 ~GraphWriter() { |
253 for (typename NodeMapWriters::iterator it = node_map_writers.begin(); |
150 if (own_writer) |
254 it != node_map_writers.end(); ++it) { |
151 delete writer; |
255 delete it->second; |
152 } |
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 |
|
266 |
153 |
267 /// \brief Add a new node map writer command for the writer. |
154 /// \brief Add a new node map writer command for the writer. |
268 /// |
155 /// |
269 /// Add a new node map writer command for the writer. |
156 /// Add a new node map writer command for the writer. |
270 template <typename Map> |
157 template <typename Map> |
271 GraphWriter& writeNodeMap(std::string name, const Map& map) { |
158 GraphWriter& writeNodeMap(std::string name, const Map& map) { |
272 return writeNodeMap<typename WriterTraits::template Writer< |
159 nodeset_writer.writeMap(name, map); |
273 typename Map::Value>, Map>(name, map); |
160 return *this; |
274 } |
161 } |
275 |
162 |
276 /// \brief Add a new node map writer command for the writer. |
163 /// \brief Add a new node map writer command for the writer. |
277 /// |
164 /// |
278 /// Add a new node map writer command for the writer. |
165 /// Add a new node map writer command for the writer. |
279 template <typename Writer, typename Map> |
166 template <typename Writer, typename Map> |
280 GraphWriter& writeNodeMap(std::string name, const Map& map, |
167 GraphWriter& writeNodeMap(std::string name, const Map& map, |
281 const Writer& writer = Writer()) { |
168 const Writer& writer = Writer()) { |
282 node_map_writers.push_back( |
169 nodeset_writer.writeMap(name, map, writer); |
283 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer))); |
170 return *this; |
284 return *this; |
171 } |
285 } |
172 |
286 |
|
287 // Edge map rules |
|
288 |
173 |
289 /// \brief Add a new edge map writer command for the writer. |
174 /// \brief Add a new edge map writer command for the writer. |
290 /// |
175 /// |
291 /// Add a new edge map writer command for the writer. |
176 /// Add a new edge map writer command for the writer. |
292 template <typename Map> |
177 template <typename Map> |
293 GraphWriter& writeEdgeMap(std::string name, const Map& map) { |
178 GraphWriter& writeEdgeMap(std::string name, const Map& map) { |
294 return writeEdgeMap<typename WriterTraits::template Writer< |
179 edgeset_writer.writeMap(name, map); |
295 typename Map::Value>, Map>(name, map); |
180 return *this; |
296 } |
181 } |
297 |
182 |
298 |
183 |
299 /// \brief Add a new edge map writer command for the writer. |
184 /// \brief Add a new edge map writer command for the writer. |
300 /// |
185 /// |
301 /// Add a new edge map writer command for the writer. |
186 /// Add a new edge map writer command for the writer. |
302 template <typename Writer, typename Map> |
187 template <typename Writer, typename Map> |
303 GraphWriter& writeEdgeMap(std::string name, |
188 GraphWriter& writeEdgeMap(std::string name, const Map& map, |
304 const Map& map, const Writer& writer = Writer()) { |
189 const Writer& writer = Writer()) { |
305 edge_map_writers.push_back(make_pair(name, |
190 edgeset_writer.writeMap(name, map, writer); |
306 new MapWriter<Edge, Map, Writer>(map, writer))); |
|
307 return *this; |
191 return *this; |
308 } |
192 } |
309 |
193 |
310 /// \brief Add a new labeled node writer for the writer. |
194 /// \brief Add a new labeled node writer for the writer. |
311 /// |
195 /// |
312 /// Add a new labeled node writer for the writer. |
196 /// Add a new labeled node writer for the writer. |
313 GraphWriter& writeNode(std::string name, const Node& node) { |
197 GraphWriter& writeNode(std::string name, const Node& node) { |
314 node_writers.push_back(make_pair(name, node)); |
198 node_writer.writeNode(name, node); |
315 return *this; |
199 return *this; |
316 } |
200 } |
317 |
201 |
318 /// \brief Add a new labeled edge writer for the writer. |
202 /// \brief Add a new labeled edge writer for the writer. |
319 /// |
203 /// |
320 /// Add a new labeled edge writer for the writer. |
204 /// Add a new labeled edge writer for the writer. |
321 GraphWriter& writeEdge(std::string name, const Edge& edge) { |
205 GraphWriter& writeEdge(std::string name, const Edge& edge) { |
322 edge_writers.push_back(make_pair(name, edge)); |
206 edge_writer.writeEdge(name, edge); |
323 return *this; |
207 } |
324 } |
208 |
325 |
209 /// \brief Add a new attribute writer command. |
326 GraphWriter& writeGUI(const GUIWriter& writer) { |
210 /// |
327 gui_writer = &writer; |
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 |
330 /// \brief Executes the writer commands. |
238 /// \brief Executes the writer commands. |
331 /// |
239 /// |
332 /// Executes the writer commands. |
240 /// Executes the writer commands. |
333 void run() { |
241 void run() { |
334 WriterBase<Node>* nodeWriter = 0; |
242 writer->run(); |
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; |
|
342 } |
243 } |
343 |
244 |
344 private: |
245 private: |
345 |
246 |
346 template <class _Item> |
247 LemonWriter* writer; |
347 class WriterBase { |
248 bool own_writer; |
348 public: |
249 |
349 typedef _Item Item; |
250 const Graph& graph; |
350 virtual void write(std::ostream&, const Item&) = 0; |
251 |
351 }; |
252 NodeSetWriter<Graph, WriterTraits> nodeset_writer; |
352 |
253 EdgeSetWriter<Graph, WriterTraits> edgeset_writer; |
353 template <class _Item, typename _Map, typename _Writer> |
254 |
354 class MapWriter : public WriterBase<_Item> { |
255 NodeWriter<Graph> node_writer; |
355 public: |
256 EdgeWriter<Graph> edge_writer; |
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 } |
|
445 |
257 |
446 void writeGUI() { |
258 AttributeWriter<WriterTraits> attribute_writer; |
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 |
|
474 }; |
259 }; |
|
260 |
475 |
261 |
476 /// \brief Write a graph to the output. |
262 /// \brief Write a graph to the output. |
477 /// |
263 /// |
478 /// Write a graph to the output. |
264 /// Write a graph to the output. |
479 /// \param os The output stream. |
265 /// \param os The output stream. |