changeset 1845 | f8bbfed86036 |
parent 1746 | 874e4bc21435 |
child 1846 | 6b4e38acef1c |
8:a7e529c07088 | 9:a3b5f521c9f6 |
---|---|
43 |
43 |
44 namespace lemon { |
44 namespace lemon { |
45 |
45 |
46 namespace _reader_bits { |
46 namespace _reader_bits { |
47 |
47 |
48 template <typename T> |
|
49 bool operator<(T, T) { |
|
50 throw DataFormatError("Id is not comparable"); |
|
51 } |
|
52 |
|
53 template <typename T> |
|
54 struct Less { |
|
55 bool operator()(const T& p, const T& q) const { |
|
56 return p < q; |
|
57 } |
|
58 }; |
|
59 |
|
48 template <typename Item> |
60 template <typename Item> |
49 class ItemIdReader { |
61 class ItemIdReader { |
50 public: |
62 public: |
51 |
63 |
52 bool isIdReader() { return true; } |
64 bool isIdReader() { return true; } |
81 _ItemReader& reader; |
93 _ItemReader& reader; |
82 std::istream& is; |
94 std::istream& is; |
83 }; |
95 }; |
84 |
96 |
85 }; |
97 }; |
86 |
|
87 template <typename T> |
|
88 bool operator<(T, T) { |
|
89 throw DataFormatError("Id is not comparable"); |
|
90 } |
|
91 |
|
92 template <typename T> |
|
93 struct Less { |
|
94 bool operator()(const T& p, const T& q) const { |
|
95 return p < q; |
|
96 } |
|
97 }; |
|
98 |
98 |
99 template <typename Map> |
99 template <typename Map> |
100 struct Ref { typedef Map& Type; }; |
100 struct Ref { typedef Map& Type; }; |
101 template <typename Map> |
101 template <typename Map> |
102 struct Arg { typedef Map& Type; }; |
102 struct Arg { typedef Map& Type; }; |
194 typedef YMap<Map> Type; |
194 typedef YMap<Map> Type; |
195 }; |
195 }; |
196 template <typename Map> |
196 template <typename Map> |
197 struct Arg<YMap<Map> > { |
197 struct Arg<YMap<Map> > { |
198 typedef const YMap<Map>& Type; |
198 typedef const YMap<Map>& Type; |
199 }; |
|
200 |
|
201 |
|
202 template <typename _Item> |
|
203 class MapReaderBase; |
|
204 |
|
205 template <typename _Item> |
|
206 class MapInverterBase : public MapReaderBase<_Item> { |
|
207 public: |
|
208 typedef _Item Item; |
|
209 virtual void read(std::istream&, const Item&) = 0; |
|
210 virtual Item read(std::istream&) const = 0; |
|
211 |
|
212 virtual MapInverterBase<_Item>* getInverter() { |
|
213 return this; |
|
214 } |
|
215 }; |
|
216 |
|
217 template <typename _Item, typename _Map, typename _Reader> |
|
218 class MapReaderInverter : public MapInverterBase<_Item> { |
|
219 public: |
|
220 typedef _Item Item; |
|
221 typedef _Reader Reader; |
|
222 typedef typename Reader::Value Value; |
|
223 typedef _Map Map; |
|
224 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse; |
|
225 |
|
226 typename _reader_bits::Ref<Map>::Type map; |
|
227 Reader reader; |
|
228 Inverse inverse; |
|
229 |
|
230 MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map, |
|
231 const Reader& _reader) |
|
232 : map(_map), reader(_reader) {} |
|
233 |
|
234 virtual ~MapReaderInverter() {} |
|
235 |
|
236 virtual void read(std::istream& is, const Item& item) { |
|
237 Value value; |
|
238 reader.read(is, value); |
|
239 map.set(item, value); |
|
240 typename Inverse::iterator it = inverse.find(value); |
|
241 if (it == inverse.end()) { |
|
242 inverse.insert(std::make_pair(value, item)); |
|
243 } else { |
|
244 throw DataFormatError("Multiple ID occurence"); |
|
245 } |
|
246 } |
|
247 |
|
248 virtual Item read(std::istream& is) const { |
|
249 Value value; |
|
250 reader.read(is, value); |
|
251 typename Inverse::const_iterator it = inverse.find(value); |
|
252 if (it != inverse.end()) { |
|
253 return it->second; |
|
254 } else { |
|
255 throw DataFormatError("Invalid ID error"); |
|
256 } |
|
257 } |
|
258 }; |
|
259 |
|
260 template <typename _Item, typename _Reader> |
|
261 class SkipReaderInverter : public MapInverterBase<_Item> { |
|
262 public: |
|
263 typedef _Item Item; |
|
264 typedef _Reader Reader; |
|
265 typedef typename Reader::Value Value; |
|
266 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse; |
|
267 |
|
268 Reader reader; |
|
269 |
|
270 SkipReaderInverter(const Reader& _reader) |
|
271 : reader(_reader) {} |
|
272 |
|
273 virtual ~SkipReaderInverter() {} |
|
274 |
|
275 virtual void read(std::istream& is, const Item& item) { |
|
276 Value value; |
|
277 reader.read(is, value); |
|
278 typename Inverse::iterator it = inverse.find(value); |
|
279 if (it == inverse.end()) { |
|
280 inverse.insert(std::make_pair(value, item)); |
|
281 } else { |
|
282 throw DataFormatError("Multiple ID occurence error"); |
|
283 } |
|
284 } |
|
285 |
|
286 virtual Item read(std::istream& is) const { |
|
287 Value value; |
|
288 reader.read(is, value); |
|
289 typename Inverse::const_iterator it = inverse.find(value); |
|
290 if (it != inverse.end()) { |
|
291 return it->second; |
|
292 } else { |
|
293 throw DataFormatError("Invalid ID error"); |
|
294 } |
|
295 } |
|
296 |
|
297 private: |
|
298 Inverse inverse; |
|
299 }; |
|
300 |
|
301 template <typename _Item> |
|
302 class MapReaderBase { |
|
303 public: |
|
304 typedef _Item Item; |
|
305 |
|
306 MapReaderBase() { _touched = false; } |
|
307 |
|
308 void touch() { _touched = true; } |
|
309 bool touched() const { return _touched; } |
|
310 |
|
311 virtual ~MapReaderBase() {} |
|
312 |
|
313 virtual void read(std::istream& is, const Item& item) = 0; |
|
314 virtual MapInverterBase<_Item>* getInverter() = 0; |
|
315 |
|
316 private: |
|
317 bool _touched; |
|
318 |
|
319 }; |
|
320 |
|
321 template <typename _Item, typename _Map, typename _Reader> |
|
322 class MapReader : public MapReaderBase<_Item> { |
|
323 public: |
|
324 typedef _Map Map; |
|
325 typedef _Reader Reader; |
|
326 typedef typename Reader::Value Value; |
|
327 typedef _Item Item; |
|
328 |
|
329 typename _reader_bits::Ref<Map>::Type map; |
|
330 Reader reader; |
|
331 |
|
332 MapReader(typename _reader_bits::Arg<Map>::Type _map, |
|
333 const Reader& _reader) |
|
334 : map(_map), reader(_reader) {} |
|
335 |
|
336 virtual ~MapReader() {} |
|
337 |
|
338 virtual void read(std::istream& is, const Item& item) { |
|
339 Value value; |
|
340 reader.read(is, value); |
|
341 map.set(item, value); |
|
342 } |
|
343 |
|
344 virtual MapInverterBase<_Item>* getInverter() { |
|
345 return new MapReaderInverter<Item, Map, Reader>(map, reader); |
|
346 } |
|
347 }; |
|
348 |
|
349 |
|
350 template <typename _Item, typename _Reader> |
|
351 class SkipReader : public MapReaderBase<_Item> { |
|
352 public: |
|
353 typedef _Reader Reader; |
|
354 typedef typename Reader::Value Value; |
|
355 typedef _Item Item; |
|
356 |
|
357 Reader reader; |
|
358 SkipReader(const Reader& _reader) : reader(_reader) {} |
|
359 |
|
360 virtual ~SkipReader() {} |
|
361 |
|
362 virtual void read(std::istream& is, const Item&) { |
|
363 Value value; |
|
364 reader.read(is, value); |
|
365 } |
|
366 |
|
367 virtual MapInverterBase<Item>* getInverter() { |
|
368 return new SkipReaderInverter<Item, Reader>(reader); |
|
369 } |
|
370 }; |
|
371 |
|
372 template <typename _Item> |
|
373 class IdReaderBase { |
|
374 public: |
|
375 typedef _Item Item; |
|
376 virtual ~IdReaderBase() {} |
|
377 virtual Item read(std::istream& is) const = 0; |
|
378 virtual bool isIdReader() const = 0; |
|
379 }; |
|
380 |
|
381 template <typename _Item, typename _BoxedIdReader> |
|
382 class IdReader : public IdReaderBase<_Item> { |
|
383 public: |
|
384 typedef _Item Item; |
|
385 typedef _BoxedIdReader BoxedIdReader; |
|
386 |
|
387 const BoxedIdReader& boxedIdReader; |
|
388 |
|
389 IdReader(const BoxedIdReader& _boxedIdReader) |
|
390 : boxedIdReader(_boxedIdReader) {} |
|
391 |
|
392 virtual Item read(std::istream& is) const { |
|
393 Item item; |
|
394 boxedIdReader.readId(is, item); |
|
395 return item; |
|
396 } |
|
397 |
|
398 virtual bool isIdReader() const { |
|
399 return boxedIdReader.isIdReader(); |
|
400 } |
|
401 }; |
|
402 |
|
403 template <typename _Item> |
|
404 class ItemStore { |
|
405 public: |
|
406 |
|
407 typedef _Item Item; |
|
408 |
|
409 ItemStore(Item& _item) : item(&_item) { |
|
410 _touched = false; |
|
411 } |
|
412 |
|
413 void touch() { _touched = true; } |
|
414 bool touched() const { return _touched; } |
|
415 |
|
416 void read(const Item& _item) { |
|
417 *item = _item; |
|
418 } |
|
419 |
|
420 private: |
|
421 Item* item; |
|
422 bool _touched; |
|
423 }; |
|
424 |
|
425 class ValueReaderBase { |
|
426 public: |
|
427 virtual void read(std::istream&) {}; |
|
428 virtual ~ValueReaderBase() {} |
|
429 }; |
|
430 |
|
431 template <typename _Value, typename _Reader> |
|
432 class ValueReader : public ValueReaderBase { |
|
433 public: |
|
434 typedef _Value Value; |
|
435 typedef _Reader Reader; |
|
436 |
|
437 ValueReader(Value& _value, const Reader& _reader) |
|
438 : value(_value), reader(_reader) {} |
|
439 |
|
440 virtual void read(std::istream& is) { |
|
441 reader.read(is, value); |
|
442 } |
|
443 private: |
|
444 Value& value; |
|
445 Reader reader; |
|
199 }; |
446 }; |
200 |
447 |
201 } |
448 } |
202 |
449 |
203 /// \ingroup io_group |
450 /// \ingroup io_group |
467 typedef std::vector<SectionReader*> SectionReaders; |
714 typedef std::vector<SectionReader*> SectionReaders; |
468 SectionReaders readers; |
715 SectionReaders readers; |
469 |
716 |
470 }; |
717 }; |
471 |
718 |
472 /// \brief Helper class for implementing the common SectionReaders. |
|
473 /// |
|
474 /// Helper class for implementing the common SectionReaders. |
|
475 class CommonSectionReaderBase : public LemonReader::SectionReader { |
|
476 typedef LemonReader::SectionReader Parent; |
|
477 protected: |
|
478 |
|
479 /// \brief Constructor for CommonSectionReaderBase. |
|
480 /// |
|
481 /// Constructor for CommonSectionReaderBase. It attach this reader to |
|
482 /// the given LemonReader. |
|
483 CommonSectionReaderBase(LemonReader& _reader) |
|
484 : Parent(_reader) {} |
|
485 |
|
486 template <typename _Item> |
|
487 class ReaderBase; |
|
488 |
|
489 template <typename _Item> |
|
490 class InverterBase : public ReaderBase<_Item> { |
|
491 public: |
|
492 typedef _Item Item; |
|
493 virtual void read(std::istream&, const Item&) = 0; |
|
494 virtual Item read(std::istream&) const = 0; |
|
495 |
|
496 virtual InverterBase<_Item>* getInverter() { |
|
497 return this; |
|
498 } |
|
499 }; |
|
500 |
|
501 template <typename _Item, typename _Map, typename _Reader> |
|
502 class MapReaderInverter : public InverterBase<_Item> { |
|
503 public: |
|
504 typedef _Item Item; |
|
505 typedef _Reader Reader; |
|
506 typedef typename Reader::Value Value; |
|
507 typedef _Map Map; |
|
508 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse; |
|
509 |
|
510 typename _reader_bits::Ref<Map>::Type map; |
|
511 Reader reader; |
|
512 Inverse inverse; |
|
513 |
|
514 MapReaderInverter(typename _reader_bits::Arg<Map>::Type _map, |
|
515 const Reader& _reader) |
|
516 : map(_map), reader(_reader) {} |
|
517 |
|
518 virtual ~MapReaderInverter() {} |
|
519 |
|
520 virtual void read(std::istream& is, const Item& item) { |
|
521 Value value; |
|
522 reader.read(is, value); |
|
523 map.set(item, value); |
|
524 typename Inverse::iterator it = inverse.find(value); |
|
525 if (it == inverse.end()) { |
|
526 inverse.insert(std::make_pair(value, item)); |
|
527 } else { |
|
528 throw DataFormatError("Multiple ID occurence"); |
|
529 } |
|
530 } |
|
531 |
|
532 virtual Item read(std::istream& is) const { |
|
533 Value value; |
|
534 reader.read(is, value); |
|
535 typename Inverse::const_iterator it = inverse.find(value); |
|
536 if (it != inverse.end()) { |
|
537 return it->second; |
|
538 } else { |
|
539 throw DataFormatError("Invalid ID error"); |
|
540 } |
|
541 } |
|
542 }; |
|
543 |
|
544 template <typename _Item, typename _Reader> |
|
545 class SkipReaderInverter : public InverterBase<_Item> { |
|
546 public: |
|
547 typedef _Item Item; |
|
548 typedef _Reader Reader; |
|
549 typedef typename Reader::Value Value; |
|
550 typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse; |
|
551 |
|
552 Reader reader; |
|
553 |
|
554 SkipReaderInverter(const Reader& _reader) |
|
555 : reader(_reader) {} |
|
556 |
|
557 virtual ~SkipReaderInverter() {} |
|
558 |
|
559 virtual void read(std::istream& is, const Item& item) { |
|
560 Value value; |
|
561 reader.read(is, value); |
|
562 typename Inverse::iterator it = inverse.find(value); |
|
563 if (it == inverse.end()) { |
|
564 inverse.insert(std::make_pair(value, item)); |
|
565 } else { |
|
566 throw DataFormatError("Multiple ID occurence error"); |
|
567 } |
|
568 } |
|
569 |
|
570 virtual Item read(std::istream& is) const { |
|
571 Value value; |
|
572 reader.read(is, value); |
|
573 typename Inverse::const_iterator it = inverse.find(value); |
|
574 if (it != inverse.end()) { |
|
575 return it->second; |
|
576 } else { |
|
577 throw DataFormatError("Invalid ID error"); |
|
578 } |
|
579 } |
|
580 |
|
581 private: |
|
582 Inverse inverse; |
|
583 }; |
|
584 |
|
585 template <typename _Item> |
|
586 class ReaderBase { |
|
587 public: |
|
588 typedef _Item Item; |
|
589 |
|
590 virtual ~ReaderBase() {} |
|
591 |
|
592 virtual void read(std::istream& is, const Item& item) = 0; |
|
593 virtual InverterBase<_Item>* getInverter() = 0; |
|
594 }; |
|
595 |
|
596 template <typename _Item, typename _Map, typename _Reader> |
|
597 class MapReader : public ReaderBase<_Item> { |
|
598 public: |
|
599 typedef _Map Map; |
|
600 typedef _Reader Reader; |
|
601 typedef typename Reader::Value Value; |
|
602 typedef _Item Item; |
|
603 |
|
604 typename _reader_bits::Ref<Map>::Type map; |
|
605 Reader reader; |
|
606 |
|
607 MapReader(typename _reader_bits::Arg<Map>::Type _map, |
|
608 const Reader& _reader) |
|
609 : map(_map), reader(_reader) {} |
|
610 |
|
611 virtual ~MapReader() {} |
|
612 |
|
613 virtual void read(std::istream& is, const Item& item) { |
|
614 Value value; |
|
615 reader.read(is, value); |
|
616 map.set(item, value); |
|
617 } |
|
618 |
|
619 virtual InverterBase<_Item>* getInverter() { |
|
620 return new MapReaderInverter<Item, Map, Reader>(map, reader); |
|
621 } |
|
622 }; |
|
623 |
|
624 |
|
625 template <typename _Item, typename _Reader> |
|
626 class SkipReader : public ReaderBase<_Item> { |
|
627 public: |
|
628 typedef _Reader Reader; |
|
629 typedef typename Reader::Value Value; |
|
630 typedef _Item Item; |
|
631 |
|
632 Reader reader; |
|
633 SkipReader(const Reader& _reader) : reader(_reader) {} |
|
634 |
|
635 virtual ~SkipReader() {} |
|
636 |
|
637 virtual void read(std::istream& is, const Item&) { |
|
638 Value value; |
|
639 reader.read(is, value); |
|
640 } |
|
641 |
|
642 virtual InverterBase<Item>* getInverter() { |
|
643 return new SkipReaderInverter<Item, Reader>(reader); |
|
644 } |
|
645 }; |
|
646 |
|
647 template <typename _Item> |
|
648 class IdReaderBase { |
|
649 public: |
|
650 typedef _Item Item; |
|
651 virtual ~IdReaderBase() {} |
|
652 virtual Item read(std::istream& is) const = 0; |
|
653 virtual bool isIdReader() const = 0; |
|
654 }; |
|
655 |
|
656 template <typename _Item, typename _BoxedIdReader> |
|
657 class IdReader : public IdReaderBase<_Item> { |
|
658 public: |
|
659 typedef _Item Item; |
|
660 typedef _BoxedIdReader BoxedIdReader; |
|
661 |
|
662 const BoxedIdReader& boxedIdReader; |
|
663 |
|
664 IdReader(const BoxedIdReader& _boxedIdReader) |
|
665 : boxedIdReader(_boxedIdReader) {} |
|
666 |
|
667 virtual Item read(std::istream& is) const { |
|
668 Item item; |
|
669 boxedIdReader.readId(is, item); |
|
670 return item; |
|
671 } |
|
672 |
|
673 virtual bool isIdReader() const { |
|
674 return boxedIdReader.isIdReader(); |
|
675 } |
|
676 }; |
|
677 |
|
678 class ValueReaderBase { |
|
679 public: |
|
680 virtual void read(std::istream&) {}; |
|
681 virtual ~ValueReaderBase() {} |
|
682 }; |
|
683 |
|
684 template <typename _Value, typename _Reader> |
|
685 class ValueReader : public ValueReaderBase { |
|
686 public: |
|
687 typedef _Value Value; |
|
688 typedef _Reader Reader; |
|
689 |
|
690 ValueReader(Value& _value, const Reader& _reader) |
|
691 : value(_value), reader(_reader) {} |
|
692 |
|
693 virtual void read(std::istream& is) { |
|
694 reader.read(is, value); |
|
695 } |
|
696 private: |
|
697 Value& value; |
|
698 Reader reader; |
|
699 }; |
|
700 |
|
701 }; |
|
702 |
|
703 /// \ingroup io_group |
719 /// \ingroup io_group |
704 /// \brief SectionReader for reading a graph's nodeset. |
720 /// \brief SectionReader for reading a graph's nodeset. |
705 /// |
721 /// |
706 /// The lemon format can store multiple graph nodesets with several maps. |
722 /// The lemon format can store multiple graph nodesets with several maps. |
707 /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the |
723 /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the |
716 /// \c readId() member will read a value from the given stream it will |
732 /// \c readId() member will read a value from the given stream it will |
717 /// give back that node which is mapped to this value. |
733 /// give back that node which is mapped to this value. |
718 /// |
734 /// |
719 /// \relates LemonReader |
735 /// \relates LemonReader |
720 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
736 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
721 class NodeSetReader : public CommonSectionReaderBase { |
737 class NodeSetReader : public LemonReader::SectionReader { |
722 typedef CommonSectionReaderBase Parent; |
738 typedef LemonReader::SectionReader Parent; |
723 public: |
739 public: |
724 |
740 |
725 typedef _Graph Graph; |
741 typedef _Graph Graph; |
726 typedef _Traits Traits; |
742 typedef _Traits Traits; |
727 typedef typename Graph::Node Node; |
743 typedef typename Graph::Node Node; |
799 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
815 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
800 if (readers.find(name) != readers.end()) { |
816 if (readers.find(name) != readers.end()) { |
801 ErrorMessage msg; |
817 ErrorMessage msg; |
802 msg << "Multiple read rule for node map: " << name; |
818 msg << "Multiple read rule for node map: " << name; |
803 throw IOParameterError(msg.message()); |
819 throw IOParameterError(msg.message()); |
804 } |
820 } |
805 readers.insert( |
821 readers.insert( |
806 make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
822 make_pair(name, new _reader_bits:: |
823 MapReader<Node, Map, Reader>(map, reader))); |
|
807 return *this; |
824 return *this; |
808 } |
825 } |
809 |
826 |
810 public: |
827 public: |
811 |
828 |
818 if (readers.find(name) != readers.end()) { |
835 if (readers.find(name) != readers.end()) { |
819 ErrorMessage msg; |
836 ErrorMessage msg; |
820 msg << "Multiple read rule for node map: " << name; |
837 msg << "Multiple read rule for node map: " << name; |
821 throw IOParameterError(msg.message()); |
838 throw IOParameterError(msg.message()); |
822 } |
839 } |
823 readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |
840 readers.insert(make_pair(name, new _reader_bits:: |
841 SkipReader<Node, Reader>(reader))); |
|
824 return *this; |
842 return *this; |
825 } |
843 } |
826 |
844 |
827 protected: |
845 protected: |
828 |
846 |
841 |
859 |
842 /// \brief Reader function of the section. |
860 /// \brief Reader function of the section. |
843 /// |
861 /// |
844 /// It reads the content of the section. |
862 /// It reads the content of the section. |
845 virtual void read(std::istream& is) { |
863 virtual void read(std::istream& is) { |
846 std::vector<ReaderBase<Node>* > index; |
864 std::vector<_reader_bits::MapReaderBase<Node>* > index; |
847 std::string line; |
865 std::string line; |
848 |
866 |
849 getline(is, line); |
867 getline(is, line); |
850 std::istringstream ls(line); |
868 std::istringstream ls(line); |
851 while (ls >> id) { |
869 while (ls >> id) { |
852 typename MapReaders::iterator it = readers.find(id); |
870 typename MapReaders::iterator it = readers.find(id); |
853 if (it != readers.end()) { |
871 if (it != readers.end()) { |
872 it->second->touch(); |
|
854 index.push_back(it->second); |
873 index.push_back(it->second); |
855 } else { |
874 } else { |
856 index.push_back(&skipper); |
875 index.push_back(&skipper); |
857 } |
876 } |
858 if (id == "id" && inverter.get() == 0) { |
877 if (id == "id" && inverter.get() == 0) { |
859 inverter.reset(index.back()->getInverter()); |
878 inverter.reset(index.back()->getInverter()); |
860 index.back() = inverter.get(); |
879 index.back() = inverter.get(); |
880 } |
|
881 } |
|
882 for (typename MapReaders::iterator it = readers.begin(); |
|
883 it != readers.end(); ++it) { |
|
884 if (!it->second->touched()) { |
|
885 ErrorMessage msg; |
|
886 msg << "Map not found in file: " << it->first; |
|
887 throw IOParameterError(msg.message()); |
|
861 } |
888 } |
862 } |
889 } |
863 while (getline(is, line)) { |
890 while (getline(is, line)) { |
864 Node node = graph.addNode(); |
891 Node node = graph.addNode(); |
865 std::istringstream ls(line); |
892 std::istringstream ls(line); |
887 node = inverter->read(is); |
914 node = inverter->read(is); |
888 } |
915 } |
889 |
916 |
890 private: |
917 private: |
891 |
918 |
892 typedef std::map<std::string, ReaderBase<Node>*> MapReaders; |
919 typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders; |
893 MapReaders readers; |
920 MapReaders readers; |
894 |
921 |
895 Graph& graph; |
922 Graph& graph; |
896 std::string id; |
923 std::string id; |
897 SkipReader<Node, DefaultSkipper> skipper; |
924 _reader_bits::SkipReader<Node, DefaultSkipper> skipper; |
898 |
925 |
899 std::auto_ptr<InverterBase<Node> > inverter; |
926 std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter; |
900 }; |
927 }; |
901 |
928 |
902 /// \ingroup io_group |
929 /// \ingroup io_group |
903 /// \brief SectionReader for reading a graph's edgeset. |
930 /// \brief SectionReader for reading a graph's edgeset. |
904 /// |
931 /// |
920 /// have to be connected. If a NodeSetReader reads an "id" named map, |
947 /// have to be connected. If a NodeSetReader reads an "id" named map, |
921 /// it will be able to resolve the nodes by ids. |
948 /// it will be able to resolve the nodes by ids. |
922 /// |
949 /// |
923 /// \relates LemonReader |
950 /// \relates LemonReader |
924 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
951 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
925 class EdgeSetReader : public CommonSectionReaderBase { |
952 class EdgeSetReader : public LemonReader::SectionReader { |
926 typedef CommonSectionReaderBase Parent; |
953 typedef LemonReader::SectionReader Parent; |
927 public: |
954 public: |
928 |
955 |
929 typedef _Graph Graph; |
956 typedef _Graph Graph; |
930 typedef _Traits Traits; |
957 typedef _Traits Traits; |
931 typedef typename Graph::Node Node; |
958 typedef typename Graph::Node Node; |
946 const NodeIdReader& _nodeIdReader, |
973 const NodeIdReader& _nodeIdReader, |
947 const std::string& _id = std::string(), |
974 const std::string& _id = std::string(), |
948 const DefaultSkipper& _skipper = DefaultSkipper()) |
975 const DefaultSkipper& _skipper = DefaultSkipper()) |
949 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) { |
976 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) { |
950 checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>(); |
977 checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>(); |
951 nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader)); |
978 nodeIdReader.reset(new _reader_bits:: |
979 IdReader<Node, NodeIdReader>(_nodeIdReader)); |
|
952 } |
980 } |
953 /// \brief Destructor. |
981 /// \brief Destructor. |
954 /// |
982 /// |
955 /// Destructor for EdgeSetReader. |
983 /// Destructor for EdgeSetReader. |
956 virtual ~EdgeSetReader() { |
984 virtual ~EdgeSetReader() { |
1011 ErrorMessage msg; |
1039 ErrorMessage msg; |
1012 msg << "Multiple read rule for edge map: " << name; |
1040 msg << "Multiple read rule for edge map: " << name; |
1013 throw IOParameterError(msg.message()); |
1041 throw IOParameterError(msg.message()); |
1014 } |
1042 } |
1015 readers.insert( |
1043 readers.insert( |
1016 make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
1044 make_pair(name, new _reader_bits:: |
1045 MapReader<Edge, Map, Reader>(map, reader))); |
|
1017 return *this; |
1046 return *this; |
1018 } |
1047 } |
1019 |
1048 |
1020 public: |
1049 public: |
1021 |
1050 |
1028 if (readers.find(name) != readers.end()) { |
1057 if (readers.find(name) != readers.end()) { |
1029 ErrorMessage msg; |
1058 ErrorMessage msg; |
1030 msg << "Multiple read rule for edge map: " << name; |
1059 msg << "Multiple read rule for edge map: " << name; |
1031 throw IOParameterError(msg.message()); |
1060 throw IOParameterError(msg.message()); |
1032 } |
1061 } |
1033 readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |
1062 readers.insert(make_pair(name, new _reader_bits:: |
1063 SkipReader<Edge, Reader>(reader))); |
|
1034 return *this; |
1064 return *this; |
1035 } |
1065 } |
1036 |
1066 |
1037 protected: |
1067 protected: |
1038 |
1068 |
1054 /// It reads the content of the section. |
1084 /// It reads the content of the section. |
1055 virtual void read(std::istream& is) { |
1085 virtual void read(std::istream& is) { |
1056 if (!nodeIdReader->isIdReader()) { |
1086 if (!nodeIdReader->isIdReader()) { |
1057 throw DataFormatError("Cannot find nodeset or ID map"); |
1087 throw DataFormatError("Cannot find nodeset or ID map"); |
1058 } |
1088 } |
1059 std::vector<ReaderBase<Edge>* > index; |
1089 std::vector<_reader_bits::MapReaderBase<Edge>* > index; |
1060 std::string line; |
1090 std::string line; |
1061 |
1091 |
1062 getline(is, line); |
1092 getline(is, line); |
1063 std::istringstream ls(line); |
1093 std::istringstream ls(line); |
1064 while (ls >> id) { |
1094 while (ls >> id) { |
1065 typename MapReaders::iterator it = readers.find(id); |
1095 typename MapReaders::iterator it = readers.find(id); |
1066 if (it != readers.end()) { |
1096 if (it != readers.end()) { |
1067 index.push_back(it->second); |
1097 index.push_back(it->second); |
1098 it->second->touch(); |
|
1068 } else { |
1099 } else { |
1069 index.push_back(&skipper); |
1100 index.push_back(&skipper); |
1070 } |
1101 } |
1071 if (id == "id" && inverter.get() == 0) { |
1102 if (id == "id" && inverter.get() == 0) { |
1072 inverter.reset(index.back()->getInverter()); |
1103 inverter.reset(index.back()->getInverter()); |
1073 index.back() = inverter.get(); |
1104 index.back() = inverter.get(); |
1105 } |
|
1106 } |
|
1107 for (typename MapReaders::iterator it = readers.begin(); |
|
1108 it != readers.end(); ++it) { |
|
1109 if (!it->second->touched()) { |
|
1110 ErrorMessage msg; |
|
1111 msg << "Map not found in file: " << it->first; |
|
1112 throw IOParameterError(msg.message()); |
|
1074 } |
1113 } |
1075 } |
1114 } |
1076 while (getline(is, line)) { |
1115 while (getline(is, line)) { |
1077 std::istringstream ls(line); |
1116 std::istringstream ls(line); |
1078 Node from = nodeIdReader->read(ls); |
1117 Node from = nodeIdReader->read(ls); |
1102 edge = inverter->read(is); |
1141 edge = inverter->read(is); |
1103 } |
1142 } |
1104 |
1143 |
1105 private: |
1144 private: |
1106 |
1145 |
1107 typedef std::map<std::string, ReaderBase<Edge>*> MapReaders; |
1146 typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders; |
1108 MapReaders readers; |
1147 MapReaders readers; |
1109 |
1148 |
1110 Graph& graph; |
1149 Graph& graph; |
1111 std::string id; |
1150 std::string id; |
1112 SkipReader<Edge, DefaultSkipper> skipper; |
1151 _reader_bits::SkipReader<Edge, DefaultSkipper> skipper; |
1113 |
1152 |
1114 std::auto_ptr<InverterBase<Edge> > inverter; |
1153 std::auto_ptr<_reader_bits::MapInverterBase<Edge> > inverter; |
1115 std::auto_ptr<IdReaderBase<Node> > nodeIdReader; |
1154 std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader; |
1116 }; |
1155 }; |
1117 |
1156 |
1118 /// \ingroup io_group |
1157 /// \ingroup io_group |
1119 /// \brief SectionReader for reading a undirected graph's edgeset. |
1158 /// \brief SectionReader for reading a undirected graph's edgeset. |
1120 /// |
1159 /// |
1141 /// nodes have to be connected. If a NodeSetReader reads an "id" named map, |
1180 /// nodes have to be connected. If a NodeSetReader reads an "id" named map, |
1142 /// it will be able to resolve the nodes by ids. |
1181 /// it will be able to resolve the nodes by ids. |
1143 /// |
1182 /// |
1144 /// \relates LemonReader |
1183 /// \relates LemonReader |
1145 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
1184 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
1146 class UndirEdgeSetReader : public CommonSectionReaderBase { |
1185 class UndirEdgeSetReader : public LemonReader::SectionReader { |
1147 typedef CommonSectionReaderBase Parent; |
1186 typedef LemonReader::SectionReader Parent; |
1148 public: |
1187 public: |
1149 |
1188 |
1150 typedef _Graph Graph; |
1189 typedef _Graph Graph; |
1151 typedef _Traits Traits; |
1190 typedef _Traits Traits; |
1152 typedef typename Graph::Node Node; |
1191 typedef typename Graph::Node Node; |
1168 const NodeIdReader& _nodeIdReader, |
1207 const NodeIdReader& _nodeIdReader, |
1169 const std::string& _id = std::string(), |
1208 const std::string& _id = std::string(), |
1170 const DefaultSkipper& _skipper = DefaultSkipper()) |
1209 const DefaultSkipper& _skipper = DefaultSkipper()) |
1171 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) { |
1210 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) { |
1172 checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>(); |
1211 checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>(); |
1173 nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader)); |
1212 nodeIdReader.reset(new _reader_bits:: |
1213 IdReader<Node, NodeIdReader>(_nodeIdReader)); |
|
1174 } |
1214 } |
1175 /// \brief Destructor. |
1215 /// \brief Destructor. |
1176 /// |
1216 /// |
1177 /// Destructor for UndirEdgeSetReader. |
1217 /// Destructor for UndirEdgeSetReader. |
1178 virtual ~UndirEdgeSetReader() { |
1218 virtual ~UndirEdgeSetReader() { |
1233 ErrorMessage msg; |
1273 ErrorMessage msg; |
1234 msg << "Multiple read rule for edge map: " << name; |
1274 msg << "Multiple read rule for edge map: " << name; |
1235 throw IOParameterError(msg.message()); |
1275 throw IOParameterError(msg.message()); |
1236 } |
1276 } |
1237 readers.insert( |
1277 readers.insert( |
1238 make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader))); |
1278 make_pair(name, new _reader_bits:: |
1279 MapReader<UndirEdge, Map, Reader>(map, reader))); |
|
1239 return *this; |
1280 return *this; |
1240 } |
1281 } |
1241 |
1282 |
1242 public: |
1283 public: |
1243 |
1284 |
1250 if (readers.find(name) != readers.end()) { |
1291 if (readers.find(name) != readers.end()) { |
1251 ErrorMessage msg; |
1292 ErrorMessage msg; |
1252 msg << "Multiple read rule for node map: " << name; |
1293 msg << "Multiple read rule for node map: " << name; |
1253 throw IOParameterError(msg.message()); |
1294 throw IOParameterError(msg.message()); |
1254 } |
1295 } |
1255 readers.insert(make_pair(name, |
1296 readers.insert(make_pair(name, new _reader_bits:: |
1256 new SkipReader<UndirEdge, Reader>(reader))); |
1297 SkipReader<UndirEdge, Reader>(reader))); |
1257 return *this; |
1298 return *this; |
1258 } |
1299 } |
1259 |
1300 |
1260 /// \brief Add a new directed edge map reader command for the reader. |
1301 /// \brief Add a new directed edge map reader command for the reader. |
1261 /// |
1302 /// |
1338 /// It reads the content of the section. |
1379 /// It reads the content of the section. |
1339 virtual void read(std::istream& is) { |
1380 virtual void read(std::istream& is) { |
1340 if (!nodeIdReader->isIdReader()) { |
1381 if (!nodeIdReader->isIdReader()) { |
1341 throw DataFormatError("Cannot find nodeset or ID map"); |
1382 throw DataFormatError("Cannot find nodeset or ID map"); |
1342 } |
1383 } |
1343 std::vector<ReaderBase<UndirEdge>* > index; |
1384 std::vector<_reader_bits::MapReaderBase<UndirEdge>* > index; |
1344 std::string line; |
1385 std::string line; |
1345 |
1386 |
1346 getline(is, line); |
1387 getline(is, line); |
1347 std::istringstream ls(line); |
1388 std::istringstream ls(line); |
1348 while (ls >> id) { |
1389 while (ls >> id) { |
1349 typename MapReaders::iterator it = readers.find(id); |
1390 typename MapReaders::iterator it = readers.find(id); |
1350 if (it != readers.end()) { |
1391 if (it != readers.end()) { |
1351 index.push_back(it->second); |
1392 index.push_back(it->second); |
1393 it->second->touch(); |
|
1352 } else { |
1394 } else { |
1353 index.push_back(&skipper); |
1395 index.push_back(&skipper); |
1354 } |
1396 } |
1355 if (id == "id" && inverter.get() == 0) { |
1397 if (id == "id" && inverter.get() == 0) { |
1356 inverter.reset(index.back()->getInverter()); |
1398 inverter.reset(index.back()->getInverter()); |
1357 index.back() = inverter.get(); |
1399 index.back() = inverter.get(); |
1400 } |
|
1401 } |
|
1402 for (typename MapReaders::iterator it = readers.begin(); |
|
1403 it != readers.end(); ++it) { |
|
1404 if (!it->second->touched()) { |
|
1405 ErrorMessage msg; |
|
1406 msg << "Map not found in file: " << it->first; |
|
1407 throw IOParameterError(msg.message()); |
|
1358 } |
1408 } |
1359 } |
1409 } |
1360 while (getline(is, line)) { |
1410 while (getline(is, line)) { |
1361 std::istringstream ls(line); |
1411 std::istringstream ls(line); |
1362 Node from = nodeIdReader->read(ls); |
1412 Node from = nodeIdReader->read(ls); |
1406 } |
1456 } |
1407 } |
1457 } |
1408 |
1458 |
1409 private: |
1459 private: |
1410 |
1460 |
1411 typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders; |
1461 typedef std::map<std::string, |
1462 _reader_bits::MapReaderBase<UndirEdge>*> MapReaders; |
|
1412 MapReaders readers; |
1463 MapReaders readers; |
1413 |
1464 |
1414 Graph& graph; |
1465 Graph& graph; |
1415 std::string id; |
1466 std::string id; |
1416 SkipReader<UndirEdge, DefaultSkipper> skipper; |
1467 _reader_bits::SkipReader<UndirEdge, DefaultSkipper> skipper; |
1417 |
1468 |
1418 std::auto_ptr<InverterBase<UndirEdge> > inverter; |
1469 std::auto_ptr<_reader_bits::MapInverterBase<UndirEdge> > inverter; |
1419 std::auto_ptr<IdReaderBase<Node> > nodeIdReader; |
1470 std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader; |
1420 }; |
1471 }; |
1421 |
1472 |
1422 /// \ingroup io_group |
1473 /// \ingroup io_group |
1423 /// \brief SectionReader for reading labeled nodes. |
1474 /// \brief SectionReader for reading labeled nodes. |
1424 /// |
1475 /// |
1428 /// Each line in the section contains the name of the node |
1479 /// Each line in the section contains the name of the node |
1429 /// and then the node id. |
1480 /// and then the node id. |
1430 /// |
1481 /// |
1431 /// \relates LemonReader |
1482 /// \relates LemonReader |
1432 template <typename _Graph> |
1483 template <typename _Graph> |
1433 class NodeReader : public CommonSectionReaderBase { |
1484 class NodeReader : public LemonReader::SectionReader { |
1434 typedef CommonSectionReaderBase Parent; |
1485 typedef LemonReader::SectionReader Parent; |
1435 typedef _Graph Graph; |
1486 typedef _Graph Graph; |
1436 typedef typename Graph::Node Node; |
1487 typedef typename Graph::Node Node; |
1437 public: |
1488 public: |
1438 |
1489 |
1439 /// \brief Constructor. |
1490 /// \brief Constructor. |
1445 template <typename _IdReader> |
1496 template <typename _IdReader> |
1446 NodeReader(LemonReader& _reader, const _IdReader& _idReader, |
1497 NodeReader(LemonReader& _reader, const _IdReader& _idReader, |
1447 const std::string& _id = std::string()) |
1498 const std::string& _id = std::string()) |
1448 : Parent(_reader), id(_id) { |
1499 : Parent(_reader), id(_id) { |
1449 checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>(); |
1500 checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>(); |
1450 nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader)); |
1501 nodeIdReader.reset(new _reader_bits:: |
1502 IdReader<Node, _IdReader>(_idReader)); |
|
1451 } |
1503 } |
1452 |
1504 |
1453 /// \brief Destructor. |
1505 /// \brief Destructor. |
1454 /// |
1506 /// |
1455 /// Destructor for NodeReader. |
1507 /// Destructor for NodeReader. |
1468 if (readers.find(name) != readers.end()) { |
1520 if (readers.find(name) != readers.end()) { |
1469 ErrorMessage msg; |
1521 ErrorMessage msg; |
1470 msg << "Multiple read rule for node: " << name; |
1522 msg << "Multiple read rule for node: " << name; |
1471 throw IOParameterError(msg.message()); |
1523 throw IOParameterError(msg.message()); |
1472 } |
1524 } |
1473 readers.insert(make_pair(name, &item)); |
1525 readers.insert(make_pair(name, _reader_bits::ItemStore<Node>(item))); |
1474 } |
1526 } |
1475 |
1527 |
1476 protected: |
1528 protected: |
1477 |
1529 |
1478 /// \brief Gives back true when the SectionReader can process |
1530 /// \brief Gives back true when the SectionReader can process |
1500 std::istringstream ls(line); |
1552 std::istringstream ls(line); |
1501 std::string id; |
1553 std::string id; |
1502 ls >> id; |
1554 ls >> id; |
1503 typename NodeReaders::iterator it = readers.find(id); |
1555 typename NodeReaders::iterator it = readers.find(id); |
1504 if (it != readers.end()) { |
1556 if (it != readers.end()) { |
1505 *(it->second) = nodeIdReader->read(ls); |
1557 it->second.read(nodeIdReader->read(ls)); |
1558 it->second.touch(); |
|
1506 } |
1559 } |
1560 } |
|
1561 for (typename NodeReaders::iterator it = readers.begin(); |
|
1562 it != readers.end(); ++it) { |
|
1563 if (!it->second.touched()) { |
|
1564 ErrorMessage msg; |
|
1565 msg << "Node not found in file: " << it->first; |
|
1566 throw IOParameterError(msg.message()); |
|
1567 } |
|
1507 } |
1568 } |
1508 } |
1569 } |
1509 |
1570 |
1510 private: |
1571 private: |
1511 |
1572 |
1512 std::string id; |
1573 std::string id; |
1513 |
1574 |
1514 typedef std::map<std::string, Node*> NodeReaders; |
1575 typedef std::map<std::string, _reader_bits::ItemStore<Node> > NodeReaders; |
1515 NodeReaders readers; |
1576 NodeReaders readers; |
1516 std::auto_ptr<IdReaderBase<Node> > nodeIdReader; |
1577 std::auto_ptr<_reader_bits::IdReaderBase<Node> > nodeIdReader; |
1517 }; |
1578 }; |
1518 |
1579 |
1519 /// \ingroup io_group |
1580 /// \ingroup io_group |
1520 /// \brief SectionReader for reading labeled edges. |
1581 /// \brief SectionReader for reading labeled edges. |
1521 /// |
1582 /// |
1525 /// Each line in the section contains the name of the edge |
1586 /// Each line in the section contains the name of the edge |
1526 /// and then the edge id. |
1587 /// and then the edge id. |
1527 /// |
1588 /// |
1528 /// \relates LemonReader |
1589 /// \relates LemonReader |
1529 template <typename _Graph> |
1590 template <typename _Graph> |
1530 class EdgeReader : public CommonSectionReaderBase { |
1591 class EdgeReader : public LemonReader::SectionReader { |
1531 typedef CommonSectionReaderBase Parent; |
1592 typedef LemonReader::SectionReader Parent; |
1532 typedef _Graph Graph; |
1593 typedef _Graph Graph; |
1533 typedef typename Graph::Edge Edge; |
1594 typedef typename Graph::Edge Edge; |
1534 public: |
1595 public: |
1535 |
1596 |
1536 /// \brief Constructor. |
1597 /// \brief Constructor. |
1542 template <typename _IdReader> |
1603 template <typename _IdReader> |
1543 EdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1604 EdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1544 const std::string& _id = std::string()) |
1605 const std::string& _id = std::string()) |
1545 : Parent(_reader), id(_id) { |
1606 : Parent(_reader), id(_id) { |
1546 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1607 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1547 edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader)); |
1608 edgeIdReader.reset(new _reader_bits:: |
1609 IdReader<Edge, _IdReader>(_idReader)); |
|
1548 } |
1610 } |
1549 |
1611 |
1550 /// \brief Destructor. |
1612 /// \brief Destructor. |
1551 /// |
1613 /// |
1552 /// Destructor for EdgeReader. |
1614 /// Destructor for EdgeReader. |
1564 if (readers.find(name) != readers.end()) { |
1626 if (readers.find(name) != readers.end()) { |
1565 ErrorMessage msg; |
1627 ErrorMessage msg; |
1566 msg << "Multiple read rule for edge: " << name; |
1628 msg << "Multiple read rule for edge: " << name; |
1567 throw IOParameterError(msg.message()); |
1629 throw IOParameterError(msg.message()); |
1568 } |
1630 } |
1569 readers.insert(make_pair(name, &item)); |
1631 readers.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item))); |
1570 } |
1632 } |
1571 |
1633 |
1572 protected: |
1634 protected: |
1573 |
1635 |
1574 /// \brief Gives back true when the SectionReader can process |
1636 /// \brief Gives back true when the SectionReader can process |
1596 std::istringstream ls(line); |
1658 std::istringstream ls(line); |
1597 std::string id; |
1659 std::string id; |
1598 ls >> id; |
1660 ls >> id; |
1599 typename EdgeReaders::iterator it = readers.find(id); |
1661 typename EdgeReaders::iterator it = readers.find(id); |
1600 if (it != readers.end()) { |
1662 if (it != readers.end()) { |
1601 *(it->second) = edgeIdReader->read(ls); |
1663 it->second.read(edgeIdReader->read(ls)); |
1664 it->second.touch(); |
|
1602 } |
1665 } |
1666 } |
|
1667 for (typename EdgeReaders::iterator it = readers.begin(); |
|
1668 it != readers.end(); ++it) { |
|
1669 if (!it->second.touched()) { |
|
1670 ErrorMessage msg; |
|
1671 msg << "Edge not found in file: " << it->first; |
|
1672 throw IOParameterError(msg.message()); |
|
1673 } |
|
1603 } |
1674 } |
1604 } |
1675 } |
1605 |
1676 |
1606 private: |
1677 private: |
1607 |
1678 |
1608 std::string id; |
1679 std::string id; |
1609 |
1680 |
1610 typedef std::map<std::string, Edge*> EdgeReaders; |
1681 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders; |
1611 EdgeReaders readers; |
1682 EdgeReaders readers; |
1612 std::auto_ptr<IdReaderBase<Edge> > edgeIdReader; |
1683 std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader; |
1613 }; |
1684 }; |
1614 |
1685 |
1615 /// \ingroup io_group |
1686 /// \ingroup io_group |
1616 /// \brief SectionReader for reading labeled undirected edges. |
1687 /// \brief SectionReader for reading labeled undirected edges. |
1617 /// |
1688 /// |
1621 /// Each line in the section contains the name of the undirected edge |
1692 /// Each line in the section contains the name of the undirected edge |
1622 /// and then the undirected edge id. |
1693 /// and then the undirected edge id. |
1623 /// |
1694 /// |
1624 /// \relates LemonReader |
1695 /// \relates LemonReader |
1625 template <typename _Graph> |
1696 template <typename _Graph> |
1626 class UndirEdgeReader : public CommonSectionReaderBase { |
1697 class UndirEdgeReader : public LemonReader::SectionReader { |
1627 typedef CommonSectionReaderBase Parent; |
1698 typedef LemonReader::SectionReader Parent; |
1628 typedef _Graph Graph; |
1699 typedef _Graph Graph; |
1629 typedef typename Graph::Edge Edge; |
1700 typedef typename Graph::Edge Edge; |
1630 typedef typename Graph::UndirEdge UndirEdge; |
1701 typedef typename Graph::UndirEdge UndirEdge; |
1631 public: |
1702 public: |
1632 |
1703 |
1641 UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1712 UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1642 const std::string& _id = std::string()) |
1713 const std::string& _id = std::string()) |
1643 : Parent(_reader), id(_id) { |
1714 : Parent(_reader), id(_id) { |
1644 checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>(); |
1715 checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>(); |
1645 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1716 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1646 undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader)); |
1717 undirEdgeIdReader.reset(new _reader_bits:: |
1647 edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader)); |
1718 IdReader<UndirEdge, _IdReader>(_idReader)); |
1719 edgeIdReader.reset(new _reader_bits:: |
|
1720 IdReader<Edge, _IdReader>(_idReader)); |
|
1648 } |
1721 } |
1649 |
1722 |
1650 /// \brief Destructor. |
1723 /// \brief Destructor. |
1651 /// |
1724 /// |
1652 /// Destructor for UndirEdgeReader. |
1725 /// Destructor for UndirEdgeReader. |
1664 if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) { |
1737 if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) { |
1665 ErrorMessage msg; |
1738 ErrorMessage msg; |
1666 msg << "Multiple read rule for undirected edge: " << name; |
1739 msg << "Multiple read rule for undirected edge: " << name; |
1667 throw IOParameterError(msg.message()); |
1740 throw IOParameterError(msg.message()); |
1668 } |
1741 } |
1669 undirEdgeReaders.insert(make_pair(name, &item)); |
1742 undirEdgeReaders.insert(make_pair(name, _reader_bits:: |
1743 ItemStore<UndirEdge>(item))); |
|
1670 } |
1744 } |
1671 |
1745 |
1672 /// \brief Add an edge reader command for the UndirEdgeReader. |
1746 /// \brief Add an edge reader command for the UndirEdgeReader. |
1673 /// |
1747 /// |
1674 /// Add an edge reader command for the UndirEdgeReader. |
1748 /// Add an edge reader command for the UndirEdgeReader. |
1676 if (edgeReaders.find(name) != edgeReaders.end()) { |
1750 if (edgeReaders.find(name) != edgeReaders.end()) { |
1677 ErrorMessage msg; |
1751 ErrorMessage msg; |
1678 msg << "Multiple read rule for edge: " << name; |
1752 msg << "Multiple read rule for edge: " << name; |
1679 throw IOParameterError(msg.message()); |
1753 throw IOParameterError(msg.message()); |
1680 } |
1754 } |
1681 edgeReaders.insert(make_pair(name, &item)); |
1755 edgeReaders.insert(make_pair(name, _reader_bits::ItemStore<Edge>(item))); |
1682 } |
1756 } |
1683 |
1757 |
1684 protected: |
1758 protected: |
1685 |
1759 |
1686 /// \brief Gives back true when the SectionReader can process |
1760 /// \brief Gives back true when the SectionReader can process |
1712 std::string id; |
1786 std::string id; |
1713 ls >> id; |
1787 ls >> id; |
1714 { |
1788 { |
1715 typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id); |
1789 typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id); |
1716 if (it != undirEdgeReaders.end()) { |
1790 if (it != undirEdgeReaders.end()) { |
1717 *(it->second) = undirEdgeIdReader->read(ls); |
1791 it->second.read(undirEdgeIdReader->read(ls)); |
1718 break; |
1792 it->second.touch(); |
1793 continue; |
|
1719 } |
1794 } |
1720 } { |
1795 } { |
1721 typename EdgeReaders::iterator it = edgeReaders.find(id); |
1796 typename EdgeReaders::iterator it = edgeReaders.find(id); |
1722 if (it != edgeReaders.end()) { |
1797 if (it != edgeReaders.end()) { |
1723 *(it->second) = edgeIdReader->read(ls); |
1798 it->second.read(edgeIdReader->read(ls)); |
1724 break; |
1799 it->second.touch(); |
1800 continue; |
|
1725 } |
1801 } |
1802 } |
|
1803 } |
|
1804 for (typename EdgeReaders::iterator it = edgeReaders.begin(); |
|
1805 it != edgeReaders.end(); ++it) { |
|
1806 if (!it->second.touched()) { |
|
1807 ErrorMessage msg; |
|
1808 msg << "Edge not found in file: " << it->first; |
|
1809 throw IOParameterError(msg.message()); |
|
1810 } |
|
1811 } |
|
1812 for (typename UndirEdgeReaders::iterator it = undirEdgeReaders.begin(); |
|
1813 it != undirEdgeReaders.end(); ++it) { |
|
1814 if (!it->second.touched()) { |
|
1815 ErrorMessage msg; |
|
1816 msg << "UndirEdge not found in file: " << it->first; |
|
1817 throw IOParameterError(msg.message()); |
|
1726 } |
1818 } |
1727 } |
1819 } |
1728 } |
1820 } |
1729 |
1821 |
1730 private: |
1822 private: |
1731 |
1823 |
1732 std::string id; |
1824 std::string id; |
1733 |
1825 |
1734 typedef std::map<std::string, UndirEdge*> UndirEdgeReaders; |
1826 typedef std::map<std::string, |
1827 _reader_bits::ItemStore<UndirEdge> > UndirEdgeReaders; |
|
1735 UndirEdgeReaders undirEdgeReaders; |
1828 UndirEdgeReaders undirEdgeReaders; |
1736 std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader; |
1829 std::auto_ptr<_reader_bits::IdReaderBase<UndirEdge> > undirEdgeIdReader; |
1737 |
1830 |
1738 typedef std::map<std::string, Edge*> EdgeReaders; |
1831 typedef std::map<std::string, _reader_bits::ItemStore<Edge> > EdgeReaders; |
1739 EdgeReaders edgeReaders; |
1832 EdgeReaders edgeReaders; |
1740 std::auto_ptr<IdReaderBase<Edge> > edgeIdReader; |
1833 std::auto_ptr<_reader_bits::IdReaderBase<Edge> > edgeIdReader; |
1741 }; |
1834 }; |
1742 |
1835 |
1743 /// \ingroup io_group |
1836 /// \ingroup io_group |
1744 /// \brief SectionReader for attributes. |
1837 /// \brief SectionReader for attributes. |
1745 /// |
1838 /// |
1750 /// The attributeset section contains several lines. Each of them starts |
1843 /// The attributeset section contains several lines. Each of them starts |
1751 /// with an attribute and then a the value for the id. |
1844 /// with an attribute and then a the value for the id. |
1752 /// |
1845 /// |
1753 /// \relates LemonReader |
1846 /// \relates LemonReader |
1754 template <typename _Traits = DefaultReaderTraits> |
1847 template <typename _Traits = DefaultReaderTraits> |
1755 class AttributeReader : public CommonSectionReaderBase { |
1848 class AttributeReader : public LemonReader::SectionReader { |
1756 typedef CommonSectionReaderBase Parent; |
1849 typedef LemonReader::SectionReader Parent; |
1757 typedef _Traits Traits; |
1850 typedef _Traits Traits; |
1758 public: |
1851 public: |
1759 /// \brief Constructor. |
1852 /// \brief Constructor. |
1760 /// |
1853 /// |
1761 /// Constructor for AttributeReader. It creates the AttributeReader and |
1854 /// Constructor for AttributeReader. It creates the AttributeReader and |
1799 if (readers.find(name) != readers.end()) { |
1892 if (readers.find(name) != readers.end()) { |
1800 ErrorMessage msg; |
1893 ErrorMessage msg; |
1801 msg << "Multiple read rule for attribute: " << name; |
1894 msg << "Multiple read rule for attribute: " << name; |
1802 throw IOParameterError(msg.message()); |
1895 throw IOParameterError(msg.message()); |
1803 } |
1896 } |
1804 readers.insert(make_pair(name, new ValueReader<Value, Reader> |
1897 readers.insert(make_pair(name, new _reader_bits:: |
1805 (value, reader))); |
1898 ValueReader<Value, Reader>(value, reader))); |
1806 return *this; |
1899 return *this; |
1807 } |
1900 } |
1808 |
1901 |
1809 protected: |
1902 protected: |
1810 |
1903 |
1838 } |
1931 } |
1839 |
1932 |
1840 private: |
1933 private: |
1841 std::string id; |
1934 std::string id; |
1842 |
1935 |
1843 typedef std::map<std::string, ValueReaderBase*> Readers; |
1936 typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers; |
1844 Readers readers; |
1937 Readers readers; |
1845 }; |
1938 }; |
1846 |
1939 |
1847 /// \ingroup io_group |
1940 /// \ingroup io_group |
1848 /// \brief SectionReader for retrieve what is in the file. |
1941 /// \brief SectionReader for retrieve what is in the file. |