1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/lemon/lemon_reader.h Mon May 09 11:24:26 2005 +0000
1.3 @@ -0,0 +1,977 @@
1.4 +/* -*- C++ -*-
1.5 + * src/lemon/lemon_reader.h - Part of LEMON, a generic C++ optimization library
1.6 + *
1.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.9 + *
1.10 + * Permission to use, modify and distribute this software is granted
1.11 + * provided that this copyright notice appears in all copies. For
1.12 + * precise terms see the accompanying LICENSE file.
1.13 + *
1.14 + * This software is provided "AS IS" with no warranty of any kind,
1.15 + * express or implied, and with no claim as to its suitability for any
1.16 + * purpose.
1.17 + *
1.18 + */
1.19 +
1.20 +///\ingroup io_group
1.21 +///\file
1.22 +///\brief Lemon Format reader.
1.23 +
1.24 +#ifndef LEMON_LEMON_READER_H
1.25 +#define LEMON_LEMON_READER_H
1.26 +
1.27 +#include <iostream>
1.28 +#include <fstream>
1.29 +#include <string>
1.30 +#include <vector>
1.31 +#include <algorithm>
1.32 +#include <map>
1.33 +#include <memory>
1.34 +
1.35 +#include <lemon/error.h>
1.36 +#include "item_reader.h"
1.37 +
1.38 +
1.39 +namespace lemon {
1.40 +
1.41 + /// \addtogroup io_group
1.42 + /// @{
1.43 +
1.44 + /// \brief Lemon Format reader class.
1.45 + ///
1.46 + class LemonReader {
1.47 + private:
1.48 +
1.49 + class FilterStreamBuf : public std::streambuf {
1.50 + public:
1.51 +
1.52 + typedef std::streambuf Parent;
1.53 + typedef Parent::char_type char_type;
1.54 + FilterStreamBuf(std::istream& is, int& num)
1.55 + : _is(is), _base(0), _eptr(0),
1.56 + _num(num), skip_state(after_endl) {}
1.57 +
1.58 + protected:
1.59 +
1.60 + enum skip_state_type {
1.61 + no_skip,
1.62 + after_comment,
1.63 + after_endl,
1.64 + empty_line
1.65 + };
1.66 +
1.67 + char_type small_buf[1];
1.68 +
1.69 +
1.70 + std::istream& _is;
1.71 +
1.72 + char_type* _base;
1.73 + char_type* _eptr;
1.74 +
1.75 + int& _num;
1.76 +
1.77 + skip_state_type skip_state;
1.78 +
1.79 +
1.80 + char_type* base() { return _base; }
1.81 +
1.82 + char_type* eptr() { return _eptr; }
1.83 +
1.84 + int blen() { return _eptr - _base; }
1.85 +
1.86 + void setb(char_type* buf, int len) {
1.87 + _base = buf;
1.88 + _eptr = buf + len;
1.89 + }
1.90 +
1.91 + virtual std::streambuf* setbuf(char *buf, int len) {
1.92 + if (base()) return 0;
1.93 + if (buf != 0 && len >= (int)sizeof(small_buf)) {
1.94 + setb(buf, len);
1.95 + } else {
1.96 + setb(small_buf, sizeof(small_buf));
1.97 + }
1.98 + setg(0, 0, 0);
1.99 + return this;
1.100 + }
1.101 +
1.102 + bool put_char(char c) {
1.103 + switch (skip_state) {
1.104 + case no_skip:
1.105 + switch (c) {
1.106 + case '\n':
1.107 + skip_state = after_endl;
1.108 + return true;
1.109 + case '#':
1.110 + skip_state = after_comment;
1.111 + return false;
1.112 + default:
1.113 + return true;
1.114 + }
1.115 + case after_comment:
1.116 + switch (c) {
1.117 + case '\n':
1.118 + skip_state = after_endl;
1.119 + return true;
1.120 + default:
1.121 + return false;
1.122 + }
1.123 + case after_endl:
1.124 + switch (c) {
1.125 + case '@':
1.126 + return false;
1.127 + case '\n':
1.128 + return false;
1.129 + case '#':
1.130 + skip_state = empty_line;
1.131 + return false;
1.132 + default:
1.133 + if (!isspace(c)) {
1.134 + skip_state = no_skip;
1.135 + return true;
1.136 + } else {
1.137 + return false;
1.138 + }
1.139 + }
1.140 + break;
1.141 + case empty_line:
1.142 + switch (c) {
1.143 + case '\n':
1.144 + skip_state = after_endl;
1.145 + return false;
1.146 + default:
1.147 + return false;
1.148 + }
1.149 + }
1.150 + return false;
1.151 + }
1.152 +
1.153 + virtual int underflow() {
1.154 + char c;
1.155 + if (_is.read(&c, 1)) {
1.156 + _is.putback(c);
1.157 + if (c == '@') {
1.158 + return EOF;
1.159 + }
1.160 + } else {
1.161 + return EOF;
1.162 + }
1.163 + char_type *ptr;
1.164 + for (ptr = base(); ptr != eptr(); ++ptr) {
1.165 + if (_is.read(&c, 1)) {
1.166 + if (c == '\n') ++_num;
1.167 + if (put_char(c)) {
1.168 + *ptr = c;
1.169 + } else {
1.170 + if (skip_state == after_endl && c == '@') {
1.171 + _is.putback('@');
1.172 + break;
1.173 + }
1.174 + --ptr;
1.175 + }
1.176 + } else {
1.177 + break;
1.178 + }
1.179 + }
1.180 + setg(base(), base(), ptr);
1.181 + return *base();
1.182 + }
1.183 +
1.184 + virtual int sync() {
1.185 + return EOF;
1.186 + }
1.187 + };
1.188 +
1.189 + public:
1.190 +
1.191 + class SectionReader {
1.192 + public:
1.193 + /// \e
1.194 + virtual bool header(const std::string& line) = 0;
1.195 + /// \e
1.196 + virtual void read(std::istream& is) = 0;
1.197 + };
1.198 +
1.199 + /// \e
1.200 + LemonReader(std::istream& _is)
1.201 + : is(&_is), own_is(false) {}
1.202 +
1.203 + LemonReader(const std::string& filename)
1.204 + : is(0), own_is(true) {
1.205 + is = new std::ifstream(filename.c_str());
1.206 + }
1.207 +
1.208 +
1.209 + ~LemonReader() {
1.210 + if (own_is) {
1.211 + delete is;
1.212 + }
1.213 + }
1.214 +
1.215 + private:
1.216 + LemonReader(const LemonReader&);
1.217 + void operator=(const LemonReader&);
1.218 +
1.219 + public:
1.220 +
1.221 + /// \e
1.222 + void attach(SectionReader& reader) {
1.223 + readers.push_back(&reader);
1.224 + }
1.225 +
1.226 + /// \e
1.227 + void detach(SectionReader& reader) {
1.228 + std::vector<SectionReader*>::iterator it =
1.229 + std::find(readers.begin(), readers.end(), &reader);
1.230 + if (it != readers.end()) {
1.231 + readers.erase(it);
1.232 + }
1.233 + }
1.234 +
1.235 + /// \e
1.236 + void run() {
1.237 + int line_num = 0;
1.238 + std::string line;
1.239 + try {
1.240 + while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
1.241 + SectionReaders::iterator it;
1.242 + for (it = readers.begin(); it != readers.end(); ++it) {
1.243 + if ((*it)->header(line)) {
1.244 + char buf[2048];
1.245 + FilterStreamBuf buffer(*is, line_num);
1.246 + buffer.pubsetbuf(buf, sizeof(buf));
1.247 + std::istream is(&buffer);
1.248 + (*it)->read(is);
1.249 + break;
1.250 + }
1.251 + }
1.252 + }
1.253 + } catch (DataFormatError& error) {
1.254 + error.line(line_num);
1.255 + throw error;
1.256 + }
1.257 + }
1.258 +
1.259 +
1.260 + private:
1.261 +
1.262 + std::istream* is;
1.263 + bool own_is;
1.264 +
1.265 + typedef std::vector<SectionReader*> SectionReaders;
1.266 + SectionReaders readers;
1.267 +
1.268 + };
1.269 +
1.270 +
1.271 + /// \e
1.272 + class CommonSectionReaderBase : public LemonReader::SectionReader {
1.273 + protected:
1.274 + template <typename _Item>
1.275 + class ReaderBase;
1.276 +
1.277 + template <typename _Item>
1.278 + class InverterBase : public ReaderBase<_Item> {
1.279 + public:
1.280 + typedef _Item Item;
1.281 + virtual void read(std::istream&, const Item&) = 0;
1.282 + virtual Item read(std::istream&) const = 0;
1.283 +
1.284 + virtual InverterBase<_Item>* getInverter() {
1.285 + return this;
1.286 + }
1.287 +
1.288 +
1.289 + };
1.290 +
1.291 + template <typename _Item, typename _Map, typename _Reader>
1.292 + class MapReaderInverter : public InverterBase<_Item> {
1.293 + public:
1.294 + typedef _Item Item;
1.295 + typedef _Reader Reader;
1.296 + typedef typename Reader::Value Value;
1.297 + typedef _Map Map;
1.298 + typedef std::map<Value, Item> Inverse;
1.299 +
1.300 + Map& map;
1.301 + Reader reader;
1.302 + Inverse inverse;
1.303 +
1.304 + MapReaderInverter(Map& _map, const Reader& _reader)
1.305 + : map(_map), reader(_reader) {}
1.306 +
1.307 + virtual ~MapReaderInverter() {}
1.308 +
1.309 + virtual void read(std::istream& is, const Item& item) {
1.310 + Value value;
1.311 + reader.read(is, value);
1.312 + map.set(item, value);
1.313 + typename Inverse::iterator it = inverse.find(value);
1.314 + if (it == inverse.end()) {
1.315 + inverse.insert(std::make_pair(value, item));
1.316 + } else {
1.317 + throw DataFormatError("Multiple ID occurence");
1.318 + }
1.319 + }
1.320 +
1.321 + virtual Item read(std::istream& is) const {
1.322 + Value value;
1.323 + reader.read(is, value);
1.324 + typename Inverse::const_iterator it = inverse.find(value);
1.325 + if (it != inverse.end()) {
1.326 + return it->second;
1.327 + } else {
1.328 + throw DataFormatError("Invalid ID error");
1.329 + }
1.330 + }
1.331 +
1.332 + };
1.333 +
1.334 + template <typename _Item, typename _Reader>
1.335 + class SkipReaderInverter : public InverterBase<_Item> {
1.336 + public:
1.337 + typedef _Item Item;
1.338 + typedef _Reader Reader;
1.339 + typedef typename Reader::Value Value;
1.340 + typedef std::map<Value, Item> Inverse;
1.341 +
1.342 + Reader reader;
1.343 +
1.344 + SkipReaderInverter(const Reader& _reader)
1.345 + : reader(_reader) {}
1.346 +
1.347 + virtual ~SkipReaderInverter() {}
1.348 +
1.349 + virtual void read(std::istream& is, const Item& item) {
1.350 + Value value;
1.351 + reader.read(is, value);
1.352 + typename Inverse::iterator it = inverse.find(value);
1.353 + if (it == inverse.end()) {
1.354 + inverse.insert(std::make_pair(value, item));
1.355 + } else {
1.356 + throw DataFormatError("Multiple ID occurence error");
1.357 + }
1.358 + }
1.359 +
1.360 + virtual Item read(std::istream& is) const {
1.361 + Value value;
1.362 + reader.read(is, value);
1.363 + typename Inverse::const_iterator it = inverse.find(value);
1.364 + if (it != inverse.end()) {
1.365 + return it->second;
1.366 + } else {
1.367 + throw DataFormatError("Invalid ID error");
1.368 + }
1.369 + }
1.370 +
1.371 + private:
1.372 + Inverse inverse;
1.373 + };
1.374 +
1.375 + // Readers
1.376 +
1.377 + template <typename _Item>
1.378 + class ReaderBase {
1.379 + public:
1.380 + typedef _Item Item;
1.381 +
1.382 + virtual ~ReaderBase() {}
1.383 +
1.384 + virtual void read(std::istream& is, const Item& item) = 0;
1.385 + virtual InverterBase<_Item>* getInverter() = 0;
1.386 + };
1.387 +
1.388 + template <typename _Item, typename _Map, typename _Reader>
1.389 + class MapReader : public ReaderBase<_Item> {
1.390 + public:
1.391 + typedef _Map Map;
1.392 + typedef _Reader Reader;
1.393 + typedef typename Reader::Value Value;
1.394 + typedef _Item Item;
1.395 +
1.396 + Map& map;
1.397 + Reader reader;
1.398 +
1.399 + MapReader(Map& _map, const Reader& _reader)
1.400 + : map(_map), reader(_reader) {}
1.401 +
1.402 + virtual ~MapReader() {}
1.403 +
1.404 + virtual void read(std::istream& is, const Item& item) {
1.405 + Value value;
1.406 + reader.read(is, value);
1.407 + map.set(item, value);
1.408 + }
1.409 +
1.410 + virtual InverterBase<_Item>* getInverter() {
1.411 + return new MapReaderInverter<Item, Map, Reader>(map, reader);
1.412 + }
1.413 + };
1.414 +
1.415 +
1.416 + template <typename _Item, typename _Reader>
1.417 + class SkipReader : public ReaderBase<_Item> {
1.418 + public:
1.419 + typedef _Reader Reader;
1.420 + typedef typename Reader::Value Value;
1.421 + typedef _Item Item;
1.422 +
1.423 + Reader reader;
1.424 + SkipReader(const Reader& _reader) : reader(_reader) {}
1.425 +
1.426 + virtual ~SkipReader() {}
1.427 +
1.428 + virtual void read(std::istream& is, const Item&) {
1.429 + Value value;
1.430 + reader.read(is, value);
1.431 + }
1.432 +
1.433 + virtual InverterBase<Item>* getInverter() {
1.434 + return new SkipReaderInverter<Item, Reader>(reader);
1.435 + }
1.436 + };
1.437 +
1.438 + template <typename _Item>
1.439 + class ResolverReaderBase {
1.440 + public:
1.441 + typedef _Item Item;
1.442 + virtual Item resolve(std::istream& is) const = 0;
1.443 + };
1.444 +
1.445 + template <typename _Item, typename _Resolver>
1.446 + class ResolverReader : public ResolverReaderBase<_Item> {
1.447 + public:
1.448 + typedef _Item Item;
1.449 + typedef _Resolver Resolver;
1.450 +
1.451 + const Resolver& resolver;
1.452 +
1.453 + ResolverReader(const Resolver& _resolver)
1.454 + : resolver(_resolver) {}
1.455 +
1.456 + virtual Item resolve(std::istream& is) const {
1.457 + return resolver.resolve(is);
1.458 + }
1.459 + };
1.460 +
1.461 + class ValueReaderBase {
1.462 + public:
1.463 + virtual void read(std::istream&) {};
1.464 + };
1.465 +
1.466 + template <typename _Value, typename _Reader>
1.467 + class ValueReader : public ValueReaderBase {
1.468 + public:
1.469 + typedef _Value Value;
1.470 + typedef _Reader Reader;
1.471 +
1.472 + ValueReader(Value& _value, const Reader& _reader)
1.473 + : value(_value), reader(_reader) {}
1.474 +
1.475 + virtual void read(std::istream& is) {
1.476 + reader.read(is, value);
1.477 + }
1.478 + private:
1.479 + Value& value;
1.480 + Reader reader;
1.481 + };
1.482 +
1.483 + };
1.484 +
1.485 +
1.486 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.487 + class NodeSetReader : public CommonSectionReaderBase {
1.488 + typedef CommonSectionReaderBase Parent;
1.489 + public:
1.490 +
1.491 + typedef _Graph Graph;
1.492 + typedef _Traits Traits;
1.493 + typedef typename Graph::Node Item;
1.494 + typedef typename Traits::Skipper DefaultSkipper;
1.495 +
1.496 + NodeSetReader(LemonReader& _reader, Graph& _graph,
1.497 + const std::string& _id = std::string(),
1.498 + const DefaultSkipper& _defreader = DefaultSkipper())
1.499 + : graph(_graph), id(_id), skipper(_defreader) {
1.500 + _reader.attach(*this);
1.501 + }
1.502 +
1.503 + virtual ~NodeSetReader() {
1.504 + for (typename MapReaders::iterator it = readers.begin();
1.505 + it != readers.end(); ++it) {
1.506 + delete it->second;
1.507 + }
1.508 + }
1.509 +
1.510 + private:
1.511 + NodeSetReader(const NodeSetReader&);
1.512 + void operator=(const NodeSetReader&);
1.513 +
1.514 + public:
1.515 +
1.516 + /// \brief Add a new node map reader command for the reader.
1.517 + ///
1.518 + /// Add a new node map reader command for the reader.
1.519 + template <typename Map>
1.520 + NodeSetReader& readMap(std::string name, Map& map) {
1.521 + return readMap<typename Traits::
1.522 + template Reader<typename Map::Value>, Map>(name, map);
1.523 + }
1.524 +
1.525 + /// \brief Add a new node map reader command for the reader.
1.526 + ///
1.527 + /// Add a new node map reader command for the reader.
1.528 + template <typename Reader, typename Map>
1.529 + NodeSetReader& readMap(std::string name, Map& map,
1.530 + const Reader& reader = Reader()) {
1.531 + if (readers.find(name) != readers.end()) {
1.532 + ErrorMessage msg;
1.533 + msg << "Multiple read rule for node map: " << name;
1.534 + throw IOParameterError(msg.message());
1.535 + }
1.536 + readers.insert(
1.537 + make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
1.538 + return *this;
1.539 + }
1.540 +
1.541 + /// \brief Add a new node map skipper command for the reader.
1.542 + ///
1.543 + /// Add a new node map skipper command for the reader.
1.544 + template <typename Reader>
1.545 + NodeSetReader& skipMap(std::string name,
1.546 + const Reader& reader = Reader()) {
1.547 + if (readers.find(name) != readers.end()) {
1.548 + ErrorMessage msg;
1.549 + msg << "Multiple read rule for node map: " << name;
1.550 + throw IOParameterError(msg.message());
1.551 + }
1.552 + readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
1.553 + return *this;
1.554 + }
1.555 +
1.556 + /// \e
1.557 + virtual bool header(const std::string& line) {
1.558 + std::istringstream ls(line);
1.559 + std::string command;
1.560 + std::string name;
1.561 + ls >> command >> name;
1.562 + return command == "@nodeset" && name == id;
1.563 + }
1.564 +
1.565 + /// \e
1.566 + virtual void read(std::istream& is) {
1.567 + std::vector<ReaderBase<Item>* > index;
1.568 + std::string line;
1.569 +
1.570 + getline(is, line);
1.571 + std::istringstream ls(line);
1.572 + while (ls >> id) {
1.573 + typename MapReaders::iterator it = readers.find(id);
1.574 + if (it != readers.end()) {
1.575 + index.push_back(it->second);
1.576 + } else {
1.577 + index.push_back(&skipper);
1.578 + }
1.579 + if (id == "id" && inverter.get() == 0) {
1.580 + inverter.reset(index.back()->getInverter());
1.581 + index.back() = inverter.get();
1.582 + }
1.583 + }
1.584 + while (getline(is, line)) {
1.585 + typename Graph::Node node = graph.addNode();
1.586 + std::istringstream ls(line);
1.587 + for (int i = 0; i < (int)index.size(); ++i) {
1.588 + index[i]->read(ls, node);
1.589 + }
1.590 + }
1.591 + }
1.592 +
1.593 + bool isResolver() const {
1.594 + return inverter.get() != 0;
1.595 + }
1.596 +
1.597 + typename Graph::Node resolve(std::istream& is) const {
1.598 + return inverter->read(is);
1.599 + }
1.600 +
1.601 + private:
1.602 +
1.603 + typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
1.604 + MapReaders readers;
1.605 +
1.606 + Graph& graph;
1.607 + std::string id;
1.608 + SkipReader<Item, DefaultSkipper> skipper;
1.609 +
1.610 + std::auto_ptr<InverterBase<Item> > inverter;
1.611 + };
1.612 +
1.613 +
1.614 +
1.615 + /// \e
1.616 + template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.617 + class EdgeSetReader : public CommonSectionReaderBase {
1.618 + typedef CommonSectionReaderBase Parent;
1.619 + public:
1.620 +
1.621 + typedef _Graph Graph;
1.622 + typedef _Traits Traits;
1.623 + typedef typename Graph::Edge Item;
1.624 + typedef typename Traits::Skipper DefaultSkipper;
1.625 +
1.626 + template <typename Resolver>
1.627 + EdgeSetReader(LemonReader& _reader, Graph& _graph,
1.628 + const Resolver& _nodeResolver,
1.629 + const std::string& _id = std::string(),
1.630 + const DefaultSkipper& _defreader = DefaultSkipper())
1.631 + : graph(_graph), id(_id), skipper(_defreader),
1.632 + nodeResolver(new ResolverReader<typename Graph::Node, Resolver>
1.633 + (_nodeResolver)) {
1.634 + _reader.attach(*this);
1.635 + }
1.636 +
1.637 + virtual ~EdgeSetReader() {
1.638 + for (typename MapReaders::iterator it = readers.begin();
1.639 + it != readers.end(); ++it) {
1.640 + delete it->second;
1.641 + }
1.642 + }
1.643 +
1.644 + private:
1.645 + EdgeSetReader(const EdgeSetReader&);
1.646 + void operator=(const EdgeSetReader&);
1.647 +
1.648 + public:
1.649 +
1.650 + /// \brief Add a new node map reader command for the reader.
1.651 + ///
1.652 + /// Add a new node map reader command for the reader.
1.653 + template <typename Map>
1.654 + EdgeSetReader& readMap(std::string name, Map& map) {
1.655 + return readMap<typename Traits::
1.656 + template Reader<typename Map::Value>, Map>(name, map);
1.657 + }
1.658 +
1.659 + /// \brief Add a new node map reader command for the reader.
1.660 + ///
1.661 + /// Add a new node map reader command for the reader.
1.662 + template <typename Reader, typename Map>
1.663 + EdgeSetReader& readMap(std::string name, Map& map,
1.664 + const Reader& reader = Reader()) {
1.665 + if (readers.find(name) != readers.end()) {
1.666 + ErrorMessage msg;
1.667 + msg << "Multiple read rule for edge map: " << name;
1.668 + throw IOParameterError(msg.message());
1.669 + }
1.670 + readers.insert(
1.671 + make_pair(name, new MapReader<Item, Map, Reader>(map, reader)));
1.672 + return *this;
1.673 + }
1.674 +
1.675 + /// \brief Add a new node map skipper command for the reader.
1.676 + ///
1.677 + /// Add a new node map skipper command for the reader.
1.678 + template <typename Reader>
1.679 + EdgeSetReader& skipMap(std::string name,
1.680 + const Reader& reader = Reader()) {
1.681 + if (readers.find(name) != readers.end()) {
1.682 + ErrorMessage msg;
1.683 + msg << "Multiple read rule for node map: " << name;
1.684 + throw IOParameterError(msg.message());
1.685 + }
1.686 + readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader)));
1.687 + return *this;
1.688 + }
1.689 +
1.690 + /// \e
1.691 + virtual bool header(const std::string& line) {
1.692 + std::istringstream ls(line);
1.693 + std::string command;
1.694 + std::string name;
1.695 + ls >> command >> name;
1.696 + return command == "@edgeset" && name == id;
1.697 + }
1.698 +
1.699 + /// \e
1.700 + virtual void read(std::istream& is) {
1.701 + std::vector<ReaderBase<Item>* > index;
1.702 + std::string line;
1.703 +
1.704 + getline(is, line);
1.705 + std::istringstream ls(line);
1.706 + while (ls >> id) {
1.707 + typename MapReaders::iterator it = readers.find(id);
1.708 + if (it != readers.end()) {
1.709 + index.push_back(it->second);
1.710 + } else {
1.711 + index.push_back(&skipper);
1.712 + }
1.713 + if (id == "id" && inverter.get() == 0) {
1.714 + inverter.reset(index.back()->getInverter());
1.715 + index.back() = inverter.get();
1.716 + }
1.717 + }
1.718 + while (getline(is, line)) {
1.719 + std::istringstream ls(line);
1.720 + typename Graph::Node from = nodeResolver->resolve(ls);
1.721 + typename Graph::Node to = nodeResolver->resolve(ls);
1.722 + typename Graph::Edge edge = graph.addEdge(from, to);
1.723 + for (int i = 0; i < (int)index.size(); ++i) {
1.724 + index[i]->read(ls, edge);
1.725 + }
1.726 + }
1.727 + }
1.728 +
1.729 + bool isResolver() const {
1.730 + return inverter.get() != 0;
1.731 + }
1.732 +
1.733 + typename Graph::Edge resolve(std::istream& is) {
1.734 + return inverter->read(is);
1.735 + }
1.736 +
1.737 + private:
1.738 +
1.739 + typedef std::map<std::string, ReaderBase<Item>*> MapReaders;
1.740 + MapReaders readers;
1.741 +
1.742 + Graph& graph;
1.743 + std::string id;
1.744 + SkipReader<Item, DefaultSkipper> skipper;
1.745 +
1.746 + std::auto_ptr<InverterBase<Item> > inverter;
1.747 + std::auto_ptr<ResolverReaderBase<typename Graph::Node> > nodeResolver;
1.748 + };
1.749 +
1.750 +
1.751 + /// \e
1.752 + template <typename _Traits = DefaultReaderTraits>
1.753 + class AttributeReader : public CommonSectionReaderBase {
1.754 + typedef CommonSectionReaderBase Parent;
1.755 + typedef _Traits Traits;
1.756 + public:
1.757 + /// \e
1.758 + AttributeReader(LemonReader& _reader,
1.759 + const std::string& _id = std::string()) : id(_id) {
1.760 + _reader.attach(*this);
1.761 + }
1.762 +
1.763 + /// \e
1.764 + virtual ~AttributeReader() {
1.765 + for (typename Readers::iterator it = readers.begin();
1.766 + it != readers.end(); ++it) {
1.767 + delete it->second;
1.768 + }
1.769 + }
1.770 +
1.771 + private:
1.772 + AttributeReader(const AttributeReader&);
1.773 + void operator=(AttributeReader&);
1.774 +
1.775 + public:
1.776 + /// \e
1.777 + template <typename Value>
1.778 + AttributeReader& readAttribute(const std::string& id, Value& value) {
1.779 + return readAttribute<typename Traits::template Reader<Value> >
1.780 + (id, value);
1.781 + }
1.782 +
1.783 + /// \e
1.784 + template <typename Reader, typename Value>
1.785 + AttributeReader& readAttribute(const std::string& name, Value& value,
1.786 + const Reader& reader = Reader()) {
1.787 + if (readers.find(name) != readers.end()) {
1.788 + ErrorMessage msg;
1.789 + msg << "Multiple read rule for attribute: " << name;
1.790 + throw IOParameterError(msg.message());
1.791 + }
1.792 + readers.insert(make_pair(name, new ValueReader<Value, Reader>
1.793 + (value, reader)));
1.794 + return *this;
1.795 + }
1.796 +
1.797 + /// \e
1.798 + bool header(const std::string& line) {
1.799 + std::istringstream ls(line);
1.800 + std::string command;
1.801 + std::string name;
1.802 + ls >> command >> name;
1.803 + return command == "@attributes" && name == id;
1.804 + }
1.805 +
1.806 + /// \e
1.807 + void read(std::istream& is) {
1.808 + std::string line;
1.809 + while (getline(is, line)) {
1.810 + std::istringstream ls(line);
1.811 + std::string id;
1.812 + ls >> id;
1.813 + typename Readers::iterator it = readers.find(id);
1.814 + if (it != readers.end()) {
1.815 + it->second->read(ls);
1.816 + }
1.817 + }
1.818 + }
1.819 +
1.820 + private:
1.821 + std::string id;
1.822 +
1.823 + typedef std::map<std::string, ValueReaderBase*> Readers;
1.824 + Readers readers;
1.825 +
1.826 + };
1.827 +
1.828 + template <typename _Graph>
1.829 + class NodeReader : public CommonSectionReaderBase {
1.830 + typedef CommonSectionReaderBase Parent;
1.831 + typedef _Graph Graph;
1.832 + typedef typename Graph::Node Item;
1.833 + public:
1.834 +
1.835 + template <typename Resolver>
1.836 + NodeReader(LemonReader& _reader, const Resolver& _resolver,
1.837 + const std::string& _id = std::string())
1.838 + : id(_id), resolver(new ResolverReader<typename Graph::Node, Resolver>
1.839 + (_resolver)) {
1.840 + _reader.attach(*this);
1.841 + }
1.842 +
1.843 + virtual ~NodeReader() {}
1.844 +
1.845 + private:
1.846 + NodeReader(const NodeReader&);
1.847 + void operator=(const NodeReader&);
1.848 +
1.849 + public:
1.850 +
1.851 + void readNode(const std::string& name, Item& item) {
1.852 + if (readers.find(name) != readers.end()) {
1.853 + ErrorMessage msg;
1.854 + msg << "Multiple read rule for node: " << name;
1.855 + throw IOParameterError(msg.message());
1.856 + }
1.857 + readers.insert(make_pair(name, &item));
1.858 + }
1.859 +
1.860 + virtual bool header(const std::string& line) {
1.861 + std::istringstream ls(line);
1.862 + std::string command;
1.863 + std::string name;
1.864 + ls >> command >> name;
1.865 + return command == "@nodes" && name == id;
1.866 + }
1.867 +
1.868 + virtual void read(std::istream& is) {
1.869 + std::string line;
1.870 + while (getline(is, line)) {
1.871 + std::istringstream ls(line);
1.872 + std::string id;
1.873 + ls >> id;
1.874 + typename ItemReaders::iterator it = readers.find(id);
1.875 + if (it != readers.end()) {
1.876 + *(it->second) = resolver->resolve(ls);
1.877 + }
1.878 + }
1.879 + }
1.880 +
1.881 + private:
1.882 +
1.883 + std::string id;
1.884 +
1.885 + typedef std::map<std::string, Item*> ItemReaders;
1.886 + ItemReaders readers;
1.887 + std::auto_ptr<ResolverReaderBase<Item> > resolver;
1.888 + };
1.889 +
1.890 + template <typename _Graph>
1.891 + class EdgeReader : public CommonSectionReaderBase {
1.892 + typedef CommonSectionReaderBase Parent;
1.893 + typedef _Graph Graph;
1.894 + typedef typename Graph::Edge Item;
1.895 + public:
1.896 +
1.897 + template <typename Resolver>
1.898 + EdgeReader(LemonReader& _reader, const Resolver& _resolver,
1.899 + const std::string& _id = std::string())
1.900 + : id(_id), resolver(new ResolverReader<typename Graph::Node, Resolver>
1.901 + (_resolver)) {
1.902 + _reader.attach(*this);
1.903 + }
1.904 +
1.905 + virtual ~EdgeReader() {}
1.906 + private:
1.907 + EdgeReader(const EdgeReader&);
1.908 + void operator=(const EdgeReader&);
1.909 +
1.910 + public:
1.911 +
1.912 + void readEdge(const std::string& name, Item& item) {
1.913 + if (readers.find(name) != readers.end()) {
1.914 + ErrorMessage msg;
1.915 + msg << "Multiple read rule for edge: " << name;
1.916 + throw IOParameterError(msg.message());
1.917 + }
1.918 + readers.insert(make_pair(name, &item));
1.919 + }
1.920 +
1.921 +
1.922 + virtual bool header(const std::string& line) {
1.923 + std::istringstream ls(line);
1.924 + std::string command;
1.925 + std::string name;
1.926 + ls >> command >> name;
1.927 + return command == "@nodes" && name == id;
1.928 + }
1.929 +
1.930 + virtual void read(std::istream& is) {
1.931 + std::string line;
1.932 + while (getline(is, line)) {
1.933 + std::istringstream ls(line);
1.934 + std::string id;
1.935 + ls >> id;
1.936 + typename ItemReaders::iterator it = readers.find(id);
1.937 + if (it != readers.end()) {
1.938 + *(it->second) = resolver->resolve(ls);
1.939 + }
1.940 + }
1.941 + }
1.942 +
1.943 + private:
1.944 +
1.945 + std::string id;
1.946 +
1.947 + typedef std::map<std::string, Item*> ItemReaders;
1.948 + ItemReaders readers;
1.949 + std::auto_ptr<ResolverReaderBase<Item> > resolver;
1.950 + };
1.951 +
1.952 + /// \e
1.953 + class PrintReader : public LemonReader::SectionReader {
1.954 + typedef LemonReader::SectionReader Parent;
1.955 + public:
1.956 +
1.957 + /// \e
1.958 + PrintReader(LemonReader& reader) {
1.959 + reader.attach(*this);
1.960 + }
1.961 +
1.962 + /// \e
1.963 + bool header(const std::string& line) {
1.964 + std::cout << "Asked header: " << line << std::endl;
1.965 + return true;
1.966 + }
1.967 +
1.968 + /// \e
1.969 + void read(std::istream& is) {
1.970 + std::string line;
1.971 + while (std::getline(is, line)) {
1.972 + std::cout << line << std::endl;
1.973 + }
1.974 + }
1.975 +
1.976 + };
1.977 +
1.978 + /// @}
1.979 +}
1.980 +#endif