1.1 --- a/src/lemon/graph_reader.h Fri May 06 15:39:33 2005 +0000
1.2 +++ b/src/lemon/graph_reader.h Mon May 09 11:24:26 2005 +0000
1.3 @@ -22,173 +22,17 @@
1.4 #define LEMON_GRAPH_READER_H
1.5
1.6 #include <iostream>
1.7 -#include <sstream>
1.8 -
1.9 -#include <map>
1.10 -#include <vector>
1.11 -
1.12 -#include <memory>
1.13
1.14 #include <lemon/error.h>
1.15 -
1.16 +#include <lemon/lemon_reader.h>
1.17
1.18 namespace lemon {
1.19
1.20 /// \addtogroup io_group
1.21 /// @{
1.22
1.23 - /// \brief Standard ReaderTraits for the GraphReader class.
1.24 - ///
1.25 - /// Standard ReaderTraits for the GraphReader class.
1.26 - /// It defines standard reading method for all type of value.
1.27 - /// \author Balazs Dezso
1.28 - struct DefaultReaderTraits {
1.29 -
1.30 - /// \brief Template class for reading an value.
1.31 - ///
1.32 - /// Template class for reading an value.
1.33 - /// \author Balazs Dezso
1.34 - template <typename _Value>
1.35 - struct Reader {
1.36 - /// The value type.
1.37 - typedef _Value Value;
1.38 - /// \brief Reads a value from the given stream.
1.39 - ///
1.40 - /// Reads a value from the given stream.
1.41 - void read(std::istream& is, Value& value) {
1.42 - if (!(is >> value))
1.43 - throw DataFormatError("Default reader format exception");
1.44 - }
1.45 - };
1.46 -
1.47 - /// \brief Returns wheter this name is an ID map name.
1.48 - ///
1.49 - /// Returns wheter this name is an ID map name.
1.50 - static bool idMapName(const std::string& name) {
1.51 - return name == "id";
1.52 - }
1.53 -
1.54 - /// The reader class for the not needed maps.
1.55 - typedef Reader<std::string> DefaultReader;
1.56 -
1.57 - };
1.58 -
1.59 - /// \brief Reader class for quoted strings.
1.60 - ///
1.61 - /// Reader class for quoted strings. It can process the escape
1.62 - /// sequences in the string.
1.63 - /// \author Balazs Dezso
1.64 - class QuotedStringReader {
1.65 - public:
1.66 - typedef std::string Value;
1.67 -
1.68 - /// \brief Constructor for the reader.
1.69 - ///
1.70 - /// Constructor for the reader. If the given parameter is true
1.71 - /// the reader processes the escape sequences.
1.72 - QuotedStringReader(bool _escaped = true) : escaped(_escaped) {}
1.73 -
1.74 - /// \brief Reads a quoted string from the given stream.
1.75 - ///
1.76 - /// Reads a quoted string from the given stream.
1.77 - void read(std::istream& is, std::string& value) {
1.78 - char c;
1.79 - value.clear();
1.80 - is >> std::ws;
1.81 - if (!is.get(c) || c != '\"')
1.82 - throw DataFormatError("Quoted string format error");
1.83 - while (is.get(c) && c != '\"') {
1.84 - if (escaped && c == '\\') {
1.85 - value += readEscape(is);
1.86 - } else {
1.87 - value += c;
1.88 - }
1.89 - }
1.90 - if (!is) throw DataFormatError("Quoted string format error");
1.91 - }
1.92 -
1.93 - private:
1.94 -
1.95 - static char readEscape(std::istream& is) {
1.96 - char c;
1.97 - switch (is.get(c), c) {
1.98 - case '\\':
1.99 - return '\\';
1.100 - case '\"':
1.101 - return '\"';
1.102 - case '\'':
1.103 - return '\'';
1.104 - case '\?':
1.105 - return '\?';
1.106 - case 'a':
1.107 - return '\a';
1.108 - case 'b':
1.109 - return '\b';
1.110 - case 'f':
1.111 - return '\f';
1.112 - case 'n':
1.113 - return '\n';
1.114 - case 'r':
1.115 - return '\r';
1.116 - case 't':
1.117 - return '\t';
1.118 - case 'v':
1.119 - return '\v';
1.120 - case 'x':
1.121 - {
1.122 - int code;
1.123 - if (!is.get(c) || !isHex(c))
1.124 - throw DataFormatError("Escape format error");
1.125 - else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
1.126 - else code = code * 16 + valueHex(c);
1.127 - return code;
1.128 - }
1.129 - default:
1.130 - {
1.131 - int code;
1.132 - if (!isOct(c))
1.133 - throw DataFormatError("Escape format error");
1.134 - else if (code = valueOct(c), !is.get(c) || !isOct(c))
1.135 - is.putback(c);
1.136 - else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
1.137 - is.putback(c);
1.138 - else code = code * 8 + valueOct(c);
1.139 - return code;
1.140 - }
1.141 - }
1.142 - }
1.143 -
1.144 - static bool isOct(char c) {
1.145 - return '0' <= c && c <='7';
1.146 - }
1.147 -
1.148 - static int valueOct(char c) {
1.149 - return c - '0';
1.150 - }
1.151 -
1.152 - static bool isHex(char c) {
1.153 - return ('0' <= c && c <= '9') ||
1.154 - ('a' <= c && c <= 'z') ||
1.155 - ('A' <= c && c <= 'Z');
1.156 - }
1.157 -
1.158 - static int valueHex(char c) {
1.159 - if ('0' <= c && c <= '9') return c - '0';
1.160 - if ('a' <= c && c <= 'z') return c - 'a' + 10;
1.161 - return c - 'A' + 10;
1.162 - }
1.163 -
1.164 - bool escaped;
1.165 - };
1.166 -
1.167 - class GUIReader {
1.168 - public:
1.169 - virtual void read(std::istream& is) = 0;
1.170 - };
1.171 -
1.172 /// \brief The graph reader class.
1.173 ///
1.174 - ///
1.175 /// The given file format may contain several maps and labeled nodes or
1.176 /// edges.
1.177 ///
1.178 @@ -229,8 +73,8 @@
1.179 /// reader.readEdgeMap("label", labelMap);
1.180 /// \endcode
1.181 ///
1.182 - /// With \c readNode() and \c readEdge() functions you can read labeled Nodes
1.183 - /// and Edges.
1.184 + /// With \c readNode() and \c readEdge() functions you can read
1.185 + /// labeled Nodes and Edges.
1.186 ///
1.187 /// \code
1.188 /// reader.readNode("source", sourceNode);
1.189 @@ -239,6 +83,10 @@
1.190 /// reader.readEdge("observed", edge);
1.191 /// \endcode
1.192 ///
1.193 + /// With the \c readAttribute() functions you can read an attribute
1.194 + /// in a variable. You can specify the reader for the attribute as
1.195 + /// the nodemaps.
1.196 + ///
1.197 /// After you give all read commands you must call the \c run() member
1.198 /// function, which execute all the commands.
1.199 ///
1.200 @@ -260,31 +108,56 @@
1.201 typedef typename Graph::Edge Edge;
1.202
1.203 typedef _ReaderTraits ReaderTraits;
1.204 - typedef typename ReaderTraits::DefaultReader DefaultReader;
1.205 + typedef typename ReaderTraits::Skipper DefaultSkipper;
1.206
1.207 /// \brief Construct a new GraphReader.
1.208 ///
1.209 /// Construct a new GraphReader. It reads into the given graph
1.210 /// and it use the given reader as the default skipper.
1.211 GraphReader(std::istream& _is, Graph& _graph,
1.212 - const DefaultReader& _reader = DefaultReader())
1.213 - : gui_reader(0), is(_is), graph(_graph),
1.214 - nodeSkipper(_reader), edgeSkipper(_reader) {}
1.215 + const DefaultSkipper& _skipper = DefaultSkipper())
1.216 + : reader(new LemonReader(_is)), own_reader(true),
1.217 + graph(_graph), skipper(_skipper),
1.218 + nodeset_reader(*reader, graph, std::string(), skipper),
1.219 + edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.220 + node_reader(*reader, nodeset_reader, std::string()),
1.221 + edge_reader(*reader, edgeset_reader, std::string()),
1.222 + attribute_reader(*reader, std::string()) {}
1.223 +
1.224 + /// \brief Construct a new GraphReader.
1.225 + ///
1.226 + /// Construct a new GraphReader. It reads into the given graph
1.227 + /// and it use the given reader as the default skipper.
1.228 + GraphReader(const std::string& _filename, Graph& _graph,
1.229 + const DefaultSkipper& _skipper = DefaultSkipper())
1.230 + : reader(new LemonReader(_filename)), own_reader(true),
1.231 + graph(_graph), skipper(_skipper),
1.232 + nodeset_reader(*reader, graph, std::string(), skipper),
1.233 + edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.234 + node_reader(*reader, nodeset_reader, std::string()),
1.235 + edge_reader(*reader, edgeset_reader, std::string()),
1.236 + attribute_reader(*reader, std::string()) {}
1.237 +
1.238 + /// \brief Construct a new GraphReader.
1.239 + ///
1.240 + /// Construct a new GraphReader. It reads into the given graph
1.241 + /// and it use the given reader as the default skipper.
1.242 + GraphReader(LemonReader& _reader, Graph& _graph,
1.243 + const DefaultSkipper& _skipper = DefaultSkipper())
1.244 + : reader(_reader), own_reader(false),
1.245 + graph(_graph), skipper(_skipper),
1.246 + nodeset_reader(*reader, graph, std::string(), skipper),
1.247 + edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
1.248 + node_reader(*reader, nodeset_reader, std::string()),
1.249 + edge_reader(*reader, edgeset_reader, std::string()),
1.250 + attribute_reader(*reader, std::string()) {}
1.251
1.252 /// \brief Destruct the graph reader.
1.253 ///
1.254 /// Destruct the graph reader.
1.255 ~GraphReader() {
1.256 - for (typename NodeMapReaders::iterator it = node_map_readers.begin();
1.257 - it != node_map_readers.end(); ++it) {
1.258 - delete it->second;
1.259 - }
1.260 -
1.261 - for (typename EdgeMapReaders::iterator it = edge_map_readers.begin();
1.262 - it != edge_map_readers.end(); ++it) {
1.263 - delete it->second;
1.264 - }
1.265 -
1.266 + if (own_reader)
1.267 + delete reader;
1.268 }
1.269
1.270 /// \brief Add a new node map reader command for the reader.
1.271 @@ -292,8 +165,8 @@
1.272 /// Add a new node map reader command for the reader.
1.273 template <typename Map>
1.274 GraphReader& readNodeMap(std::string name, Map& map) {
1.275 - return readNodeMap<typename ReaderTraits::template
1.276 - Reader<typename Map::Value>, Map>(name, map);
1.277 + nodeset_reader.readMap(name, map);
1.278 + return *this;
1.279 }
1.280
1.281 /// \brief Add a new node map reader command for the reader.
1.282 @@ -302,13 +175,7 @@
1.283 template <typename Reader, typename Map>
1.284 GraphReader& readNodeMap(std::string name, Map& map,
1.285 const Reader& reader = Reader()) {
1.286 - if (node_map_readers.find(name) != node_map_readers.end()) {
1.287 - ErrorMessage msg;
1.288 - msg << "Multiple read rule for node map: " << name;
1.289 - throw IOParameterError(msg.message());
1.290 - }
1.291 - node_map_readers.insert(
1.292 - make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
1.293 + nodeset_reader.readMap(name, map, reader);
1.294 return *this;
1.295 }
1.296
1.297 @@ -318,13 +185,7 @@
1.298 template <typename Reader>
1.299 GraphReader& skipNodeMap(std::string name,
1.300 const Reader& reader = Reader()) {
1.301 - if (node_map_readers.find(name) != node_map_readers.end()) {
1.302 - ErrorMessage msg;
1.303 - msg << "Multiple read rule for node map: " << name;
1.304 - throw IOParameterError(msg.message());
1.305 - }
1.306 - node_map_readers.insert(
1.307 - make_pair(name, new SkipReader<Node, Reader>(reader)));
1.308 + nodeset_reader.skipMap(name, reader);
1.309 return *this;
1.310 }
1.311
1.312 @@ -333,8 +194,8 @@
1.313 /// Add a new edge map reader command for the reader.
1.314 template <typename Map>
1.315 GraphReader& readEdgeMap(std::string name, Map& map) {
1.316 - return readEdgeMap<typename ReaderTraits::template
1.317 - Reader<typename Map::Value>, Map>(name, map);
1.318 + edgeset_reader.readMap(name, map);
1.319 + return *this;
1.320 }
1.321
1.322
1.323 @@ -344,13 +205,7 @@
1.324 template <typename Reader, typename Map>
1.325 GraphReader& readEdgeMap(std::string name, Map& map,
1.326 const Reader& reader = Reader()) {
1.327 - if (edge_map_readers.find(name) != edge_map_readers.end()) {
1.328 - ErrorMessage msg;
1.329 - msg << "Multiple read rule for edge map: " << name;
1.330 - throw IOParameterError(msg.message());
1.331 - }
1.332 - edge_map_readers.insert(
1.333 - make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
1.334 + edgeset_reader.readMap(name, map, reader);
1.335 return *this;
1.336 }
1.337
1.338 @@ -360,13 +215,8 @@
1.339 template <typename Reader>
1.340 GraphReader& skipEdgeMap(std::string name,
1.341 const Reader& reader = Reader()) {
1.342 - if (edge_map_readers.find(name) != edge_map_readers.end()) {
1.343 - ErrorMessage msg;
1.344 - msg << "Multiple read rule for edge map: " << name;
1.345 - throw IOParameterError(msg.message());
1.346 - }
1.347 - edge_map_readers.insert(
1.348 - make_pair(name, new SkipReader<Edge, Reader>(reader)));
1.349 +
1.350 + edgeset_reader.skipMap(name, reader);
1.351 return *this;
1.352 }
1.353
1.354 @@ -374,12 +224,7 @@
1.355 ///
1.356 /// Add a new labeled node reader for the reader.
1.357 GraphReader& readNode(std::string name, Node& node) {
1.358 - if (node_readers.find(name) != node_readers.end()) {
1.359 - ErrorMessage msg;
1.360 - msg << "Multiple read rule for node: " << name;
1.361 - throw IOParameterError(msg.message());
1.362 - }
1.363 - node_readers.insert(make_pair(name, &node));
1.364 + node_reader.readNode(name, node);
1.365 return *this;
1.366 }
1.367
1.368 @@ -387,385 +232,61 @@
1.369 ///
1.370 /// Add a new labeled edge reader for the reader.
1.371 GraphReader& readEdge(std::string name, Edge& edge) {
1.372 - if (edge_readers.find(name) != edge_readers.end()) {
1.373 - ErrorMessage msg;
1.374 - msg << "Multiple read rule for edge: " << name;
1.375 - throw IOParameterError(msg.message());
1.376 - }
1.377 - edge_readers.insert(make_pair(name, &edge));
1.378 + edge_reader.readEdge(name, edge);
1.379 + }
1.380 +
1.381 + /// \brief Add a new attribute reader command.
1.382 + ///
1.383 + /// Add a new attribute reader command.
1.384 + template <typename Value>
1.385 + GraphReader& readAttribute(std::string name, Value& value) {
1.386 + attribute_reader.readAttribute(name, value);
1.387 return *this;
1.388 }
1.389 +
1.390 + /// \brief Add a new attribute reader command.
1.391 + ///
1.392 + /// Add a new attribute reader command.
1.393 + template <typename Reader, typename Value>
1.394 + GraphReader& readAttribute(std::string name, Value& value,
1.395 + const Reader& reader) {
1.396 + attribute_reader.readAttribute<Reader>(name, value, reader);
1.397 + return *this;
1.398 + }
1.399 +
1.400 + /// \brief Conversion operator to LemonReader.
1.401 + ///
1.402 + /// Conversion operator to LemonReader. It make possible
1.403 + /// to access the encapsulated \e LemonReader, this way
1.404 + /// you can attach to this reader new instances of
1.405 + /// \e LemonReader::SectionReader.
1.406 + operator LemonReader&() {
1.407 + return *reader;
1.408 + }
1.409
1.410 /// \brief Executes the reader commands.
1.411 ///
1.412 /// Executes the reader commands.
1.413 void run() {
1.414 - int line_num = 0;
1.415 - std::auto_ptr<InverterBase<Node> > nodeInverter;
1.416 - std::auto_ptr<InverterBase<Edge> > edgeInverter;
1.417 - try {
1.418 - std::string line = readNotEmptyLine(is, line_num);
1.419 - if (line.find("@nodeset") == 0) {
1.420 - line = readNodeSet(line_num, nodeInverter);
1.421 - }
1.422 - if (line.find("@edgeset") == 0) {
1.423 - line = readEdgeSet(line_num, edgeInverter, nodeInverter);
1.424 - }
1.425 - if (line.find("@nodes") == 0) {
1.426 - line = readNodes(line_num, nodeInverter);
1.427 - }
1.428 - if (line.find("@edges") == 0) {
1.429 - line = readEdges(line_num, edgeInverter);
1.430 - }
1.431 - if (line.find("@gui") == 0) {
1.432 - line = readGUI(line_num);
1.433 - }
1.434 - if (line.find("@end") != 0) {
1.435 - throw DataFormatError("Invalid control sequence error");
1.436 - }
1.437 - } catch (DataFormatError e) {
1.438 - e.line(line_num);
1.439 - throw e;
1.440 - }
1.441 - }
1.442 -
1.443 - GraphReader& readGUI(GUIReader& reader) {
1.444 - gui_reader = &reader;
1.445 - return *this;
1.446 + reader->run();
1.447 }
1.448
1.449 private:
1.450
1.451 - template <typename Item> class InverterBase;
1.452 + LemonReader* reader;
1.453 + bool own_reader;
1.454
1.455 - std::string readNodeSet(int& line_num,
1.456 - std::auto_ptr<InverterBase<Node> >& nodeInverter) {
1.457 - std::vector<ReaderBase<Node>* > index;
1.458 - {
1.459 - std::string line = readNotEmptyLine(is, line_num);
1.460 - std::string id;
1.461 - std::istringstream ls(line);
1.462 - while (ls >> id) {
1.463 - typename NodeMapReaders::iterator it = node_map_readers.find(id);
1.464 - if (it != node_map_readers.end()) {
1.465 - index.push_back(it->second);
1.466 - node_map_readers.erase(it);
1.467 - } else {
1.468 - index.push_back(&nodeSkipper);
1.469 - }
1.470 - if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
1.471 - nodeInverter.reset(index.back()->getInverter());
1.472 - index.back() = nodeInverter.get();
1.473 - }
1.474 - }
1.475 - }
1.476 -
1.477 -// if (index.size() == 0) {
1.478 -// throw DataFormatError("Cannot find node id map");
1.479 -// }
1.480 -
1.481 -// nodeInverter =
1.482 -// std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
1.483 - std::string line;
1.484 - while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.485 - Node node = graph.addNode();
1.486 - std::istringstream ls(line);
1.487 - for (int i = 0; i < (int)index.size(); ++i) {
1.488 - index[i]->read(ls, node);
1.489 - }
1.490 - }
1.491 - return line;
1.492 - }
1.493 -
1.494 - std::string readEdgeSet(int& line_num,
1.495 - std::auto_ptr<InverterBase<Edge> >& edgeInverter,
1.496 - std::auto_ptr<InverterBase<Node> >& nodeInverter) {
1.497 - std::vector<ReaderBase<Edge>*> index;
1.498 - {
1.499 - std::string line = readNotEmptyLine(is, line_num);
1.500 - std::string id;
1.501 - std::istringstream ls(line);
1.502 - while (ls >> id) {
1.503 - typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
1.504 - if (it != edge_map_readers.end()) {
1.505 - index.push_back(it->second);
1.506 - edge_map_readers.erase(it);
1.507 - } else {
1.508 - index.push_back(&edgeSkipper);
1.509 - }
1.510 - if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
1.511 - edgeInverter.reset(index.back()->getInverter());
1.512 - index.back() = edgeInverter.get();
1.513 - }
1.514 - }
1.515 - }
1.516 -
1.517 - if (nodeInverter.get() == 0) {
1.518 - throw DataFormatError("Cannot find node id map");
1.519 - }
1.520 -// if (index.size() == 0) {
1.521 -// throw DataFormatError("Cannot find edge id map");
1.522 -// }
1.523 -
1.524 -// edgeInverter =
1.525 -// std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
1.526 - std::string line;
1.527 - while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.528 - std::istringstream ls(line);
1.529 - Node source = nodeInverter->read(ls);
1.530 - Node target = nodeInverter->read(ls);
1.531 - Edge edge = graph.addEdge(source, target);
1.532 - for (int i = 0; i < (int)index.size(); ++i) {
1.533 - index[i]->read(ls, edge);
1.534 - }
1.535 - }
1.536 - return line;
1.537 - }
1.538 -
1.539 - std::string readNodes(int& line_num,
1.540 - std::auto_ptr<InverterBase<Node> >& nodeInverter) {
1.541 - std::string line;
1.542 - if (nodeInverter.get() == 0) {
1.543 - throw DataFormatError("Cannot find node id map");
1.544 - }
1.545 - while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.546 - std::istringstream ls(line);
1.547 - std::string name;
1.548 - ls >> name;
1.549 - typename NodeReaders::iterator it = node_readers.find(name);
1.550 - if (it != node_readers.end()) {
1.551 - *(it -> second) = nodeInverter->read(ls);
1.552 - }
1.553 - }
1.554 - return line;
1.555 - }
1.556 -
1.557 - std::string readEdges(int& line_num,
1.558 - std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
1.559 - std::string line;
1.560 - if (edgeInverter.get() == 0) {
1.561 - throw DataFormatError("Cannot find edge id map");
1.562 - }
1.563 - while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.564 - std::istringstream ls(line);
1.565 - std::string name;
1.566 - ls >> name;
1.567 - typename EdgeReaders::iterator it = edge_readers.find(name);
1.568 - if (it != edge_readers.end()) {
1.569 - *(it -> second) = edgeInverter->read(ls);
1.570 - }
1.571 - }
1.572 - return line;
1.573 - }
1.574 -
1.575 - std::string readGUI(int& line_num) {
1.576 - std::stringstream section;
1.577 - std::string line;
1.578 - while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.579 - section << line << std::endl;
1.580 - }
1.581 - if (gui_reader != 0) {
1.582 - gui_reader->read(section);
1.583 - }
1.584 - return line;
1.585 - }
1.586 -
1.587 - std::string readNotEmptyLine(std::istream& is, int& line_num) {
1.588 - std::string line;
1.589 - while (++line_num, getline(is, line)) {
1.590 - int vi = line.find('#');
1.591 - if (vi != (int)::std::string::npos) {
1.592 - line = line.substr(0, vi);
1.593 - }
1.594 - vi = line.find_first_not_of(" \t");
1.595 - if (vi != (int)std::string::npos) {
1.596 - return line.substr(vi);
1.597 - }
1.598 - }
1.599 - throw DataFormatError("End of stream error");
1.600 - }
1.601 -
1.602 - template <typename _Item>
1.603 - class ReaderBase;
1.604 -
1.605 - template <typename _Item>
1.606 - class InverterBase : public ReaderBase<_Item> {
1.607 - public:
1.608 - typedef _Item Item;
1.609 - virtual void read(std::istream&, const Item&) = 0;
1.610 - virtual Item read(std::istream&) = 0;
1.611 -
1.612 - virtual InverterBase<_Item>* getInverter() {
1.613 - return this;
1.614 - }
1.615 - };
1.616 -
1.617 - template <typename _Item, typename _Map, typename _Reader>
1.618 - class MapReaderInverter : public InverterBase<_Item> {
1.619 - public:
1.620 - typedef _Item Item;
1.621 - typedef _Reader Reader;
1.622 - typedef typename Reader::Value Value;
1.623 - typedef _Map Map;
1.624 - typedef std::map<Value, Item> Inverse;
1.625 -
1.626 - Map& map;
1.627 - Reader reader;
1.628 - Inverse inverse;
1.629 -
1.630 - MapReaderInverter(Map& _map, const Reader& _reader)
1.631 - : map(_map), reader(_reader) {}
1.632 -
1.633 - virtual ~MapReaderInverter() {}
1.634 -
1.635 - virtual void read(std::istream& is, const Item& item) {
1.636 - Value value;
1.637 - reader.read(is, value);
1.638 - map.set(item, value);
1.639 - typename Inverse::iterator it = inverse.find(value);
1.640 - if (it == inverse.end()) {
1.641 - inverse.insert(std::make_pair(value, item));
1.642 - } else {
1.643 - throw DataFormatError("Multiple ID occurence");
1.644 - }
1.645 - }
1.646 -
1.647 - virtual Item read(std::istream& is) {
1.648 - Value value;
1.649 - reader.read(is, value);
1.650 - typename Inverse::const_iterator it = inverse.find(value);
1.651 - if (it != inverse.end()) {
1.652 - return it->second;
1.653 - } else {
1.654 - throw DataFormatError("Invalid ID error");
1.655 - }
1.656 - }
1.657 - };
1.658 -
1.659 - template <typename _Item, typename _Reader>
1.660 - class SkipReaderInverter : public InverterBase<_Item> {
1.661 - public:
1.662 - typedef _Item Item;
1.663 - typedef _Reader Reader;
1.664 - typedef typename Reader::Value Value;
1.665 - typedef std::map<Value, Item> Inverse;
1.666 -
1.667 - Reader reader;
1.668 -
1.669 - SkipReaderInverter(const Reader& _reader)
1.670 - : reader(_reader) {}
1.671 -
1.672 - virtual ~SkipReaderInverter() {}
1.673 -
1.674 - virtual void read(std::istream& is, const Item& item) {
1.675 - Value value;
1.676 - reader.read(is, value);
1.677 - typename Inverse::iterator it = inverse.find(value);
1.678 - if (it == inverse.end()) {
1.679 - inverse.insert(std::make_pair(value, item));
1.680 - } else {
1.681 - throw DataFormatError("Multiple ID occurence error");
1.682 - }
1.683 - }
1.684 -
1.685 - virtual Item read(std::istream& is) {
1.686 - Value value;
1.687 - reader.read(is, value);
1.688 - typename Inverse::const_iterator it = inverse.find(value);
1.689 - if (it != inverse.end()) {
1.690 - return it->second;
1.691 - } else {
1.692 - throw DataFormatError("Invalid ID error");
1.693 - }
1.694 - }
1.695 - private:
1.696 - Inverse inverse;
1.697 - };
1.698 -
1.699 - // Readers
1.700 -
1.701 - template <typename _Item>
1.702 - class ReaderBase {
1.703 - public:
1.704 - typedef _Item Item;
1.705 -
1.706 - // virtual ~ReaderBase() {}
1.707 -
1.708 - virtual void read(std::istream& is, const Item& item) = 0;
1.709 - virtual InverterBase<_Item>* getInverter() = 0;
1.710 - };
1.711 -
1.712 - template <typename _Item, typename _Map, typename _Reader>
1.713 - class MapReader : public ReaderBase<_Item> {
1.714 - public:
1.715 - typedef _Map Map;
1.716 - typedef _Reader Reader;
1.717 - typedef typename Reader::Value Value;
1.718 - typedef _Item Item;
1.719 -
1.720 - Map& map;
1.721 - Reader reader;
1.722 -
1.723 - MapReader(Map& _map, const Reader& _reader)
1.724 - : map(_map), reader(_reader) {}
1.725 -
1.726 - virtual ~MapReader() {}
1.727 -
1.728 - virtual void read(std::istream& is, const Item& item) {
1.729 - Value value;
1.730 - reader.read(is, value);
1.731 - map.set(item, value);
1.732 - }
1.733 -
1.734 - virtual InverterBase<_Item>* getInverter() {
1.735 - return new MapReaderInverter<Item, Map, Reader>(map, reader);
1.736 - }
1.737 - };
1.738 -
1.739 -
1.740 - template <typename _Item, typename _Reader>
1.741 - class SkipReader : public ReaderBase<_Item> {
1.742 - public:
1.743 - typedef _Reader Reader;
1.744 - typedef typename Reader::Value Value;
1.745 - typedef _Item Item;
1.746 -
1.747 - Reader reader;
1.748 - SkipReader(const Reader& _reader) : reader(_reader) {}
1.749 -
1.750 - virtual ~SkipReader() {}
1.751 -
1.752 - virtual void read(std::istream& is, const Item&) {
1.753 - Value value;
1.754 - reader.read(is, value);
1.755 - }
1.756 -
1.757 - virtual InverterBase<Item>* getInverter() {
1.758 - return new SkipReaderInverter<Item, Reader>(reader);
1.759 - }
1.760 - };
1.761 -
1.762 -
1.763 - typedef std::map<std::string, ReaderBase<Node>*> NodeMapReaders;
1.764 - NodeMapReaders node_map_readers;
1.765 -
1.766 - typedef std::map<std::string, ReaderBase<Edge>*> EdgeMapReaders;
1.767 - EdgeMapReaders edge_map_readers;
1.768 -
1.769 - typedef std::map<std::string, Node*> NodeReaders;
1.770 - NodeReaders node_readers;
1.771 -
1.772 - typedef std::map<std::string, Edge*> EdgeReaders;
1.773 - EdgeReaders edge_readers;
1.774 -
1.775 - GUIReader* gui_reader;
1.776 -
1.777 - std::istream& is;
1.778 Graph& graph;
1.779
1.780 - SkipReader<Node, DefaultReader> nodeSkipper;
1.781 - SkipReader<Edge, DefaultReader> edgeSkipper;
1.782 + DefaultSkipper skipper;
1.783
1.784 + NodeSetReader<Graph, ReaderTraits> nodeset_reader;
1.785 + EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
1.786 +
1.787 + NodeReader<Graph> node_reader;
1.788 + EdgeReader<Graph> edge_reader;
1.789 +
1.790 + AttributeReader<ReaderTraits> attribute_reader;
1.791 };
1.792
1.793 /// \brief Read a graph from the input.