593 |
645 |
594 /// \brief Add a new node map reader command for the reader. |
646 /// \brief Add a new node map reader command for the reader. |
595 /// |
647 /// |
596 /// Add a new node map reader command for the reader. |
648 /// Add a new node map reader command for the reader. |
597 template <typename Map> |
649 template <typename Map> |
598 NodeSetReader& readMap(std::string name, Map& map) { |
650 NodeSetReader& readNodeMap(std::string name, Map& map) { |
599 return readMap<typename Traits:: |
651 return _readMap< |
600 template Reader<typename Map::Value>, Map>(name, map); |
652 typename Traits::template Reader<typename Map::Value>, Map, |
|
653 typename SmartParameter<Map>::Type>(name, map); |
|
654 } |
|
655 |
|
656 template <typename Map> |
|
657 NodeSetReader& readNodeMap(std::string name, const Map& map) { |
|
658 return _readMap< |
|
659 typename Traits::template Reader<typename Map::Value>, Map, |
|
660 typename SmartParameter<Map>::Type>(name, map); |
601 } |
661 } |
602 |
662 |
603 /// \brief Add a new node map reader command for the reader. |
663 /// \brief Add a new node map reader command for the reader. |
604 /// |
664 /// |
605 /// Add a new node map reader command for the reader. |
665 /// Add a new node map reader command for the reader. |
606 template <typename Reader, typename Map> |
666 template <typename Reader, typename Map> |
607 NodeSetReader& readMap(std::string name, Map& map, |
667 NodeSetReader& readNodeMap(std::string name, Map& map, |
608 const Reader& reader = Reader()) { |
668 const Reader& reader = Reader()) { |
|
669 return _readMap< |
|
670 typename Traits::template Reader<typename Map::Value>, Map, |
|
671 typename SmartParameter<Map>::Type>(name, map, reader); |
|
672 } |
|
673 |
|
674 template <typename Reader, typename Map> |
|
675 NodeSetReader& readNodeMap(std::string name, const Map& map, |
|
676 const Reader& reader = Reader()) { |
|
677 return _readMap< |
|
678 typename Traits::template Reader<typename Map::Value>, Map, |
|
679 typename SmartParameter<Map>::Type>(name, map, reader); |
|
680 } |
|
681 |
|
682 private: |
|
683 |
|
684 template <typename Reader, typename Map, typename MapParameter> |
|
685 NodeSetReader& _readMap(std::string name, MapParameter map, |
|
686 const Reader& reader = Reader()) { |
609 if (readers.find(name) != readers.end()) { |
687 if (readers.find(name) != readers.end()) { |
610 ErrorMessage msg; |
688 ErrorMessage msg; |
611 msg << "Multiple read rule for node map: " << name; |
689 msg << "Multiple read rule for node map: " << name; |
612 throw IOParameterError(msg.message()); |
690 throw IOParameterError(msg.message()); |
613 } |
691 } |
614 readers.insert( |
692 readers.insert( |
615 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); |
693 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); |
616 return *this; |
694 return *this; |
617 } |
695 } |
618 |
696 |
|
697 public: |
|
698 |
619 /// \brief Add a new node map skipper command for the reader. |
699 /// \brief Add a new node map skipper command for the reader. |
620 /// |
700 /// |
621 /// Add a new node map skipper command for the reader. |
701 /// Add a new node map skipper command for the reader. |
622 template <typename Reader> |
702 template <typename Reader> |
623 NodeSetReader& skipMap(std::string name, |
703 NodeSetReader& skipNodeMap(std::string name, |
624 const Reader& reader = Reader()) { |
704 const Reader& reader = Reader()) { |
625 if (readers.find(name) != readers.end()) { |
705 if (readers.find(name) != readers.end()) { |
626 ErrorMessage msg; |
706 ErrorMessage msg; |
627 msg << "Multiple read rule for node map: " << name; |
707 msg << "Multiple read rule for node map: " << name; |
628 throw IOParameterError(msg.message()); |
708 throw IOParameterError(msg.message()); |
772 |
854 |
773 /// \brief Add a new edge map reader command for the reader. |
855 /// \brief Add a new edge map reader command for the reader. |
774 /// |
856 /// |
775 /// Add a new edge map reader command for the reader. |
857 /// Add a new edge map reader command for the reader. |
776 template <typename Map> |
858 template <typename Map> |
777 EdgeSetReader& readMap(std::string name, Map& map) { |
859 EdgeSetReader& readEdgeMap(std::string name, Map& map) { |
778 return readMap<typename Traits:: |
860 return _readMap< |
779 template Reader<typename Map::Value>, Map>(name, map); |
861 typename Traits::template Reader<typename Map::Value>, Map, |
|
862 typename SmartParameter<Map>::Type>(name, map); |
|
863 } |
|
864 |
|
865 template <typename Map> |
|
866 EdgeSetReader& readEdgeMap(std::string name, const Map& map) { |
|
867 return _readMap< |
|
868 typename Traits::template Reader<typename Map::Value>, Map, |
|
869 typename SmartParameter<Map>::Type>(name, map); |
780 } |
870 } |
781 |
871 |
782 /// \brief Add a new edge map reader command for the reader. |
872 /// \brief Add a new edge map reader command for the reader. |
783 /// |
873 /// |
784 /// Add a new edge map reader command for the reader. |
874 /// Add a new edge map reader command for the reader. |
785 template <typename Reader, typename Map> |
875 template <typename Reader, typename Map> |
786 EdgeSetReader& readMap(std::string name, Map& map, |
876 EdgeSetReader& readEdgeMap(std::string name, Map& map, |
787 const Reader& reader = Reader()) { |
877 const Reader& reader = Reader()) { |
|
878 return _readMap< |
|
879 typename Traits::template Reader<typename Map::Value>, Map, |
|
880 typename SmartParameter<Map>::Type>(name, map, reader); |
|
881 } |
|
882 |
|
883 template <typename Reader, typename Map> |
|
884 EdgeSetReader& readEdgeMap(std::string name, const Map& map, |
|
885 const Reader& reader = Reader()) { |
|
886 return _readMap< |
|
887 typename Traits::template Reader<typename Map::Value>, Map, |
|
888 typename SmartParameter<Map>::Type>(name, map, reader); |
|
889 } |
|
890 |
|
891 private: |
|
892 |
|
893 template <typename Reader, typename Map, typename MapParameter> |
|
894 EdgeSetReader& _readMap(std::string name, MapParameter map, |
|
895 const Reader& reader = Reader()) { |
788 if (readers.find(name) != readers.end()) { |
896 if (readers.find(name) != readers.end()) { |
789 ErrorMessage msg; |
897 ErrorMessage msg; |
790 msg << "Multiple read rule for edge map: " << name; |
898 msg << "Multiple read rule for edge map: " << name; |
791 throw IOParameterError(msg.message()); |
899 throw IOParameterError(msg.message()); |
792 } |
900 } |
793 readers.insert( |
901 readers.insert( |
794 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); |
902 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); |
795 return *this; |
903 return *this; |
796 } |
904 } |
797 |
905 |
|
906 public: |
|
907 |
798 /// \brief Add a new edge map skipper command for the reader. |
908 /// \brief Add a new edge map skipper command for the reader. |
799 /// |
909 /// |
800 /// Add a new edge map skipper command for the reader. |
910 /// Add a new edge map skipper command for the reader. |
801 template <typename Reader> |
911 template <typename Reader> |
802 EdgeSetReader& skipMap(std::string name, |
912 EdgeSetReader& skipEdgeMap(std::string name, |
803 const Reader& reader = Reader()) { |
913 const Reader& reader = Reader()) { |
804 if (readers.find(name) != readers.end()) { |
914 if (readers.find(name) != readers.end()) { |
805 ErrorMessage msg; |
915 ErrorMessage msg; |
806 msg << "Multiple read rule for node map: " << name; |
916 msg << "Multiple read rule for edge map: " << name; |
807 throw IOParameterError(msg.message()); |
917 throw IOParameterError(msg.message()); |
808 } |
918 } |
809 readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader))); |
919 readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader))); |
810 return *this; |
920 return *this; |
811 } |
921 } |
869 |
979 |
870 /// \brief Gives back the edge by its id. |
980 /// \brief Gives back the edge by its id. |
871 /// |
981 /// |
872 /// It reads an id from the stream and gives back which edge belongs to |
982 /// It reads an id from the stream and gives back which edge belongs to |
873 /// it. It is possible only if there was read an "id" named map. |
983 /// it. It is possible only if there was read an "id" named map. |
874 typename Graph::Edge readId(std::istream& is) const { |
984 Item readId(std::istream& is) const { |
875 return inverter->read(is); |
985 return inverter->read(is); |
876 } |
986 } |
877 |
987 |
878 private: |
988 private: |
879 |
989 |
880 typedef std::map<std::string, ReaderBase<Item>*> MapReaders; |
990 typedef std::map<std::string, ReaderBase<Item>*> MapReaders; |
881 MapReaders readers; |
991 MapReaders readers; |
882 |
992 |
883 Graph& graph; |
993 typename SmartReference<Graph>::Type graph; |
|
994 std::string id; |
|
995 SkipReader<Item, DefaultSkipper> skipper; |
|
996 |
|
997 std::auto_ptr<InverterBase<Item> > inverter; |
|
998 std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader; |
|
999 }; |
|
1000 |
|
1001 /// \ingroup io_group |
|
1002 /// \brief SectionReader for reading a undirected graph's edgeset. |
|
1003 /// |
|
1004 /// The lemon format can store multiple undirected edgesets with several |
|
1005 /// maps. The undirected edgeset section's header line is \c \@undiredgeset |
|
1006 /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. |
|
1007 /// |
|
1008 /// The first line of the section contains the names of the maps separated |
|
1009 /// with white spaces. Each next lines describes an edge in the edgeset. The |
|
1010 /// line contains the connected nodes' id and the mapped values for each map. |
|
1011 /// |
|
1012 /// The section can handle the directed as a syntactical sugar. Two |
|
1013 /// undirected edge map describes one directed edge map. This two maps |
|
1014 /// are the forward map and the backward map and the names of this map |
|
1015 /// is near the same just with a prefix \c '+' or \c '-' character |
|
1016 /// difference. |
|
1017 /// |
|
1018 /// If the edgeset contains an \c "id" named map then it will be regarded |
|
1019 /// as id map. This map should contain only unique values and when the |
|
1020 /// \c readId() member will read a value from the given stream it will |
|
1021 /// give back that undiricted edge which is mapped to this value. |
|
1022 /// |
|
1023 /// The undirected edgeset reader needs a node id reader to identify which |
|
1024 /// nodes have to be connected. If a NodeSetReader reads an "id" named map, |
|
1025 /// it will be able to resolve the nodes by ids. |
|
1026 /// |
|
1027 /// \relates LemonReader |
|
1028 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
|
1029 class UndirEdgeSetReader : public CommonSectionReaderBase { |
|
1030 typedef CommonSectionReaderBase Parent; |
|
1031 public: |
|
1032 |
|
1033 typedef _Graph Graph; |
|
1034 typedef _Traits Traits; |
|
1035 typedef typename Graph::UndirEdge Item; |
|
1036 typedef typename Traits::Skipper DefaultSkipper; |
|
1037 |
|
1038 /// \brief Constructor. |
|
1039 /// |
|
1040 /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader |
|
1041 /// and attach it into the given LemonReader. The undirected edgeset |
|
1042 /// reader will add the readed undirected edges to the given Graph. It |
|
1043 /// will use the given node id reader to read the source and target |
|
1044 /// nodes of the edges. The reader will read the section only if the |
|
1045 /// \c _id and the \c undiredgset_id are the same. |
|
1046 template <typename NodeIdReader> |
|
1047 UndirEdgeSetReader(LemonReader& _reader, |
|
1048 typename SmartParameter<Graph>::Type _graph, |
|
1049 const NodeIdReader& _nodeIdReader, |
|
1050 const std::string& _id = std::string(), |
|
1051 const DefaultSkipper& _skipper = DefaultSkipper()) |
|
1052 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper), |
|
1053 nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader> |
|
1054 (_nodeIdReader)) {} |
|
1055 |
|
1056 /// \brief Destructor. |
|
1057 /// |
|
1058 /// Destructor for UndirEdgeSetReader. |
|
1059 virtual ~UndirEdgeSetReader() { |
|
1060 for (typename MapReaders::iterator it = readers.begin(); |
|
1061 it != readers.end(); ++it) { |
|
1062 delete it->second; |
|
1063 } |
|
1064 } |
|
1065 |
|
1066 private: |
|
1067 UndirEdgeSetReader(const UndirEdgeSetReader&); |
|
1068 void operator=(const UndirEdgeSetReader&); |
|
1069 |
|
1070 public: |
|
1071 |
|
1072 /// \brief Add a new undirected edge map reader command for the reader. |
|
1073 /// |
|
1074 /// Add a new edge undirected map reader command for the reader. |
|
1075 template <typename Map> |
|
1076 UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) { |
|
1077 return _readMap< |
|
1078 typename Traits::template Reader<typename Map::Value>, Map, |
|
1079 typename SmartParameter<Map>::Type>(name, map); |
|
1080 } |
|
1081 |
|
1082 template <typename Map> |
|
1083 UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) { |
|
1084 return _readMap< |
|
1085 typename Traits::template Reader<typename Map::Value>, Map, |
|
1086 typename SmartParameter<Map>::Type>(name, map); |
|
1087 } |
|
1088 |
|
1089 /// \brief Add a new undirected edge map reader command for the reader. |
|
1090 /// |
|
1091 /// Add a new edge undirected map reader command for the reader. |
|
1092 template <typename Reader, typename Map> |
|
1093 UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map, |
|
1094 const Reader& reader = Reader()) { |
|
1095 return _readMap<Reader, Map, typename SmartParameter<Map>::Type> |
|
1096 (name, map, reader); |
|
1097 } |
|
1098 |
|
1099 template <typename Reader, typename Map> |
|
1100 UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map, |
|
1101 const Reader& reader = Reader()) { |
|
1102 return _readMap<Reader, Map, typename SmartParameter<Map>::Type > |
|
1103 (name, map, reader); |
|
1104 } |
|
1105 |
|
1106 private: |
|
1107 |
|
1108 template <typename Reader, typename Map, typename MapParameter> |
|
1109 UndirEdgeSetReader& _readMap(std::string name, MapParameter map, |
|
1110 const Reader& reader = Reader()) { |
|
1111 if (readers.find(name) != readers.end()) { |
|
1112 ErrorMessage msg; |
|
1113 msg << "Multiple read rule for edge map: " << name; |
|
1114 throw IOParameterError(msg.message()); |
|
1115 } |
|
1116 readers.insert( |
|
1117 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); |
|
1118 return *this; |
|
1119 } |
|
1120 |
|
1121 public: |
|
1122 |
|
1123 /// \brief Add a new undirected edge map skipper command for the reader. |
|
1124 /// |
|
1125 /// Add a new undirected edge map skipper command for the reader. |
|
1126 template <typename Reader> |
|
1127 UndirEdgeSetReader& skipUndirEdgeMap(std::string name, |
|
1128 const Reader& reader = Reader()) { |
|
1129 if (readers.find(name) != readers.end()) { |
|
1130 ErrorMessage msg; |
|
1131 msg << "Multiple read rule for node map: " << name; |
|
1132 throw IOParameterError(msg.message()); |
|
1133 } |
|
1134 readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader))); |
|
1135 return *this; |
|
1136 } |
|
1137 |
|
1138 /// \brief Add a new directed edge map reader command for the reader. |
|
1139 /// |
|
1140 /// Add a new directed edge map reader command for the reader. |
|
1141 template <typename Map> |
|
1142 UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) { |
|
1143 return _readDirMap< |
|
1144 typename Traits::template Reader<typename Map::Value>, Map, |
|
1145 typename SmartParameter<Map>::Type>(name, map); |
|
1146 } |
|
1147 |
|
1148 template <typename Map> |
|
1149 UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) { |
|
1150 return _readDirMap< |
|
1151 typename Traits::template Reader<typename Map::Value>, Map, |
|
1152 typename SmartParameter<Map>::Type>(name, map); |
|
1153 } |
|
1154 |
|
1155 /// \brief Add a new directed edge map reader command for the reader. |
|
1156 /// |
|
1157 /// Add a new directed edge map reader command for the reader. |
|
1158 template <typename Reader, typename Map> |
|
1159 UndirEdgeSetReader& readEdgeMap(std::string name, Map& map, |
|
1160 const Reader& reader = Reader()) { |
|
1161 return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type> |
|
1162 (name, map, reader); |
|
1163 } |
|
1164 |
|
1165 template <typename Reader, typename Map> |
|
1166 UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map, |
|
1167 const Reader& reader = Reader()) { |
|
1168 return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type> |
|
1169 (name, map, reader); |
|
1170 } |
|
1171 |
|
1172 private: |
|
1173 |
|
1174 template <typename Reader, typename Map, typename MapParameter> |
|
1175 UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map, |
|
1176 const Reader& reader = Reader()) { |
|
1177 readMap("+" + name, |
|
1178 _reader_bits::writeComposeMap(map, forwardMap(graph)), reader); |
|
1179 readMap("-" + name, |
|
1180 _reader_bits::writeComposeMap(map, backwardMap(graph)), reader); |
|
1181 return *this; |
|
1182 } |
|
1183 |
|
1184 public: |
|
1185 |
|
1186 /// \brief Add a new directed edge map skipper command for the reader. |
|
1187 /// |
|
1188 /// Add a new directed edge map skipper command for the reader. |
|
1189 template <typename Reader> |
|
1190 UndirEdgeSetReader& skipEdgeMap(std::string name, |
|
1191 const Reader& reader = Reader()) { |
|
1192 skipMap("+" + name, reader); |
|
1193 skipMap("-" + name, reader); |
|
1194 return *this; |
|
1195 } |
|
1196 |
|
1197 protected: |
|
1198 |
|
1199 /// \brief Gives back true when the SectionReader can process |
|
1200 /// the section with the given header line. |
|
1201 /// |
|
1202 /// It gives back true when the header line starts with \c \@undiredgeset, |
|
1203 /// and the header line's id and the edgeset's id are the same. |
|
1204 virtual bool header(const std::string& line) { |
|
1205 std::istringstream ls(line); |
|
1206 std::string command; |
|
1207 std::string name; |
|
1208 ls >> command >> name; |
|
1209 return command == "@undiredgeset" && name == id; |
|
1210 } |
|
1211 |
|
1212 /// \brief Reader function of the section. |
|
1213 /// |
|
1214 /// It reads the content of the section. |
|
1215 virtual void read(std::istream& is) { |
|
1216 std::vector<ReaderBase<Item>* > index; |
|
1217 std::string line; |
|
1218 |
|
1219 getline(is, line); |
|
1220 std::istringstream ls(line); |
|
1221 while (ls >> id) { |
|
1222 typename MapReaders::iterator it = readers.find(id); |
|
1223 if (it != readers.end()) { |
|
1224 index.push_back(it->second); |
|
1225 } else { |
|
1226 index.push_back(&skipper); |
|
1227 } |
|
1228 if (id == "id" && inverter.get() == 0) { |
|
1229 inverter.reset(index.back()->getInverter()); |
|
1230 index.back() = inverter.get(); |
|
1231 } |
|
1232 } |
|
1233 while (getline(is, line)) { |
|
1234 std::istringstream ls(line); |
|
1235 typename Graph::Node from = nodeIdReader->read(ls); |
|
1236 typename Graph::Node to = nodeIdReader->read(ls); |
|
1237 typename Graph::UndirEdge edge = graph.addEdge(from, to); |
|
1238 for (int i = 0; i < (int)index.size(); ++i) { |
|
1239 index[i]->read(ls, edge); |
|
1240 } |
|
1241 } |
|
1242 } |
|
1243 |
|
1244 public: |
|
1245 |
|
1246 /// \brief Returns true if the edgeset can give back the edge by its id. |
|
1247 /// |
|
1248 /// Returns true if the edgeset can give back the undirected edge by its |
|
1249 /// id. It is possible only if an "id" named map was read. |
|
1250 bool isIdReader() const { |
|
1251 return inverter.get() != 0; |
|
1252 } |
|
1253 |
|
1254 /// \brief Gives back the undirected edge by its id. |
|
1255 /// |
|
1256 /// It reads an id from the stream and gives back which undirected edge |
|
1257 /// belongs to it. It is possible only if there was read an "id" named map. |
|
1258 Item readId(std::istream& is) const { |
|
1259 return inverter->read(is); |
|
1260 } |
|
1261 |
|
1262 private: |
|
1263 |
|
1264 typedef std::map<std::string, ReaderBase<Item>*> MapReaders; |
|
1265 MapReaders readers; |
|
1266 |
|
1267 typename SmartReference<Graph>::Type graph; |
884 std::string id; |
1268 std::string id; |
885 SkipReader<Item, DefaultSkipper> skipper; |
1269 SkipReader<Item, DefaultSkipper> skipper; |
886 |
1270 |
887 std::auto_ptr<InverterBase<Item> > inverter; |
1271 std::auto_ptr<InverterBase<Item> > inverter; |
888 std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader; |
1272 std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader; |
1070 ItemReaders readers; |
1454 ItemReaders readers; |
1071 std::auto_ptr<IdReaderBase<Item> > idReader; |
1455 std::auto_ptr<IdReaderBase<Item> > idReader; |
1072 }; |
1456 }; |
1073 |
1457 |
1074 /// \ingroup io_group |
1458 /// \ingroup io_group |
|
1459 /// \brief SectionReader for reading labeled undirected edges. |
|
1460 /// |
|
1461 /// The undirected edges section's header line is \c \@undiredges |
|
1462 /// \c undiredges_id, but the \c undiredges_id may be empty. |
|
1463 /// |
|
1464 /// Each line in the section contains the name of the undirected edge |
|
1465 /// and then the undirected edge id. |
|
1466 /// |
|
1467 /// \relates LemonReader |
|
1468 template <typename _Graph> |
|
1469 class UndirEdgeReader : public CommonSectionReaderBase { |
|
1470 typedef CommonSectionReaderBase Parent; |
|
1471 typedef _Graph Graph; |
|
1472 typedef typename Graph::UndirEdge Item; |
|
1473 public: |
|
1474 |
|
1475 /// \brief Constructor. |
|
1476 /// |
|
1477 /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and |
|
1478 /// attach it into the given LemonReader. It will use the given |
|
1479 /// undirected edge id reader to give back the edges. The reader will |
|
1480 /// read the section only if the \c _id and the \c undiredges_id are |
|
1481 /// the same. |
|
1482 template <typename _IdReader> |
|
1483 UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
|
1484 const std::string& _id = std::string()) |
|
1485 : Parent(_reader), id(_id), |
|
1486 idReader(new IdReader<typename Graph::UndirEdge, _IdReader>(_idReader)) |
|
1487 {} |
|
1488 |
|
1489 /// \brief Destructor. |
|
1490 /// |
|
1491 /// Destructor for UndirEdgeReader. |
|
1492 virtual ~UndirEdgeReader() {} |
|
1493 private: |
|
1494 UndirEdgeReader(const UndirEdgeReader&); |
|
1495 void operator=(const UndirEdgeReader&); |
|
1496 |
|
1497 public: |
|
1498 |
|
1499 /// \brief Add an undirected edge reader command for the UndirEdgeReader. |
|
1500 /// |
|
1501 /// Add an undirected edge reader command for the UndirEdgeReader. |
|
1502 void readUndirEdge(const std::string& name, Item& item) { |
|
1503 if (readers.find(name) != readers.end()) { |
|
1504 ErrorMessage msg; |
|
1505 msg << "Multiple read rule for edge: " << name; |
|
1506 throw IOParameterError(msg.message()); |
|
1507 } |
|
1508 readers.insert(make_pair(name, &item)); |
|
1509 } |
|
1510 |
|
1511 protected: |
|
1512 |
|
1513 /// \brief Gives back true when the SectionReader can process |
|
1514 /// the section with the given header line. |
|
1515 /// |
|
1516 /// It gives back true when the header line start with \c \@edges, |
|
1517 /// and the header line's id and the reader's id are the same. |
|
1518 virtual bool header(const std::string& line) { |
|
1519 std::istringstream ls(line); |
|
1520 std::string command; |
|
1521 std::string name; |
|
1522 ls >> command >> name; |
|
1523 return command == "@edges" && name == id; |
|
1524 } |
|
1525 |
|
1526 /// \brief Reader function of the section. |
|
1527 /// |
|
1528 /// It reads the content of the section. |
|
1529 virtual void read(std::istream& is) { |
|
1530 std::string line; |
|
1531 while (getline(is, line)) { |
|
1532 std::istringstream ls(line); |
|
1533 std::string id; |
|
1534 ls >> id; |
|
1535 typename ItemReaders::iterator it = readers.find(id); |
|
1536 if (it != readers.end()) { |
|
1537 *(it->second) = idReader->read(ls); |
|
1538 } |
|
1539 } |
|
1540 } |
|
1541 |
|
1542 private: |
|
1543 |
|
1544 std::string id; |
|
1545 |
|
1546 typedef std::map<std::string, Item*> ItemReaders; |
|
1547 ItemReaders readers; |
|
1548 std::auto_ptr<IdReaderBase<Item> > idReader; |
|
1549 }; |
|
1550 |
|
1551 /// \ingroup io_group |
1075 /// \brief SectionReader for attributes. |
1552 /// \brief SectionReader for attributes. |
1076 /// |
1553 /// |
1077 /// The lemon format can store multiple attribute set. Each set has |
1554 /// The lemon format can store multiple attribute set. Each set has |
1078 /// the header line \c \@attributes \c attributeset_id, but the |
1555 /// the header line \c \@attributes \c attributeset_id, but the |
1079 /// attributeset_id may be empty. |
1556 /// attributeset_id may be empty. |