|
1 /* -*- C++ -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2008 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 ///\ingroup lemon_io |
|
20 ///\file |
|
21 ///\brief Lemon Graph Format reader. |
|
22 |
|
23 |
|
24 #ifndef LEMON_LGF_READER_H |
|
25 #define LEMON_LGF_READER_H |
|
26 |
|
27 #include <iostream> |
|
28 #include <fstream> |
|
29 #include <sstream> |
|
30 |
|
31 #include <set> |
|
32 #include <map> |
|
33 |
|
34 #include <lemon/assert.h> |
|
35 #include <lemon/graph_utils.h> |
|
36 |
|
37 #include <lemon/lgf_writer.h> |
|
38 |
|
39 #include <lemon/concept_check.h> |
|
40 #include <lemon/concepts/maps.h> |
|
41 |
|
42 namespace lemon { |
|
43 |
|
44 namespace _reader_bits { |
|
45 |
|
46 template <typename Value> |
|
47 struct DefaultConverter { |
|
48 Value operator()(const std::string& str) { |
|
49 std::istringstream is(str); |
|
50 Value value; |
|
51 is >> value; |
|
52 |
|
53 char c; |
|
54 if (is >> std::ws >> c) { |
|
55 throw DataFormatError("Remaining characters in token"); |
|
56 } |
|
57 return value; |
|
58 } |
|
59 }; |
|
60 |
|
61 template <> |
|
62 struct DefaultConverter<std::string> { |
|
63 std::string operator()(const std::string& str) { |
|
64 return str; |
|
65 } |
|
66 }; |
|
67 |
|
68 template <typename _Item> |
|
69 class MapStorageBase { |
|
70 public: |
|
71 typedef _Item Item; |
|
72 |
|
73 public: |
|
74 MapStorageBase() {} |
|
75 virtual ~MapStorageBase() {} |
|
76 |
|
77 virtual void set(const Item& item, const std::string& value) = 0; |
|
78 |
|
79 }; |
|
80 |
|
81 template <typename _Item, typename _Map, |
|
82 typename _Converter = DefaultConverter<typename _Map::Value> > |
|
83 class MapStorage : public MapStorageBase<_Item> { |
|
84 public: |
|
85 typedef _Map Map; |
|
86 typedef _Converter Converter; |
|
87 typedef _Item Item; |
|
88 |
|
89 private: |
|
90 Map& _map; |
|
91 Converter _converter; |
|
92 |
|
93 public: |
|
94 MapStorage(Map& map, const Converter& converter = Converter()) |
|
95 : _map(map), _converter(converter) {} |
|
96 virtual ~MapStorage() {} |
|
97 |
|
98 virtual void set(const Item& item ,const std::string& value) { |
|
99 _map.set(item, _converter(value)); |
|
100 } |
|
101 }; |
|
102 |
|
103 class ValueStorageBase { |
|
104 public: |
|
105 ValueStorageBase() {} |
|
106 virtual ~ValueStorageBase() {} |
|
107 |
|
108 virtual void set(const std::string&) = 0; |
|
109 }; |
|
110 |
|
111 template <typename _Value, typename _Converter = DefaultConverter<_Value> > |
|
112 class ValueStorage : public ValueStorageBase { |
|
113 public: |
|
114 typedef _Value Value; |
|
115 typedef _Converter Converter; |
|
116 |
|
117 private: |
|
118 Value& _value; |
|
119 Converter _converter; |
|
120 |
|
121 public: |
|
122 ValueStorage(Value& value, const Converter& converter = Converter()) |
|
123 : _value(value), _converter(converter) {} |
|
124 |
|
125 virtual void set(const std::string& value) { |
|
126 _value = _converter(value); |
|
127 } |
|
128 }; |
|
129 |
|
130 template <typename Value> |
|
131 struct MapLookUpConverter { |
|
132 const std::map<std::string, Value>& _map; |
|
133 |
|
134 MapLookUpConverter(const std::map<std::string, Value>& map) |
|
135 : _map(map) {} |
|
136 |
|
137 Value operator()(const std::string& str) { |
|
138 typename std::map<std::string, Value>::const_iterator it = |
|
139 _map.find(str); |
|
140 if (it == _map.end()) { |
|
141 std::ostringstream msg; |
|
142 msg << "Item not found: " << str; |
|
143 throw DataFormatError(msg.str().c_str()); |
|
144 } |
|
145 return it->second; |
|
146 } |
|
147 }; |
|
148 |
|
149 bool isWhiteSpace(char c) { |
|
150 return c == ' ' || c == '\t' || c == '\v' || |
|
151 c == '\n' || c == '\r' || c == '\f'; |
|
152 } |
|
153 |
|
154 bool isOct(char c) { |
|
155 return '0' <= c && c <='7'; |
|
156 } |
|
157 |
|
158 int valueOct(char c) { |
|
159 LEMON_ASSERT(isOct(c), "The character is not octal."); |
|
160 return c - '0'; |
|
161 } |
|
162 |
|
163 bool isHex(char c) { |
|
164 return ('0' <= c && c <= '9') || |
|
165 ('a' <= c && c <= 'z') || |
|
166 ('A' <= c && c <= 'Z'); |
|
167 } |
|
168 |
|
169 int valueHex(char c) { |
|
170 LEMON_ASSERT(isHex(c), "The character is not hexadecimal."); |
|
171 if ('0' <= c && c <= '9') return c - '0'; |
|
172 if ('a' <= c && c <= 'z') return c - 'a' + 10; |
|
173 return c - 'A' + 10; |
|
174 } |
|
175 |
|
176 bool isIdentifierFirstChar(char c) { |
|
177 return ('a' <= c && c <= 'z') || |
|
178 ('A' <= c && c <= 'Z') || c == '_'; |
|
179 } |
|
180 |
|
181 bool isIdentifierChar(char c) { |
|
182 return isIdentifierFirstChar(c) || |
|
183 ('0' <= c && c <= '9'); |
|
184 } |
|
185 |
|
186 char readEscape(std::istream& is) { |
|
187 char c; |
|
188 if (!is.get(c)) |
|
189 throw DataFormatError("Escape format error"); |
|
190 |
|
191 switch (c) { |
|
192 case '\\': |
|
193 return '\\'; |
|
194 case '\"': |
|
195 return '\"'; |
|
196 case '\'': |
|
197 return '\''; |
|
198 case '\?': |
|
199 return '\?'; |
|
200 case 'a': |
|
201 return '\a'; |
|
202 case 'b': |
|
203 return '\b'; |
|
204 case 'f': |
|
205 return '\f'; |
|
206 case 'n': |
|
207 return '\n'; |
|
208 case 'r': |
|
209 return '\r'; |
|
210 case 't': |
|
211 return '\t'; |
|
212 case 'v': |
|
213 return '\v'; |
|
214 case 'x': |
|
215 { |
|
216 int code; |
|
217 if (!is.get(c) || !isHex(c)) |
|
218 throw DataFormatError("Escape format error"); |
|
219 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); |
|
220 else code = code * 16 + valueHex(c); |
|
221 return code; |
|
222 } |
|
223 default: |
|
224 { |
|
225 int code; |
|
226 if (!isOct(c)) |
|
227 throw DataFormatError("Escape format error"); |
|
228 else if (code = valueOct(c), !is.get(c) || !isOct(c)) |
|
229 is.putback(c); |
|
230 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) |
|
231 is.putback(c); |
|
232 else code = code * 8 + valueOct(c); |
|
233 return code; |
|
234 } |
|
235 } |
|
236 } |
|
237 |
|
238 std::istream& readToken(std::istream& is, std::string& str) { |
|
239 std::ostringstream os; |
|
240 |
|
241 char c; |
|
242 is >> std::ws; |
|
243 |
|
244 if (!is.get(c)) |
|
245 return is; |
|
246 |
|
247 if (c == '\"') { |
|
248 while (is.get(c) && c != '\"') { |
|
249 if (c == '\\') |
|
250 c = readEscape(is); |
|
251 os << c; |
|
252 } |
|
253 if (!is) |
|
254 throw DataFormatError("Quoted format error"); |
|
255 } else { |
|
256 is.putback(c); |
|
257 while (is.get(c) && !isWhiteSpace(c)) { |
|
258 if (c == '\\') |
|
259 c = readEscape(is); |
|
260 os << c; |
|
261 } |
|
262 if (!is) { |
|
263 is.clear(); |
|
264 } else { |
|
265 is.putback(c); |
|
266 } |
|
267 } |
|
268 str = os.str(); |
|
269 return is; |
|
270 } |
|
271 |
|
272 std::istream& readIdentifier(std::istream& is, std::string& str) { |
|
273 std::ostringstream os; |
|
274 |
|
275 char c; |
|
276 is >> std::ws; |
|
277 |
|
278 if (!is.get(c)) |
|
279 return is; |
|
280 |
|
281 if (!isIdentifierFirstChar(c)) |
|
282 throw DataFormatError("Wrong char in identifier"); |
|
283 |
|
284 os << c; |
|
285 |
|
286 while (is.get(c) && !isWhiteSpace(c)) { |
|
287 if (!isIdentifierChar(c)) |
|
288 throw DataFormatError("Wrong char in identifier"); |
|
289 os << c; |
|
290 } |
|
291 if (!is) is.clear(); |
|
292 |
|
293 str = os.str(); |
|
294 return is; |
|
295 } |
|
296 |
|
297 } |
|
298 |
|
299 /// \e |
|
300 template <typename _Digraph> |
|
301 class DigraphReader { |
|
302 public: |
|
303 |
|
304 typedef _Digraph Digraph; |
|
305 GRAPH_TYPEDEFS(typename Digraph); |
|
306 |
|
307 private: |
|
308 |
|
309 |
|
310 std::istream* _is; |
|
311 bool local_is; |
|
312 |
|
313 Digraph& _digraph; |
|
314 |
|
315 std::string _nodes_caption; |
|
316 std::string _arcs_caption; |
|
317 std::string _attributes_caption; |
|
318 |
|
319 typedef std::map<std::string, Node> NodeIndex; |
|
320 NodeIndex _node_index; |
|
321 typedef std::map<std::string, Arc> ArcIndex; |
|
322 ArcIndex _arc_index; |
|
323 |
|
324 typedef std::vector<std::pair<std::string, |
|
325 _reader_bits::MapStorageBase<Node>*> > NodeMaps; |
|
326 NodeMaps _node_maps; |
|
327 |
|
328 typedef std::vector<std::pair<std::string, |
|
329 _reader_bits::MapStorageBase<Arc>*> >ArcMaps; |
|
330 ArcMaps _arc_maps; |
|
331 |
|
332 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> |
|
333 Attributes; |
|
334 Attributes _attributes; |
|
335 |
|
336 bool _use_nodes; |
|
337 bool _use_arcs; |
|
338 |
|
339 int line_num; |
|
340 std::istringstream line; |
|
341 |
|
342 public: |
|
343 |
|
344 /// \e |
|
345 DigraphReader(std::istream& is, Digraph& digraph) |
|
346 : _is(&is), local_is(false), _digraph(digraph), |
|
347 _use_nodes(false), _use_arcs(false) {} |
|
348 |
|
349 /// \e |
|
350 DigraphReader(const std::string& fn, Digraph& digraph) |
|
351 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph), |
|
352 _use_nodes(false), _use_arcs(false) {} |
|
353 |
|
354 |
|
355 /// \e |
|
356 DigraphReader(const char* fn, Digraph& digraph) |
|
357 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph), |
|
358 _use_nodes(false), _use_arcs(false) {} |
|
359 |
|
360 /// \e |
|
361 DigraphReader(DigraphReader& other) |
|
362 : _is(other._is), local_is(other.local_is), _digraph(other._digraph), |
|
363 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) { |
|
364 |
|
365 other.is = 0; |
|
366 other.local_is = false; |
|
367 |
|
368 _node_index.swap(other._node_index); |
|
369 _arc_index.swap(other._arc_index); |
|
370 |
|
371 _node_maps.swap(other._node_maps); |
|
372 _arc_maps.swap(other._arc_maps); |
|
373 _attributes.swap(other._attributes); |
|
374 |
|
375 _nodes_caption = other._nodes_caption; |
|
376 _arcs_caption = other._arcs_caption; |
|
377 _attributes_caption = other._attributes_caption; |
|
378 } |
|
379 |
|
380 /// \e |
|
381 ~DigraphReader() { |
|
382 for (typename NodeMaps::iterator it = _node_maps.begin(); |
|
383 it != _node_maps.end(); ++it) { |
|
384 delete it->second; |
|
385 } |
|
386 |
|
387 for (typename ArcMaps::iterator it = _arc_maps.begin(); |
|
388 it != _arc_maps.end(); ++it) { |
|
389 delete it->second; |
|
390 } |
|
391 |
|
392 for (typename Attributes::iterator it = _attributes.begin(); |
|
393 it != _attributes.end(); ++it) { |
|
394 delete it->second; |
|
395 } |
|
396 |
|
397 if (local_is) { |
|
398 delete _is; |
|
399 } |
|
400 |
|
401 } |
|
402 |
|
403 private: |
|
404 |
|
405 DigraphReader& operator=(const DigraphReader&); |
|
406 |
|
407 public: |
|
408 |
|
409 /// \e |
|
410 template <typename Map> |
|
411 DigraphReader& nodeMap(const std::string& caption, Map& map) { |
|
412 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
413 _reader_bits::MapStorageBase<Node>* storage = |
|
414 new _reader_bits::MapStorage<Node, Map>(map); |
|
415 _node_maps.push_back(std::make_pair(caption, storage)); |
|
416 return *this; |
|
417 } |
|
418 |
|
419 /// \e |
|
420 template <typename Map, typename Converter> |
|
421 DigraphReader& nodeMap(const std::string& caption, Map& map, |
|
422 const Converter& converter = Converter()) { |
|
423 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
424 _reader_bits::MapStorageBase<Node>* storage = |
|
425 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
|
426 _node_maps.push_back(std::make_pair(caption, storage)); |
|
427 return *this; |
|
428 } |
|
429 |
|
430 /// \e |
|
431 template <typename Map> |
|
432 DigraphReader& arcMap(const std::string& caption, Map& map) { |
|
433 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
|
434 _reader_bits::MapStorageBase<Arc>* storage = |
|
435 new _reader_bits::MapStorage<Arc, Map>(map); |
|
436 _arc_maps.push_back(std::make_pair(caption, storage)); |
|
437 return *this; |
|
438 } |
|
439 |
|
440 /// \e |
|
441 template <typename Map, typename Converter> |
|
442 DigraphReader& arcMap(const std::string& caption, Map& map, |
|
443 const Converter& converter = Converter()) { |
|
444 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
|
445 _reader_bits::MapStorageBase<Arc>* storage = |
|
446 new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); |
|
447 _arc_maps.push_back(std::make_pair(caption, storage)); |
|
448 return *this; |
|
449 } |
|
450 |
|
451 /// \e |
|
452 template <typename Value> |
|
453 DigraphReader& attribute(const std::string& caption, Value& value) { |
|
454 _reader_bits::ValueStorageBase* storage = |
|
455 new _reader_bits::ValueStorage<Value>(value); |
|
456 _attributes.insert(std::make_pair(caption, storage)); |
|
457 return *this; |
|
458 } |
|
459 |
|
460 /// \e |
|
461 template <typename Value, typename Converter> |
|
462 DigraphReader& attribute(const std::string& caption, Value& value, |
|
463 const Converter& converter = Converter()) { |
|
464 _reader_bits::ValueStorageBase* storage = |
|
465 new _reader_bits::ValueStorage<Value, Converter>(value, converter); |
|
466 _attributes.insert(std::make_pair(caption, storage)); |
|
467 return *this; |
|
468 } |
|
469 |
|
470 /// \e |
|
471 DigraphReader& node(const std::string& caption, Node& node) { |
|
472 typedef _reader_bits::MapLookUpConverter<Node> Converter; |
|
473 Converter converter(_node_index); |
|
474 _reader_bits::ValueStorageBase* storage = |
|
475 new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
|
476 _attributes.insert(std::make_pair(caption, storage)); |
|
477 return *this; |
|
478 } |
|
479 |
|
480 /// \e |
|
481 DigraphReader& arc(const std::string& caption, Arc& arc) { |
|
482 typedef _reader_bits::MapLookUpConverter<Arc> Converter; |
|
483 Converter converter(_arc_index); |
|
484 _reader_bits::ValueStorageBase* storage = |
|
485 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); |
|
486 _attributes.insert(std::make_pair(caption, storage)); |
|
487 return *this; |
|
488 } |
|
489 |
|
490 /// \e |
|
491 DigraphReader& nodes(const std::string& caption) { |
|
492 _nodes_caption = caption; |
|
493 return *this; |
|
494 } |
|
495 |
|
496 /// \e |
|
497 DigraphReader& arcs(const std::string& caption) { |
|
498 _arcs_caption = caption; |
|
499 return *this; |
|
500 } |
|
501 |
|
502 /// \e |
|
503 DigraphReader& attributes(const std::string& caption) { |
|
504 _attributes_caption = caption; |
|
505 return *this; |
|
506 } |
|
507 |
|
508 /// \e |
|
509 template <typename Map> |
|
510 DigraphReader& useNodes(const Map& map) { |
|
511 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
|
512 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
|
513 _use_nodes = true; |
|
514 _writer_bits::DefaultConverter<typename Map::Value> converter; |
|
515 for (NodeIt n(_digraph); n != INVALID; ++n) { |
|
516 _node_index.insert(std::make_pair(converter(map[n]), n)); |
|
517 } |
|
518 return *this; |
|
519 } |
|
520 |
|
521 /// \e |
|
522 template <typename Map, typename Converter> |
|
523 DigraphReader& useNodes(const Map& map, |
|
524 const Converter& converter = Converter()) { |
|
525 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
|
526 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
|
527 _use_nodes = true; |
|
528 for (NodeIt n(_digraph); n != INVALID; ++n) { |
|
529 _node_index.insert(std::make_pair(converter(map[n]), n)); |
|
530 } |
|
531 return *this; |
|
532 } |
|
533 |
|
534 /// \e |
|
535 template <typename Map> |
|
536 DigraphReader& useArcs(const Map& map) { |
|
537 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
|
538 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); |
|
539 _use_arcs = true; |
|
540 _writer_bits::DefaultConverter<typename Map::Value> converter; |
|
541 for (ArcIt a(_digraph); a != INVALID; ++a) { |
|
542 _arc_index.insert(std::make_pair(converter(map[a]), a)); |
|
543 } |
|
544 return *this; |
|
545 } |
|
546 |
|
547 /// \e |
|
548 template <typename Map, typename Converter> |
|
549 DigraphReader& useArcs(const Map& map, |
|
550 const Converter& converter = Converter()) { |
|
551 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); |
|
552 LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); |
|
553 _use_arcs = true; |
|
554 for (ArcIt a(_digraph); a != INVALID; ++a) { |
|
555 _arc_index.insert(std::make_pair(converter(map[a]), a)); |
|
556 } |
|
557 return *this; |
|
558 } |
|
559 |
|
560 private: |
|
561 |
|
562 bool readLine() { |
|
563 std::string str; |
|
564 while(++line_num, std::getline(*_is, str)) { |
|
565 line.clear(); line.str(str); |
|
566 char c; |
|
567 if (line >> std::ws >> c && c != '#') { |
|
568 line.putback(c); |
|
569 return true; |
|
570 } |
|
571 } |
|
572 return false; |
|
573 } |
|
574 |
|
575 bool readSuccess() { |
|
576 return static_cast<bool>(*_is); |
|
577 } |
|
578 |
|
579 void skipSection() { |
|
580 char c; |
|
581 while (readSuccess() && line >> c && c != '@') { |
|
582 readLine(); |
|
583 } |
|
584 line.putback(c); |
|
585 } |
|
586 |
|
587 void readNodes() { |
|
588 |
|
589 std::vector<int> map_index(_node_maps.size()); |
|
590 int map_num, label_index; |
|
591 |
|
592 if (!readLine()) |
|
593 throw DataFormatError("Cannot find map captions"); |
|
594 |
|
595 { |
|
596 std::map<std::string, int> maps; |
|
597 |
|
598 std::string map; |
|
599 int index = 0; |
|
600 while (_reader_bits::readIdentifier(line, map)) { |
|
601 if (maps.find(map) != maps.end()) { |
|
602 std::ostringstream msg; |
|
603 msg << "Multiple occurence of node map: " << map; |
|
604 throw DataFormatError(msg.str().c_str()); |
|
605 } |
|
606 maps.insert(std::make_pair(map, index)); |
|
607 ++index; |
|
608 } |
|
609 |
|
610 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { |
|
611 std::map<std::string, int>::iterator jt = |
|
612 maps.find(_node_maps[i].first); |
|
613 if (jt == maps.end()) { |
|
614 std::ostringstream msg; |
|
615 msg << "Map not found in file: " << _node_maps[i].first; |
|
616 throw DataFormatError(msg.str().c_str()); |
|
617 } |
|
618 map_index[i] = jt->second; |
|
619 } |
|
620 |
|
621 { |
|
622 std::map<std::string, int>::iterator jt = maps.find("label"); |
|
623 if (jt == maps.end()) |
|
624 throw DataFormatError("Label map not found in file"); |
|
625 label_index = jt->second; |
|
626 } |
|
627 map_num = maps.size(); |
|
628 } |
|
629 |
|
630 char c; |
|
631 while (readLine() && line >> c && c != '@') { |
|
632 line.putback(c); |
|
633 |
|
634 std::vector<std::string> tokens(map_num); |
|
635 for (int i = 0; i < map_num; ++i) { |
|
636 if (!_reader_bits::readToken(line, tokens[i])) { |
|
637 std::ostringstream msg; |
|
638 msg << "Column not found (" << i + 1 << ")"; |
|
639 throw DataFormatError(msg.str().c_str()); |
|
640 } |
|
641 } |
|
642 if (line >> std::ws >> c) |
|
643 throw DataFormatError("Extra character on the end of line"); |
|
644 |
|
645 Node n; |
|
646 if (!_use_nodes) { |
|
647 n = _digraph.addNode(); |
|
648 _node_index.insert(std::make_pair(tokens[label_index], n)); |
|
649 } else { |
|
650 typename std::map<std::string, Node>::iterator it = |
|
651 _node_index.find(tokens[label_index]); |
|
652 if (it == _node_index.end()) { |
|
653 std::ostringstream msg; |
|
654 msg << "Node with label not found: " << tokens[label_index]; |
|
655 throw DataFormatError(msg.str().c_str()); |
|
656 } |
|
657 n = it->second; |
|
658 } |
|
659 |
|
660 for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) { |
|
661 _node_maps[i].second->set(n, tokens[map_index[i]]); |
|
662 } |
|
663 |
|
664 } |
|
665 if (readSuccess()) { |
|
666 line.putback(c); |
|
667 } |
|
668 } |
|
669 |
|
670 void readArcs() { |
|
671 |
|
672 std::vector<int> map_index(_arc_maps.size()); |
|
673 int map_num, label_index; |
|
674 |
|
675 if (!readLine()) |
|
676 throw DataFormatError("Cannot find map captions"); |
|
677 |
|
678 { |
|
679 std::map<std::string, int> maps; |
|
680 |
|
681 std::string map; |
|
682 int index = 0; |
|
683 while (_reader_bits::readIdentifier(line, map)) { |
|
684 if (maps.find(map) != maps.end()) { |
|
685 std::ostringstream msg; |
|
686 msg << "Multiple occurence of arc map: " << map; |
|
687 throw DataFormatError(msg.str().c_str()); |
|
688 } |
|
689 maps.insert(std::make_pair(map, index)); |
|
690 ++index; |
|
691 } |
|
692 |
|
693 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) { |
|
694 std::map<std::string, int>::iterator jt = |
|
695 maps.find(_arc_maps[i].first); |
|
696 if (jt == maps.end()) { |
|
697 std::ostringstream msg; |
|
698 msg << "Map not found in file: " << _arc_maps[i].first; |
|
699 throw DataFormatError(msg.str().c_str()); |
|
700 } |
|
701 map_index[i] = jt->second; |
|
702 } |
|
703 |
|
704 { |
|
705 std::map<std::string, int>::iterator jt = maps.find("label"); |
|
706 if (jt == maps.end()) |
|
707 throw DataFormatError("Label map not found in file"); |
|
708 label_index = jt->second; |
|
709 } |
|
710 map_num = maps.size(); |
|
711 } |
|
712 |
|
713 char c; |
|
714 while (readLine() && line >> c && c != '@') { |
|
715 line.putback(c); |
|
716 |
|
717 std::string source_token; |
|
718 std::string target_token; |
|
719 |
|
720 if (!_reader_bits::readToken(line, source_token)) |
|
721 throw DataFormatError("Source not found"); |
|
722 |
|
723 if (!_reader_bits::readToken(line, target_token)) |
|
724 throw DataFormatError("Source not found"); |
|
725 |
|
726 std::vector<std::string> tokens(map_num); |
|
727 for (int i = 0; i < map_num; ++i) { |
|
728 if (!_reader_bits::readToken(line, tokens[i])) { |
|
729 std::ostringstream msg; |
|
730 msg << "Column not found (" << i + 1 << ")"; |
|
731 throw DataFormatError(msg.str().c_str()); |
|
732 } |
|
733 } |
|
734 if (line >> std::ws >> c) |
|
735 throw DataFormatError("Extra character on the end of line"); |
|
736 |
|
737 Arc a; |
|
738 if (!_use_arcs) { |
|
739 |
|
740 typename NodeIndex::iterator it; |
|
741 |
|
742 it = _node_index.find(source_token); |
|
743 if (it == _node_index.end()) { |
|
744 std::ostringstream msg; |
|
745 msg << "Item not found: " << source_token; |
|
746 throw DataFormatError(msg.str().c_str()); |
|
747 } |
|
748 Node source = it->second; |
|
749 |
|
750 it = _node_index.find(target_token); |
|
751 if (it == _node_index.end()) { |
|
752 std::ostringstream msg; |
|
753 msg << "Item not found: " << target_token; |
|
754 throw DataFormatError(msg.str().c_str()); |
|
755 } |
|
756 Node target = it->second; |
|
757 |
|
758 a = _digraph.addArc(source, target); |
|
759 _arc_index.insert(std::make_pair(tokens[label_index], a)); |
|
760 } else { |
|
761 typename std::map<std::string, Arc>::iterator it = |
|
762 _arc_index.find(tokens[label_index]); |
|
763 if (it == _arc_index.end()) { |
|
764 std::ostringstream msg; |
|
765 msg << "Arc with label not found: " << tokens[label_index]; |
|
766 throw DataFormatError(msg.str().c_str()); |
|
767 } |
|
768 a = it->second; |
|
769 } |
|
770 |
|
771 for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) { |
|
772 _arc_maps[i].second->set(a, tokens[map_index[i]]); |
|
773 } |
|
774 |
|
775 } |
|
776 if (readSuccess()) { |
|
777 line.putback(c); |
|
778 } |
|
779 } |
|
780 |
|
781 void readAttributes() { |
|
782 |
|
783 std::set<std::string> read_attr; |
|
784 |
|
785 char c; |
|
786 while (readLine() && line >> c && c != '@') { |
|
787 line.putback(c); |
|
788 |
|
789 std::string attr, token; |
|
790 if (!_reader_bits::readIdentifier(line, attr)) |
|
791 throw DataFormatError("Attribute name not found"); |
|
792 if (!_reader_bits::readToken(line, token)) |
|
793 throw DataFormatError("Attribute value not found"); |
|
794 if (line >> c) |
|
795 throw DataFormatError("Extra character on the end of line"); |
|
796 |
|
797 { |
|
798 std::set<std::string>::iterator it = read_attr.find(attr); |
|
799 if (it != read_attr.end()) { |
|
800 std::ostringstream msg; |
|
801 msg << "Multiple occurence of attribute " << attr; |
|
802 throw DataFormatError(msg.str().c_str()); |
|
803 } |
|
804 read_attr.insert(attr); |
|
805 } |
|
806 |
|
807 { |
|
808 typename Attributes::iterator it = _attributes.lower_bound(attr); |
|
809 while (it != _attributes.end() && it->first == attr) { |
|
810 it->second->set(token); |
|
811 ++it; |
|
812 } |
|
813 } |
|
814 |
|
815 } |
|
816 if (readSuccess()) { |
|
817 line.putback(c); |
|
818 } |
|
819 for (typename Attributes::iterator it = _attributes.begin(); |
|
820 it != _attributes.end(); ++it) { |
|
821 if (read_attr.find(it->first) == read_attr.end()) { |
|
822 std::ostringstream msg; |
|
823 msg << "Attribute not found in file: " << it->first; |
|
824 throw DataFormatError(msg.str().c_str()); |
|
825 } |
|
826 } |
|
827 } |
|
828 |
|
829 public: |
|
830 |
|
831 /// \e |
|
832 void run() { |
|
833 |
|
834 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); |
|
835 |
|
836 bool nodes_done = false; |
|
837 bool arcs_done = false; |
|
838 bool attributes_done = false; |
|
839 |
|
840 line_num = 0; |
|
841 readLine(); |
|
842 |
|
843 while (readSuccess()) { |
|
844 skipSection(); |
|
845 try { |
|
846 char c; |
|
847 std::string section, caption; |
|
848 line >> c; |
|
849 _reader_bits::readIdentifier(line, section); |
|
850 _reader_bits::readIdentifier(line, caption); |
|
851 |
|
852 if (line >> c) |
|
853 throw DataFormatError("Extra character on the end of line"); |
|
854 |
|
855 if (section == "nodes" && !nodes_done) { |
|
856 if (_nodes_caption.empty() || _nodes_caption == caption) { |
|
857 readNodes(); |
|
858 nodes_done = true; |
|
859 } |
|
860 } else if ((section == "arcs" || section == "edges") && |
|
861 !arcs_done) { |
|
862 if (_arcs_caption.empty() || _arcs_caption == caption) { |
|
863 readArcs(); |
|
864 arcs_done = true; |
|
865 } |
|
866 } else if (section == "attributes" && !attributes_done) { |
|
867 if (_attributes_caption.empty() || _attributes_caption == caption) { |
|
868 readAttributes(); |
|
869 attributes_done = true; |
|
870 } |
|
871 } else { |
|
872 readLine(); |
|
873 skipSection(); |
|
874 } |
|
875 } catch (DataFormatError& error) { |
|
876 error.line(line_num); |
|
877 throw; |
|
878 } |
|
879 } |
|
880 |
|
881 if (!nodes_done) { |
|
882 throw DataFormatError("Section @nodes not found"); |
|
883 } |
|
884 |
|
885 if (!arcs_done) { |
|
886 throw DataFormatError("Section @arcs not found"); |
|
887 } |
|
888 |
|
889 if (!attributes_done && !_attributes.empty()) { |
|
890 throw DataFormatError("Section @attributes not found"); |
|
891 } |
|
892 |
|
893 } |
|
894 |
|
895 }; |
|
896 |
|
897 template <typename Digraph> |
|
898 DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) { |
|
899 return DigraphReader<Digraph>(is, digraph); |
|
900 } |
|
901 |
|
902 template <typename Digraph> |
|
903 DigraphReader<Digraph> digraphReader(const std::string& fn, |
|
904 Digraph& digraph) { |
|
905 return DigraphReader<Digraph>(fn, digraph); |
|
906 } |
|
907 |
|
908 template <typename Digraph> |
|
909 DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) { |
|
910 return DigraphReader<Digraph>(fn, digraph); |
|
911 } |
|
912 } |
|
913 |
|
914 #endif |