1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/lgf_reader.h Thu Apr 17 15:18:45 2008 +0100
1.3 @@ -0,0 +1,914 @@
1.4 +/* -*- C++ -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library
1.7 + *
1.8 + * Copyright (C) 2003-2008
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +///\ingroup lemon_io
1.23 +///\file
1.24 +///\brief Lemon Graph Format reader.
1.25 +
1.26 +
1.27 +#ifndef LEMON_LGF_READER_H
1.28 +#define LEMON_LGF_READER_H
1.29 +
1.30 +#include <iostream>
1.31 +#include <fstream>
1.32 +#include <sstream>
1.33 +
1.34 +#include <set>
1.35 +#include <map>
1.36 +
1.37 +#include <lemon/assert.h>
1.38 +#include <lemon/graph_utils.h>
1.39 +
1.40 +#include <lemon/lgf_writer.h>
1.41 +
1.42 +#include <lemon/concept_check.h>
1.43 +#include <lemon/concepts/maps.h>
1.44 +
1.45 +namespace lemon {
1.46 +
1.47 + namespace _reader_bits {
1.48 +
1.49 + template <typename Value>
1.50 + struct DefaultConverter {
1.51 + Value operator()(const std::string& str) {
1.52 + std::istringstream is(str);
1.53 + Value value;
1.54 + is >> value;
1.55 +
1.56 + char c;
1.57 + if (is >> std::ws >> c) {
1.58 + throw DataFormatError("Remaining characters in token");
1.59 + }
1.60 + return value;
1.61 + }
1.62 + };
1.63 +
1.64 + template <>
1.65 + struct DefaultConverter<std::string> {
1.66 + std::string operator()(const std::string& str) {
1.67 + return str;
1.68 + }
1.69 + };
1.70 +
1.71 + template <typename _Item>
1.72 + class MapStorageBase {
1.73 + public:
1.74 + typedef _Item Item;
1.75 +
1.76 + public:
1.77 + MapStorageBase() {}
1.78 + virtual ~MapStorageBase() {}
1.79 +
1.80 + virtual void set(const Item& item, const std::string& value) = 0;
1.81 +
1.82 + };
1.83 +
1.84 + template <typename _Item, typename _Map,
1.85 + typename _Converter = DefaultConverter<typename _Map::Value> >
1.86 + class MapStorage : public MapStorageBase<_Item> {
1.87 + public:
1.88 + typedef _Map Map;
1.89 + typedef _Converter Converter;
1.90 + typedef _Item Item;
1.91 +
1.92 + private:
1.93 + Map& _map;
1.94 + Converter _converter;
1.95 +
1.96 + public:
1.97 + MapStorage(Map& map, const Converter& converter = Converter())
1.98 + : _map(map), _converter(converter) {}
1.99 + virtual ~MapStorage() {}
1.100 +
1.101 + virtual void set(const Item& item ,const std::string& value) {
1.102 + _map.set(item, _converter(value));
1.103 + }
1.104 + };
1.105 +
1.106 + class ValueStorageBase {
1.107 + public:
1.108 + ValueStorageBase() {}
1.109 + virtual ~ValueStorageBase() {}
1.110 +
1.111 + virtual void set(const std::string&) = 0;
1.112 + };
1.113 +
1.114 + template <typename _Value, typename _Converter = DefaultConverter<_Value> >
1.115 + class ValueStorage : public ValueStorageBase {
1.116 + public:
1.117 + typedef _Value Value;
1.118 + typedef _Converter Converter;
1.119 +
1.120 + private:
1.121 + Value& _value;
1.122 + Converter _converter;
1.123 +
1.124 + public:
1.125 + ValueStorage(Value& value, const Converter& converter = Converter())
1.126 + : _value(value), _converter(converter) {}
1.127 +
1.128 + virtual void set(const std::string& value) {
1.129 + _value = _converter(value);
1.130 + }
1.131 + };
1.132 +
1.133 + template <typename Value>
1.134 + struct MapLookUpConverter {
1.135 + const std::map<std::string, Value>& _map;
1.136 +
1.137 + MapLookUpConverter(const std::map<std::string, Value>& map)
1.138 + : _map(map) {}
1.139 +
1.140 + Value operator()(const std::string& str) {
1.141 + typename std::map<std::string, Value>::const_iterator it =
1.142 + _map.find(str);
1.143 + if (it == _map.end()) {
1.144 + std::ostringstream msg;
1.145 + msg << "Item not found: " << str;
1.146 + throw DataFormatError(msg.str().c_str());
1.147 + }
1.148 + return it->second;
1.149 + }
1.150 + };
1.151 +
1.152 + bool isWhiteSpace(char c) {
1.153 + return c == ' ' || c == '\t' || c == '\v' ||
1.154 + c == '\n' || c == '\r' || c == '\f';
1.155 + }
1.156 +
1.157 + bool isOct(char c) {
1.158 + return '0' <= c && c <='7';
1.159 + }
1.160 +
1.161 + int valueOct(char c) {
1.162 + LEMON_ASSERT(isOct(c), "The character is not octal.");
1.163 + return c - '0';
1.164 + }
1.165 +
1.166 + bool isHex(char c) {
1.167 + return ('0' <= c && c <= '9') ||
1.168 + ('a' <= c && c <= 'z') ||
1.169 + ('A' <= c && c <= 'Z');
1.170 + }
1.171 +
1.172 + int valueHex(char c) {
1.173 + LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
1.174 + if ('0' <= c && c <= '9') return c - '0';
1.175 + if ('a' <= c && c <= 'z') return c - 'a' + 10;
1.176 + return c - 'A' + 10;
1.177 + }
1.178 +
1.179 + bool isIdentifierFirstChar(char c) {
1.180 + return ('a' <= c && c <= 'z') ||
1.181 + ('A' <= c && c <= 'Z') || c == '_';
1.182 + }
1.183 +
1.184 + bool isIdentifierChar(char c) {
1.185 + return isIdentifierFirstChar(c) ||
1.186 + ('0' <= c && c <= '9');
1.187 + }
1.188 +
1.189 + char readEscape(std::istream& is) {
1.190 + char c;
1.191 + if (!is.get(c))
1.192 + throw DataFormatError("Escape format error");
1.193 +
1.194 + switch (c) {
1.195 + case '\\':
1.196 + return '\\';
1.197 + case '\"':
1.198 + return '\"';
1.199 + case '\'':
1.200 + return '\'';
1.201 + case '\?':
1.202 + return '\?';
1.203 + case 'a':
1.204 + return '\a';
1.205 + case 'b':
1.206 + return '\b';
1.207 + case 'f':
1.208 + return '\f';
1.209 + case 'n':
1.210 + return '\n';
1.211 + case 'r':
1.212 + return '\r';
1.213 + case 't':
1.214 + return '\t';
1.215 + case 'v':
1.216 + return '\v';
1.217 + case 'x':
1.218 + {
1.219 + int code;
1.220 + if (!is.get(c) || !isHex(c))
1.221 + throw DataFormatError("Escape format error");
1.222 + else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
1.223 + else code = code * 16 + valueHex(c);
1.224 + return code;
1.225 + }
1.226 + default:
1.227 + {
1.228 + int code;
1.229 + if (!isOct(c))
1.230 + throw DataFormatError("Escape format error");
1.231 + else if (code = valueOct(c), !is.get(c) || !isOct(c))
1.232 + is.putback(c);
1.233 + else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
1.234 + is.putback(c);
1.235 + else code = code * 8 + valueOct(c);
1.236 + return code;
1.237 + }
1.238 + }
1.239 + }
1.240 +
1.241 + std::istream& readToken(std::istream& is, std::string& str) {
1.242 + std::ostringstream os;
1.243 +
1.244 + char c;
1.245 + is >> std::ws;
1.246 +
1.247 + if (!is.get(c))
1.248 + return is;
1.249 +
1.250 + if (c == '\"') {
1.251 + while (is.get(c) && c != '\"') {
1.252 + if (c == '\\')
1.253 + c = readEscape(is);
1.254 + os << c;
1.255 + }
1.256 + if (!is)
1.257 + throw DataFormatError("Quoted format error");
1.258 + } else {
1.259 + is.putback(c);
1.260 + while (is.get(c) && !isWhiteSpace(c)) {
1.261 + if (c == '\\')
1.262 + c = readEscape(is);
1.263 + os << c;
1.264 + }
1.265 + if (!is) {
1.266 + is.clear();
1.267 + } else {
1.268 + is.putback(c);
1.269 + }
1.270 + }
1.271 + str = os.str();
1.272 + return is;
1.273 + }
1.274 +
1.275 + std::istream& readIdentifier(std::istream& is, std::string& str) {
1.276 + std::ostringstream os;
1.277 +
1.278 + char c;
1.279 + is >> std::ws;
1.280 +
1.281 + if (!is.get(c))
1.282 + return is;
1.283 +
1.284 + if (!isIdentifierFirstChar(c))
1.285 + throw DataFormatError("Wrong char in identifier");
1.286 +
1.287 + os << c;
1.288 +
1.289 + while (is.get(c) && !isWhiteSpace(c)) {
1.290 + if (!isIdentifierChar(c))
1.291 + throw DataFormatError("Wrong char in identifier");
1.292 + os << c;
1.293 + }
1.294 + if (!is) is.clear();
1.295 +
1.296 + str = os.str();
1.297 + return is;
1.298 + }
1.299 +
1.300 + }
1.301 +
1.302 + /// \e
1.303 + template <typename _Digraph>
1.304 + class DigraphReader {
1.305 + public:
1.306 +
1.307 + typedef _Digraph Digraph;
1.308 + GRAPH_TYPEDEFS(typename Digraph);
1.309 +
1.310 + private:
1.311 +
1.312 +
1.313 + std::istream* _is;
1.314 + bool local_is;
1.315 +
1.316 + Digraph& _digraph;
1.317 +
1.318 + std::string _nodes_caption;
1.319 + std::string _arcs_caption;
1.320 + std::string _attributes_caption;
1.321 +
1.322 + typedef std::map<std::string, Node> NodeIndex;
1.323 + NodeIndex _node_index;
1.324 + typedef std::map<std::string, Arc> ArcIndex;
1.325 + ArcIndex _arc_index;
1.326 +
1.327 + typedef std::vector<std::pair<std::string,
1.328 + _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1.329 + NodeMaps _node_maps;
1.330 +
1.331 + typedef std::vector<std::pair<std::string,
1.332 + _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
1.333 + ArcMaps _arc_maps;
1.334 +
1.335 + typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1.336 + Attributes;
1.337 + Attributes _attributes;
1.338 +
1.339 + bool _use_nodes;
1.340 + bool _use_arcs;
1.341 +
1.342 + int line_num;
1.343 + std::istringstream line;
1.344 +
1.345 + public:
1.346 +
1.347 + /// \e
1.348 + DigraphReader(std::istream& is, Digraph& digraph)
1.349 + : _is(&is), local_is(false), _digraph(digraph),
1.350 + _use_nodes(false), _use_arcs(false) {}
1.351 +
1.352 + /// \e
1.353 + DigraphReader(const std::string& fn, Digraph& digraph)
1.354 + : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
1.355 + _use_nodes(false), _use_arcs(false) {}
1.356 +
1.357 +
1.358 + /// \e
1.359 + DigraphReader(const char* fn, Digraph& digraph)
1.360 + : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
1.361 + _use_nodes(false), _use_arcs(false) {}
1.362 +
1.363 + /// \e
1.364 + DigraphReader(DigraphReader& other)
1.365 + : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
1.366 + _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
1.367 +
1.368 + other.is = 0;
1.369 + other.local_is = false;
1.370 +
1.371 + _node_index.swap(other._node_index);
1.372 + _arc_index.swap(other._arc_index);
1.373 +
1.374 + _node_maps.swap(other._node_maps);
1.375 + _arc_maps.swap(other._arc_maps);
1.376 + _attributes.swap(other._attributes);
1.377 +
1.378 + _nodes_caption = other._nodes_caption;
1.379 + _arcs_caption = other._arcs_caption;
1.380 + _attributes_caption = other._attributes_caption;
1.381 + }
1.382 +
1.383 + /// \e
1.384 + ~DigraphReader() {
1.385 + for (typename NodeMaps::iterator it = _node_maps.begin();
1.386 + it != _node_maps.end(); ++it) {
1.387 + delete it->second;
1.388 + }
1.389 +
1.390 + for (typename ArcMaps::iterator it = _arc_maps.begin();
1.391 + it != _arc_maps.end(); ++it) {
1.392 + delete it->second;
1.393 + }
1.394 +
1.395 + for (typename Attributes::iterator it = _attributes.begin();
1.396 + it != _attributes.end(); ++it) {
1.397 + delete it->second;
1.398 + }
1.399 +
1.400 + if (local_is) {
1.401 + delete _is;
1.402 + }
1.403 +
1.404 + }
1.405 +
1.406 + private:
1.407 +
1.408 + DigraphReader& operator=(const DigraphReader&);
1.409 +
1.410 + public:
1.411 +
1.412 + /// \e
1.413 + template <typename Map>
1.414 + DigraphReader& nodeMap(const std::string& caption, Map& map) {
1.415 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.416 + _reader_bits::MapStorageBase<Node>* storage =
1.417 + new _reader_bits::MapStorage<Node, Map>(map);
1.418 + _node_maps.push_back(std::make_pair(caption, storage));
1.419 + return *this;
1.420 + }
1.421 +
1.422 + /// \e
1.423 + template <typename Map, typename Converter>
1.424 + DigraphReader& nodeMap(const std::string& caption, Map& map,
1.425 + const Converter& converter = Converter()) {
1.426 + checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1.427 + _reader_bits::MapStorageBase<Node>* storage =
1.428 + new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1.429 + _node_maps.push_back(std::make_pair(caption, storage));
1.430 + return *this;
1.431 + }
1.432 +
1.433 + /// \e
1.434 + template <typename Map>
1.435 + DigraphReader& arcMap(const std::string& caption, Map& map) {
1.436 + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1.437 + _reader_bits::MapStorageBase<Arc>* storage =
1.438 + new _reader_bits::MapStorage<Arc, Map>(map);
1.439 + _arc_maps.push_back(std::make_pair(caption, storage));
1.440 + return *this;
1.441 + }
1.442 +
1.443 + /// \e
1.444 + template <typename Map, typename Converter>
1.445 + DigraphReader& arcMap(const std::string& caption, Map& map,
1.446 + const Converter& converter = Converter()) {
1.447 + checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1.448 + _reader_bits::MapStorageBase<Arc>* storage =
1.449 + new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
1.450 + _arc_maps.push_back(std::make_pair(caption, storage));
1.451 + return *this;
1.452 + }
1.453 +
1.454 + /// \e
1.455 + template <typename Value>
1.456 + DigraphReader& attribute(const std::string& caption, Value& value) {
1.457 + _reader_bits::ValueStorageBase* storage =
1.458 + new _reader_bits::ValueStorage<Value>(value);
1.459 + _attributes.insert(std::make_pair(caption, storage));
1.460 + return *this;
1.461 + }
1.462 +
1.463 + /// \e
1.464 + template <typename Value, typename Converter>
1.465 + DigraphReader& attribute(const std::string& caption, Value& value,
1.466 + const Converter& converter = Converter()) {
1.467 + _reader_bits::ValueStorageBase* storage =
1.468 + new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1.469 + _attributes.insert(std::make_pair(caption, storage));
1.470 + return *this;
1.471 + }
1.472 +
1.473 + /// \e
1.474 + DigraphReader& node(const std::string& caption, Node& node) {
1.475 + typedef _reader_bits::MapLookUpConverter<Node> Converter;
1.476 + Converter converter(_node_index);
1.477 + _reader_bits::ValueStorageBase* storage =
1.478 + new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1.479 + _attributes.insert(std::make_pair(caption, storage));
1.480 + return *this;
1.481 + }
1.482 +
1.483 + /// \e
1.484 + DigraphReader& arc(const std::string& caption, Arc& arc) {
1.485 + typedef _reader_bits::MapLookUpConverter<Arc> Converter;
1.486 + Converter converter(_arc_index);
1.487 + _reader_bits::ValueStorageBase* storage =
1.488 + new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1.489 + _attributes.insert(std::make_pair(caption, storage));
1.490 + return *this;
1.491 + }
1.492 +
1.493 + /// \e
1.494 + DigraphReader& nodes(const std::string& caption) {
1.495 + _nodes_caption = caption;
1.496 + return *this;
1.497 + }
1.498 +
1.499 + /// \e
1.500 + DigraphReader& arcs(const std::string& caption) {
1.501 + _arcs_caption = caption;
1.502 + return *this;
1.503 + }
1.504 +
1.505 + /// \e
1.506 + DigraphReader& attributes(const std::string& caption) {
1.507 + _attributes_caption = caption;
1.508 + return *this;
1.509 + }
1.510 +
1.511 + /// \e
1.512 + template <typename Map>
1.513 + DigraphReader& useNodes(const Map& map) {
1.514 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1.515 + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1.516 + _use_nodes = true;
1.517 + _writer_bits::DefaultConverter<typename Map::Value> converter;
1.518 + for (NodeIt n(_digraph); n != INVALID; ++n) {
1.519 + _node_index.insert(std::make_pair(converter(map[n]), n));
1.520 + }
1.521 + return *this;
1.522 + }
1.523 +
1.524 + /// \e
1.525 + template <typename Map, typename Converter>
1.526 + DigraphReader& useNodes(const Map& map,
1.527 + const Converter& converter = Converter()) {
1.528 + checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1.529 + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1.530 + _use_nodes = true;
1.531 + for (NodeIt n(_digraph); n != INVALID; ++n) {
1.532 + _node_index.insert(std::make_pair(converter(map[n]), n));
1.533 + }
1.534 + return *this;
1.535 + }
1.536 +
1.537 + /// \e
1.538 + template <typename Map>
1.539 + DigraphReader& useArcs(const Map& map) {
1.540 + checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1.541 + LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
1.542 + _use_arcs = true;
1.543 + _writer_bits::DefaultConverter<typename Map::Value> converter;
1.544 + for (ArcIt a(_digraph); a != INVALID; ++a) {
1.545 + _arc_index.insert(std::make_pair(converter(map[a]), a));
1.546 + }
1.547 + return *this;
1.548 + }
1.549 +
1.550 + /// \e
1.551 + template <typename Map, typename Converter>
1.552 + DigraphReader& useArcs(const Map& map,
1.553 + const Converter& converter = Converter()) {
1.554 + checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1.555 + LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
1.556 + _use_arcs = true;
1.557 + for (ArcIt a(_digraph); a != INVALID; ++a) {
1.558 + _arc_index.insert(std::make_pair(converter(map[a]), a));
1.559 + }
1.560 + return *this;
1.561 + }
1.562 +
1.563 + private:
1.564 +
1.565 + bool readLine() {
1.566 + std::string str;
1.567 + while(++line_num, std::getline(*_is, str)) {
1.568 + line.clear(); line.str(str);
1.569 + char c;
1.570 + if (line >> std::ws >> c && c != '#') {
1.571 + line.putback(c);
1.572 + return true;
1.573 + }
1.574 + }
1.575 + return false;
1.576 + }
1.577 +
1.578 + bool readSuccess() {
1.579 + return static_cast<bool>(*_is);
1.580 + }
1.581 +
1.582 + void skipSection() {
1.583 + char c;
1.584 + while (readSuccess() && line >> c && c != '@') {
1.585 + readLine();
1.586 + }
1.587 + line.putback(c);
1.588 + }
1.589 +
1.590 + void readNodes() {
1.591 +
1.592 + std::vector<int> map_index(_node_maps.size());
1.593 + int map_num, label_index;
1.594 +
1.595 + if (!readLine())
1.596 + throw DataFormatError("Cannot find map captions");
1.597 +
1.598 + {
1.599 + std::map<std::string, int> maps;
1.600 +
1.601 + std::string map;
1.602 + int index = 0;
1.603 + while (_reader_bits::readIdentifier(line, map)) {
1.604 + if (maps.find(map) != maps.end()) {
1.605 + std::ostringstream msg;
1.606 + msg << "Multiple occurence of node map: " << map;
1.607 + throw DataFormatError(msg.str().c_str());
1.608 + }
1.609 + maps.insert(std::make_pair(map, index));
1.610 + ++index;
1.611 + }
1.612 +
1.613 + for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1.614 + std::map<std::string, int>::iterator jt =
1.615 + maps.find(_node_maps[i].first);
1.616 + if (jt == maps.end()) {
1.617 + std::ostringstream msg;
1.618 + msg << "Map not found in file: " << _node_maps[i].first;
1.619 + throw DataFormatError(msg.str().c_str());
1.620 + }
1.621 + map_index[i] = jt->second;
1.622 + }
1.623 +
1.624 + {
1.625 + std::map<std::string, int>::iterator jt = maps.find("label");
1.626 + if (jt == maps.end())
1.627 + throw DataFormatError("Label map not found in file");
1.628 + label_index = jt->second;
1.629 + }
1.630 + map_num = maps.size();
1.631 + }
1.632 +
1.633 + char c;
1.634 + while (readLine() && line >> c && c != '@') {
1.635 + line.putback(c);
1.636 +
1.637 + std::vector<std::string> tokens(map_num);
1.638 + for (int i = 0; i < map_num; ++i) {
1.639 + if (!_reader_bits::readToken(line, tokens[i])) {
1.640 + std::ostringstream msg;
1.641 + msg << "Column not found (" << i + 1 << ")";
1.642 + throw DataFormatError(msg.str().c_str());
1.643 + }
1.644 + }
1.645 + if (line >> std::ws >> c)
1.646 + throw DataFormatError("Extra character on the end of line");
1.647 +
1.648 + Node n;
1.649 + if (!_use_nodes) {
1.650 + n = _digraph.addNode();
1.651 + _node_index.insert(std::make_pair(tokens[label_index], n));
1.652 + } else {
1.653 + typename std::map<std::string, Node>::iterator it =
1.654 + _node_index.find(tokens[label_index]);
1.655 + if (it == _node_index.end()) {
1.656 + std::ostringstream msg;
1.657 + msg << "Node with label not found: " << tokens[label_index];
1.658 + throw DataFormatError(msg.str().c_str());
1.659 + }
1.660 + n = it->second;
1.661 + }
1.662 +
1.663 + for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1.664 + _node_maps[i].second->set(n, tokens[map_index[i]]);
1.665 + }
1.666 +
1.667 + }
1.668 + if (readSuccess()) {
1.669 + line.putback(c);
1.670 + }
1.671 + }
1.672 +
1.673 + void readArcs() {
1.674 +
1.675 + std::vector<int> map_index(_arc_maps.size());
1.676 + int map_num, label_index;
1.677 +
1.678 + if (!readLine())
1.679 + throw DataFormatError("Cannot find map captions");
1.680 +
1.681 + {
1.682 + std::map<std::string, int> maps;
1.683 +
1.684 + std::string map;
1.685 + int index = 0;
1.686 + while (_reader_bits::readIdentifier(line, map)) {
1.687 + if (maps.find(map) != maps.end()) {
1.688 + std::ostringstream msg;
1.689 + msg << "Multiple occurence of arc map: " << map;
1.690 + throw DataFormatError(msg.str().c_str());
1.691 + }
1.692 + maps.insert(std::make_pair(map, index));
1.693 + ++index;
1.694 + }
1.695 +
1.696 + for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1.697 + std::map<std::string, int>::iterator jt =
1.698 + maps.find(_arc_maps[i].first);
1.699 + if (jt == maps.end()) {
1.700 + std::ostringstream msg;
1.701 + msg << "Map not found in file: " << _arc_maps[i].first;
1.702 + throw DataFormatError(msg.str().c_str());
1.703 + }
1.704 + map_index[i] = jt->second;
1.705 + }
1.706 +
1.707 + {
1.708 + std::map<std::string, int>::iterator jt = maps.find("label");
1.709 + if (jt == maps.end())
1.710 + throw DataFormatError("Label map not found in file");
1.711 + label_index = jt->second;
1.712 + }
1.713 + map_num = maps.size();
1.714 + }
1.715 +
1.716 + char c;
1.717 + while (readLine() && line >> c && c != '@') {
1.718 + line.putback(c);
1.719 +
1.720 + std::string source_token;
1.721 + std::string target_token;
1.722 +
1.723 + if (!_reader_bits::readToken(line, source_token))
1.724 + throw DataFormatError("Source not found");
1.725 +
1.726 + if (!_reader_bits::readToken(line, target_token))
1.727 + throw DataFormatError("Source not found");
1.728 +
1.729 + std::vector<std::string> tokens(map_num);
1.730 + for (int i = 0; i < map_num; ++i) {
1.731 + if (!_reader_bits::readToken(line, tokens[i])) {
1.732 + std::ostringstream msg;
1.733 + msg << "Column not found (" << i + 1 << ")";
1.734 + throw DataFormatError(msg.str().c_str());
1.735 + }
1.736 + }
1.737 + if (line >> std::ws >> c)
1.738 + throw DataFormatError("Extra character on the end of line");
1.739 +
1.740 + Arc a;
1.741 + if (!_use_arcs) {
1.742 +
1.743 + typename NodeIndex::iterator it;
1.744 +
1.745 + it = _node_index.find(source_token);
1.746 + if (it == _node_index.end()) {
1.747 + std::ostringstream msg;
1.748 + msg << "Item not found: " << source_token;
1.749 + throw DataFormatError(msg.str().c_str());
1.750 + }
1.751 + Node source = it->second;
1.752 +
1.753 + it = _node_index.find(target_token);
1.754 + if (it == _node_index.end()) {
1.755 + std::ostringstream msg;
1.756 + msg << "Item not found: " << target_token;
1.757 + throw DataFormatError(msg.str().c_str());
1.758 + }
1.759 + Node target = it->second;
1.760 +
1.761 + a = _digraph.addArc(source, target);
1.762 + _arc_index.insert(std::make_pair(tokens[label_index], a));
1.763 + } else {
1.764 + typename std::map<std::string, Arc>::iterator it =
1.765 + _arc_index.find(tokens[label_index]);
1.766 + if (it == _arc_index.end()) {
1.767 + std::ostringstream msg;
1.768 + msg << "Arc with label not found: " << tokens[label_index];
1.769 + throw DataFormatError(msg.str().c_str());
1.770 + }
1.771 + a = it->second;
1.772 + }
1.773 +
1.774 + for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1.775 + _arc_maps[i].second->set(a, tokens[map_index[i]]);
1.776 + }
1.777 +
1.778 + }
1.779 + if (readSuccess()) {
1.780 + line.putback(c);
1.781 + }
1.782 + }
1.783 +
1.784 + void readAttributes() {
1.785 +
1.786 + std::set<std::string> read_attr;
1.787 +
1.788 + char c;
1.789 + while (readLine() && line >> c && c != '@') {
1.790 + line.putback(c);
1.791 +
1.792 + std::string attr, token;
1.793 + if (!_reader_bits::readIdentifier(line, attr))
1.794 + throw DataFormatError("Attribute name not found");
1.795 + if (!_reader_bits::readToken(line, token))
1.796 + throw DataFormatError("Attribute value not found");
1.797 + if (line >> c)
1.798 + throw DataFormatError("Extra character on the end of line");
1.799 +
1.800 + {
1.801 + std::set<std::string>::iterator it = read_attr.find(attr);
1.802 + if (it != read_attr.end()) {
1.803 + std::ostringstream msg;
1.804 + msg << "Multiple occurence of attribute " << attr;
1.805 + throw DataFormatError(msg.str().c_str());
1.806 + }
1.807 + read_attr.insert(attr);
1.808 + }
1.809 +
1.810 + {
1.811 + typename Attributes::iterator it = _attributes.lower_bound(attr);
1.812 + while (it != _attributes.end() && it->first == attr) {
1.813 + it->second->set(token);
1.814 + ++it;
1.815 + }
1.816 + }
1.817 +
1.818 + }
1.819 + if (readSuccess()) {
1.820 + line.putback(c);
1.821 + }
1.822 + for (typename Attributes::iterator it = _attributes.begin();
1.823 + it != _attributes.end(); ++it) {
1.824 + if (read_attr.find(it->first) == read_attr.end()) {
1.825 + std::ostringstream msg;
1.826 + msg << "Attribute not found in file: " << it->first;
1.827 + throw DataFormatError(msg.str().c_str());
1.828 + }
1.829 + }
1.830 + }
1.831 +
1.832 + public:
1.833 +
1.834 + /// \e
1.835 + void run() {
1.836 +
1.837 + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1.838 +
1.839 + bool nodes_done = false;
1.840 + bool arcs_done = false;
1.841 + bool attributes_done = false;
1.842 +
1.843 + line_num = 0;
1.844 + readLine();
1.845 +
1.846 + while (readSuccess()) {
1.847 + skipSection();
1.848 + try {
1.849 + char c;
1.850 + std::string section, caption;
1.851 + line >> c;
1.852 + _reader_bits::readIdentifier(line, section);
1.853 + _reader_bits::readIdentifier(line, caption);
1.854 +
1.855 + if (line >> c)
1.856 + throw DataFormatError("Extra character on the end of line");
1.857 +
1.858 + if (section == "nodes" && !nodes_done) {
1.859 + if (_nodes_caption.empty() || _nodes_caption == caption) {
1.860 + readNodes();
1.861 + nodes_done = true;
1.862 + }
1.863 + } else if ((section == "arcs" || section == "edges") &&
1.864 + !arcs_done) {
1.865 + if (_arcs_caption.empty() || _arcs_caption == caption) {
1.866 + readArcs();
1.867 + arcs_done = true;
1.868 + }
1.869 + } else if (section == "attributes" && !attributes_done) {
1.870 + if (_attributes_caption.empty() || _attributes_caption == caption) {
1.871 + readAttributes();
1.872 + attributes_done = true;
1.873 + }
1.874 + } else {
1.875 + readLine();
1.876 + skipSection();
1.877 + }
1.878 + } catch (DataFormatError& error) {
1.879 + error.line(line_num);
1.880 + throw;
1.881 + }
1.882 + }
1.883 +
1.884 + if (!nodes_done) {
1.885 + throw DataFormatError("Section @nodes not found");
1.886 + }
1.887 +
1.888 + if (!arcs_done) {
1.889 + throw DataFormatError("Section @arcs not found");
1.890 + }
1.891 +
1.892 + if (!attributes_done && !_attributes.empty()) {
1.893 + throw DataFormatError("Section @attributes not found");
1.894 + }
1.895 +
1.896 + }
1.897 +
1.898 + };
1.899 +
1.900 + template <typename Digraph>
1.901 + DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1.902 + return DigraphReader<Digraph>(is, digraph);
1.903 + }
1.904 +
1.905 + template <typename Digraph>
1.906 + DigraphReader<Digraph> digraphReader(const std::string& fn,
1.907 + Digraph& digraph) {
1.908 + return DigraphReader<Digraph>(fn, digraph);
1.909 + }
1.910 +
1.911 + template <typename Digraph>
1.912 + DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1.913 + return DigraphReader<Digraph>(fn, digraph);
1.914 + }
1.915 +}
1.916 +
1.917 +#endif