47 class ItemIdReader { |
47 class ItemIdReader { |
48 public: |
48 public: |
49 |
49 |
50 bool isIdReader() { return true; } |
50 bool isIdReader() { return true; } |
51 |
51 |
52 Item readId(std::istream&, Item) { return Item();} |
52 void readId(std::istream&, Item&) {} |
53 |
53 |
54 template <class _ItemIdReader> |
54 template <class _ItemIdReader> |
55 struct Constraints { |
55 struct Constraints { |
56 void constraints() { |
56 void constraints() { |
57 bool b = reader.isIdReader(); |
57 bool b = reader.isIdReader(); |
58 ignore_unused_variable_warning(b); |
58 ignore_unused_variable_warning(b); |
59 Item item = reader.readId(is, Item()); |
59 Item item; |
|
60 reader.readId(is, item); |
60 } |
61 } |
61 _ItemIdReader& reader; |
62 _ItemIdReader& reader; |
|
63 std::istream& is; |
|
64 }; |
|
65 |
|
66 }; |
|
67 |
|
68 template <typename Item> |
|
69 class ItemReader { |
|
70 public: |
|
71 void read(std::istream&, Item&) {} |
|
72 |
|
73 template <class _ItemReader> |
|
74 struct Constraints { |
|
75 void constraints() { |
|
76 Item item; |
|
77 reader.read(is, item); |
|
78 } |
|
79 _ItemReader& reader; |
62 std::istream& is; |
80 std::istream& is; |
63 }; |
81 }; |
64 |
82 |
65 }; |
83 }; |
66 |
84 |
567 |
585 |
568 IdReader(const BoxedIdReader& _boxedIdReader) |
586 IdReader(const BoxedIdReader& _boxedIdReader) |
569 : boxedIdReader(_boxedIdReader) {} |
587 : boxedIdReader(_boxedIdReader) {} |
570 |
588 |
571 virtual Item read(std::istream& is) const { |
589 virtual Item read(std::istream& is) const { |
572 return boxedIdReader.readId(is, Item()); |
590 Item item; |
|
591 boxedIdReader.readId(is, item); |
|
592 return item; |
573 } |
593 } |
574 |
594 |
575 virtual bool isIdReader() const { |
595 virtual bool isIdReader() const { |
576 return boxedIdReader.isIdReader(); |
596 return boxedIdReader.isIdReader(); |
577 } |
597 } |
694 private: |
714 private: |
695 |
715 |
696 template <typename Reader, typename Map, typename MapParameter> |
716 template <typename Reader, typename Map, typename MapParameter> |
697 NodeSetReader& _readMap(std::string name, MapParameter map, |
717 NodeSetReader& _readMap(std::string name, MapParameter map, |
698 const Reader& reader = Reader()) { |
718 const Reader& reader = Reader()) { |
|
719 checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>(); |
|
720 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
699 if (readers.find(name) != readers.end()) { |
721 if (readers.find(name) != readers.end()) { |
700 ErrorMessage msg; |
722 ErrorMessage msg; |
701 msg << "Multiple read rule for node map: " << name; |
723 msg << "Multiple read rule for node map: " << name; |
702 throw IOParameterError(msg.message()); |
724 throw IOParameterError(msg.message()); |
703 } |
725 } |
780 |
802 |
781 /// \brief Gives back the node by its id. |
803 /// \brief Gives back the node by its id. |
782 /// |
804 /// |
783 /// It reads an id from the stream and gives back which node belongs to |
805 /// It reads an id from the stream and gives back which node belongs to |
784 /// it. It is possible only if there was read an "id" named map. |
806 /// it. It is possible only if there was read an "id" named map. |
785 Node readId(std::istream& is, Node = Node()) const { |
807 void readId(std::istream& is, Node& node) const { |
786 return inverter->read(is); |
808 node = inverter->read(is); |
787 } |
809 } |
788 |
810 |
789 private: |
811 private: |
790 |
812 |
791 typedef std::map<std::string, ReaderBase<Node>*> MapReaders; |
813 typedef std::map<std::string, ReaderBase<Node>*> MapReaders; |
902 private: |
924 private: |
903 |
925 |
904 template <typename Reader, typename Map, typename MapParameter> |
926 template <typename Reader, typename Map, typename MapParameter> |
905 EdgeSetReader& _readMap(std::string name, MapParameter map, |
927 EdgeSetReader& _readMap(std::string name, MapParameter map, |
906 const Reader& reader = Reader()) { |
928 const Reader& reader = Reader()) { |
|
929 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>(); |
|
930 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
907 if (readers.find(name) != readers.end()) { |
931 if (readers.find(name) != readers.end()) { |
908 ErrorMessage msg; |
932 ErrorMessage msg; |
909 msg << "Multiple read rule for edge map: " << name; |
933 msg << "Multiple read rule for edge map: " << name; |
910 throw IOParameterError(msg.message()); |
934 throw IOParameterError(msg.message()); |
911 } |
935 } |
993 |
1017 |
994 /// \brief Gives back the edge by its id. |
1018 /// \brief Gives back the edge by its id. |
995 /// |
1019 /// |
996 /// It reads an id from the stream and gives back which edge belongs to |
1020 /// It reads an id from the stream and gives back which edge belongs to |
997 /// it. It is possible only if there was read an "id" named map. |
1021 /// it. It is possible only if there was read an "id" named map. |
998 Edge readId(std::istream& is, Edge = Edge()) const { |
1022 void readId(std::istream& is, Edge& edge) const { |
999 return inverter->read(is); |
1023 edge = inverter->read(is); |
1000 } |
1024 } |
1001 |
1025 |
1002 private: |
1026 private: |
1003 |
1027 |
1004 typedef std::map<std::string, ReaderBase<Edge>*> MapReaders; |
1028 typedef std::map<std::string, ReaderBase<Edge>*> MapReaders; |
1122 private: |
1146 private: |
1123 |
1147 |
1124 template <typename Reader, typename Map, typename MapParameter> |
1148 template <typename Reader, typename Map, typename MapParameter> |
1125 UndirEdgeSetReader& _readMap(std::string name, MapParameter map, |
1149 UndirEdgeSetReader& _readMap(std::string name, MapParameter map, |
1126 const Reader& reader = Reader()) { |
1150 const Reader& reader = Reader()) { |
|
1151 checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>(); |
|
1152 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
1127 if (readers.find(name) != readers.end()) { |
1153 if (readers.find(name) != readers.end()) { |
1128 ErrorMessage msg; |
1154 ErrorMessage msg; |
1129 msg << "Multiple read rule for edge map: " << name; |
1155 msg << "Multiple read rule for edge map: " << name; |
1130 throw IOParameterError(msg.message()); |
1156 throw IOParameterError(msg.message()); |
1131 } |
1157 } |
1188 |
1214 |
1189 private: |
1215 private: |
1190 |
1216 |
1191 template <typename Reader, typename Map, typename MapParameter> |
1217 template <typename Reader, typename Map, typename MapParameter> |
1192 UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map, |
1218 UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map, |
1193 const Reader& reader = Reader()) { |
1219 const Reader& reader = Reader()) { |
|
1220 checkConcept<_reader_bits::ItemReader<typename Map::Value>, Reader>(); |
|
1221 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>(); |
1194 readMap("+" + name, |
1222 readMap("+" + name, |
1195 _reader_bits::writeComposeMap(map, forwardMap(graph)), reader); |
1223 _reader_bits::writeComposeMap(map, forwardMap(graph)), reader); |
1196 readMap("-" + name, |
1224 readMap("-" + name, |
1197 _reader_bits::writeComposeMap(map, backwardMap(graph)), reader); |
1225 _reader_bits::writeComposeMap(map, backwardMap(graph)), reader); |
1198 return *this; |
1226 return *this; |
1273 |
1301 |
1274 /// \brief Gives back the undirected edge by its id. |
1302 /// \brief Gives back the undirected edge by its id. |
1275 /// |
1303 /// |
1276 /// It reads an id from the stream and gives back which undirected edge |
1304 /// It reads an id from the stream and gives back which undirected edge |
1277 /// belongs to it. It is possible only if there was read an "id" named map. |
1305 /// belongs to it. It is possible only if there was read an "id" named map. |
1278 UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const { |
1306 void readId(std::istream& is, UndirEdge& undirEdge) const { |
1279 return inverter->read(is); |
1307 undirEdge = inverter->read(is); |
1280 } |
1308 } |
1281 |
1309 |
1282 /// \brief Gives back the directed edge by its id. |
1310 /// \brief Gives back the directed edge by its id. |
1283 /// |
1311 /// |
1284 /// It reads an id from the stream and gives back which directed edge |
1312 /// It reads an id from the stream and gives back which directed edge |
1285 /// belongs to it. The directed edge id is the \c '+' or \c '-' character |
1313 /// belongs to it. The directed edge id is the \c '+' or \c '-' character |
1286 /// and the undirected edge id. It is possible only if there was read |
1314 /// and the undirected edge id. It is possible only if there was read |
1287 /// an "id" named map. |
1315 /// an "id" named map. |
1288 Edge readId(std::istream& is, Edge = Edge()) const { |
1316 void readId(std::istream& is, Edge& edge) const { |
1289 char c; |
1317 char c; |
1290 is >> c; |
1318 is >> c; |
1291 UndirEdge undirEdge = inverter->read(is); |
1319 UndirEdge undirEdge = inverter->read(is); |
1292 if (c == '+') { |
1320 if (c == '+') { |
1293 return graph.edgeWithSource(undirEdge, graph.source(undirEdge)); |
1321 edge = graph.edgeWithSource(undirEdge, graph.source(undirEdge)); |
1294 } else if (c == '-') { |
1322 } else if (c == '-') { |
1295 return graph.edgeWithSource(undirEdge, graph.target(undirEdge)); |
1323 edge = graph.edgeWithSource(undirEdge, graph.target(undirEdge)); |
1296 } else { |
1324 } else { |
1297 throw DataFormatError("Wrong id format for edge " |
1325 throw DataFormatError("Wrong id format for edge " |
1298 "in undirected edgeset"); |
1326 "in undirected edgeset"); |
1299 } |
1327 } |
1300 } |
1328 } |
1338 template <typename _IdReader> |
1366 template <typename _IdReader> |
1339 NodeReader(LemonReader& _reader, const _IdReader& _idReader, |
1367 NodeReader(LemonReader& _reader, const _IdReader& _idReader, |
1340 const std::string& _id = std::string()) |
1368 const std::string& _id = std::string()) |
1341 : Parent(_reader), id(_id) { |
1369 : Parent(_reader), id(_id) { |
1342 checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>(); |
1370 checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>(); |
1343 idReader.reset(new IdReader<Node, _IdReader>(_idReader)); |
1371 nodeIdReader.reset(new IdReader<Node, _IdReader>(_idReader)); |
1344 } |
1372 } |
1345 |
1373 |
1346 /// \brief Destructor. |
1374 /// \brief Destructor. |
1347 /// |
1375 /// |
1348 /// Destructor for NodeReader. |
1376 /// Destructor for NodeReader. |
1383 |
1411 |
1384 /// \brief Reader function of the section. |
1412 /// \brief Reader function of the section. |
1385 /// |
1413 /// |
1386 /// It reads the content of the section. |
1414 /// It reads the content of the section. |
1387 virtual void read(std::istream& is) { |
1415 virtual void read(std::istream& is) { |
1388 if (!idReader->isIdReader()) { |
1416 if (!nodeIdReader->isIdReader()) { |
1389 throw DataFormatError("Cannot find nodeset or ID map"); |
1417 throw DataFormatError("Cannot find nodeset or ID map"); |
1390 } |
1418 } |
1391 std::string line; |
1419 std::string line; |
1392 while (getline(is, line)) { |
1420 while (getline(is, line)) { |
1393 std::istringstream ls(line); |
1421 std::istringstream ls(line); |
1394 std::string id; |
1422 std::string id; |
1395 ls >> id; |
1423 ls >> id; |
1396 typename NodeReaders::iterator it = readers.find(id); |
1424 typename NodeReaders::iterator it = readers.find(id); |
1397 if (it != readers.end()) { |
1425 if (it != readers.end()) { |
1398 *(it->second) = idReader->read(ls); |
1426 *(it->second) = nodeIdReader->read(ls); |
1399 } |
1427 } |
1400 } |
1428 } |
1401 } |
1429 } |
1402 |
1430 |
1403 private: |
1431 private: |
1404 |
1432 |
1405 std::string id; |
1433 std::string id; |
1406 |
1434 |
1407 typedef std::map<std::string, Node*> NodeReaders; |
1435 typedef std::map<std::string, Node*> NodeReaders; |
1408 NodeReaders readers; |
1436 NodeReaders readers; |
1409 std::auto_ptr<IdReaderBase<Node> > idReader; |
1437 std::auto_ptr<IdReaderBase<Node> > nodeIdReader; |
1410 }; |
1438 }; |
1411 |
1439 |
1412 /// \ingroup io_group |
1440 /// \ingroup io_group |
1413 /// \brief SectionReader for reading labeled edges. |
1441 /// \brief SectionReader for reading labeled edges. |
1414 /// |
1442 /// |
1435 template <typename _IdReader> |
1463 template <typename _IdReader> |
1436 EdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1464 EdgeReader(LemonReader& _reader, const _IdReader& _idReader, |
1437 const std::string& _id = std::string()) |
1465 const std::string& _id = std::string()) |
1438 : Parent(_reader), id(_id) { |
1466 : Parent(_reader), id(_id) { |
1439 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1467 checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>(); |
1440 idReader.reset(new IdReader<Edge, _IdReader>(_idReader)); |
1468 edgeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader)); |
1441 } |
1469 } |
1442 |
1470 |
1443 /// \brief Destructor. |
1471 /// \brief Destructor. |
1444 /// |
1472 /// |
1445 /// Destructor for EdgeReader. |
1473 /// Destructor for EdgeReader. |
1479 |
1507 |
1480 /// \brief Reader function of the section. |
1508 /// \brief Reader function of the section. |
1481 /// |
1509 /// |
1482 /// It reads the content of the section. |
1510 /// It reads the content of the section. |
1483 virtual void read(std::istream& is) { |
1511 virtual void read(std::istream& is) { |
1484 if (!idReader->isIdReader()) { |
1512 if (!edgeIdReader->isIdReader()) { |
1485 throw DataFormatError("Cannot find edgeset or ID map"); |
1513 throw DataFormatError("Cannot find edgeset or ID map"); |
1486 } |
1514 } |
1487 std::string line; |
1515 std::string line; |
1488 while (getline(is, line)) { |
1516 while (getline(is, line)) { |
1489 std::istringstream ls(line); |
1517 std::istringstream ls(line); |
1490 std::string id; |
1518 std::string id; |
1491 ls >> id; |
1519 ls >> id; |
1492 typename EdgeReaders::iterator it = readers.find(id); |
1520 typename EdgeReaders::iterator it = readers.find(id); |
1493 if (it != readers.end()) { |
1521 if (it != readers.end()) { |
1494 *(it->second) = idReader->read(ls); |
1522 *(it->second) = edgeIdReader->read(ls); |
1495 } |
1523 } |
1496 } |
1524 } |
1497 } |
1525 } |
1498 |
1526 |
1499 private: |
1527 private: |
1500 |
1528 |
1501 std::string id; |
1529 std::string id; |
1502 |
1530 |
1503 typedef std::map<std::string, Edge*> EdgeReaders; |
1531 typedef std::map<std::string, Edge*> EdgeReaders; |
1504 EdgeReaders readers; |
1532 EdgeReaders readers; |
1505 std::auto_ptr<IdReaderBase<Edge> > idReader; |
1533 std::auto_ptr<IdReaderBase<Edge> > edgeIdReader; |
1506 }; |
1534 }; |
1507 |
1535 |
1508 /// \ingroup io_group |
1536 /// \ingroup io_group |
1509 /// \brief SectionReader for reading labeled undirected edges. |
1537 /// \brief SectionReader for reading labeled undirected edges. |
1510 /// |
1538 /// |
1686 /// |
1714 /// |
1687 /// Add an attribute reader command for the reader. |
1715 /// Add an attribute reader command for the reader. |
1688 template <typename Reader, typename Value> |
1716 template <typename Reader, typename Value> |
1689 AttributeReader& readAttribute(const std::string& name, Value& value, |
1717 AttributeReader& readAttribute(const std::string& name, Value& value, |
1690 const Reader& reader = Reader()) { |
1718 const Reader& reader = Reader()) { |
|
1719 checkConcept<_reader_bits::ItemReader<Value>, Reader>(); |
1691 if (readers.find(name) != readers.end()) { |
1720 if (readers.find(name) != readers.end()) { |
1692 ErrorMessage msg; |
1721 ErrorMessage msg; |
1693 msg << "Multiple read rule for attribute: " << name; |
1722 msg << "Multiple read rule for attribute: " << name; |
1694 throw IOParameterError(msg.message()); |
1723 throw IOParameterError(msg.message()); |
1695 } |
1724 } |