1.1 --- a/src/lemon/lemon_reader.h Sat May 21 21:04:57 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1977 +0,0 @@
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 -
1.25 -#ifndef LEMON_LEMON_READER_H
1.26 -#define LEMON_LEMON_READER_H
1.27 -
1.28 -
1.29 -#include <iostream>
1.30 -#include <fstream>
1.31 -#include <string>
1.32 -#include <vector>
1.33 -#include <algorithm>
1.34 -#include <map>
1.35 -#include <memory>
1.36 -
1.37 -#include <lemon/error.h>
1.38 -#include <lemon/graph_utils.h>
1.39 -#include <lemon/utility.h>
1.40 -#include <lemon/bits/item_reader.h>
1.41 -
1.42 -
1.43 -namespace lemon {
1.44 -
1.45 - namespace _reader_bits {
1.46 -
1.47 - template <typename T>
1.48 - bool operator<(T, T) {
1.49 - throw DataFormatError("Id is not comparable");
1.50 - }
1.51 -
1.52 - template <typename T>
1.53 - struct Less {
1.54 - bool operator()(const T& p, const T& q) const {
1.55 - return p < q;
1.56 - }
1.57 - };
1.58 -
1.59 - template <typename M1, typename M2>
1.60 - class WriteComposeMap {
1.61 - public:
1.62 - typedef True NeedCopy;
1.63 -
1.64 - typedef typename M2::Key Key;
1.65 - typedef typename M1::Value Value;
1.66 -
1.67 - WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2)
1.68 - : m1(_m1), m2(_m2) {}
1.69 -
1.70 - void set(const Key& key, const Value& value) {
1.71 - m1.set(m2[key], value);
1.72 - }
1.73 -
1.74 - private:
1.75 -
1.76 - typename SmartReference<M1>::Type m1;
1.77 - typename SmartConstReference<M2>::Type m2;
1.78 -
1.79 - };
1.80 -
1.81 - template <typename M1, typename M2>
1.82 - WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) {
1.83 - return WriteComposeMap<M1, M2>(m1, m2);
1.84 - }
1.85 -
1.86 - template <typename M1, typename M2>
1.87 - WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) {
1.88 - return WriteComposeMap<M1, M2>(m1, m2);
1.89 - }
1.90 -
1.91 - }
1.92 -
1.93 - /// \ingroup io_group
1.94 - /// \brief Lemon Format reader class.
1.95 - ///
1.96 - /// The Lemon Format contains several sections. We do not want to
1.97 - /// determine what sections are in a lemon file we give only a framework
1.98 - /// to read a section oriented format.
1.99 - ///
1.100 - /// In the Lemon Format each section starts with a line contains a \c \@
1.101 - /// character on the first not white space position. This line is the
1.102 - /// header line of the section. Each next lines belong to this section
1.103 - /// while it does not starts with \c \@ character. This line can start a
1.104 - /// new section or if it can close the file with the \c \@end line.
1.105 - /// The file format ignore the empty and comment lines. The line is
1.106 - /// comment line if it starts with a \c # character.
1.107 - ///
1.108 - /// The framework provides an abstract LemonReader::SectionReader class
1.109 - /// what defines the interface of a SectionReader. The SectionReader
1.110 - /// has the \c header() member function what get a header line string and
1.111 - /// decides if it want to process the next section. Several SectionReaders
1.112 - /// can be attached to an LemonReader and the first attached what can
1.113 - /// process the section will be used. Its \c read() member will called
1.114 - /// with a stream contains the section. From this stream the empty and
1.115 - /// comment lines are filtered out.
1.116 - ///
1.117 - /// \relates GraphReader
1.118 - /// \relates NodeSetReader
1.119 - /// \relates EdgeSetReader
1.120 - /// \relates NodesReader
1.121 - /// \relates EdgesReader
1.122 - /// \relates AttributeReader
1.123 - class LemonReader {
1.124 - private:
1.125 -
1.126 - class FilterStreamBuf : public std::streambuf {
1.127 - public:
1.128 -
1.129 - typedef std::streambuf Parent;
1.130 - typedef Parent::char_type char_type;
1.131 - FilterStreamBuf(std::istream& is, int& num)
1.132 - : _is(is), _base(0), _eptr(0),
1.133 - _num(num), skip_state(after_endl) {}
1.134 -
1.135 - protected:
1.136 -
1.137 - enum skip_state_type {
1.138 - no_skip,
1.139 - after_endl,
1.140 - comment_line
1.141 - };
1.142 -
1.143 - char_type small_buf[1];
1.144 -
1.145 -
1.146 - std::istream& _is;
1.147 -
1.148 - char_type* _base;
1.149 - char_type* _eptr;
1.150 -
1.151 - int& _num;
1.152 -
1.153 - skip_state_type skip_state;
1.154 -
1.155 -
1.156 - char_type* base() { return _base; }
1.157 -
1.158 - char_type* eptr() { return _eptr; }
1.159 -
1.160 - int blen() { return _eptr - _base; }
1.161 -
1.162 - void setb(char_type* buf, int len) {
1.163 - _base = buf;
1.164 - _eptr = buf + len;
1.165 - }
1.166 -
1.167 - virtual std::streambuf* setbuf(char *buf, int len) {
1.168 - if (base()) return 0;
1.169 - if (buf != 0 && len >= (int)sizeof(small_buf)) {
1.170 - setb(buf, len);
1.171 - } else {
1.172 - setb(small_buf, sizeof(small_buf));
1.173 - }
1.174 - setg(0, 0, 0);
1.175 - return this;
1.176 - }
1.177 -
1.178 - bool put_char(char c) {
1.179 - switch (skip_state) {
1.180 - case no_skip:
1.181 - switch (c) {
1.182 - case '\n':
1.183 - skip_state = after_endl;
1.184 - return true;
1.185 - default:
1.186 - return true;
1.187 - }
1.188 - case after_endl:
1.189 - switch (c) {
1.190 - case '@':
1.191 - return false;
1.192 - case '\n':
1.193 - return false;
1.194 - case '#':
1.195 - skip_state = comment_line;
1.196 - return false;
1.197 - default:
1.198 - if (!isspace(c)) {
1.199 - skip_state = no_skip;
1.200 - return true;
1.201 - } else {
1.202 - return false;
1.203 - }
1.204 - }
1.205 - break;
1.206 - case comment_line:
1.207 - switch (c) {
1.208 - case '\n':
1.209 - skip_state = after_endl;
1.210 - return false;
1.211 - default:
1.212 - return false;
1.213 - }
1.214 - }
1.215 - return false;
1.216 - }
1.217 -
1.218 - virtual int underflow() {
1.219 - char c;
1.220 - if (_is.read(&c, 1)) {
1.221 - _is.putback(c);
1.222 - if (c == '@') {
1.223 - return EOF;
1.224 - }
1.225 - } else {
1.226 - return EOF;
1.227 - }
1.228 - char_type *ptr;
1.229 - for (ptr = base(); ptr != eptr(); ++ptr) {
1.230 - if (_is.read(&c, 1)) {
1.231 - if (c == '\n') ++_num;
1.232 - if (put_char(c)) {
1.233 - *ptr = c;
1.234 - } else {
1.235 - if (skip_state == after_endl && c == '@') {
1.236 - _is.putback('@');
1.237 - break;
1.238 - }
1.239 - --ptr;
1.240 - }
1.241 - } else {
1.242 - break;
1.243 - }
1.244 - }
1.245 - setg(base(), base(), ptr);
1.246 - return *base();
1.247 - }
1.248 -
1.249 - virtual int sync() {
1.250 - return EOF;
1.251 - }
1.252 - };
1.253 -
1.254 - public:
1.255 -
1.256 - /// \brief Abstract base class for reading a section.
1.257 - ///
1.258 - /// This class has an \c header() member function what get a
1.259 - /// header line string and decides if it want to process the next
1.260 - /// section. Several SectionReaders can be attached to an LemonReader
1.261 - /// and the first attached what can process the section will be used.
1.262 - /// Its \c read() member will called with a stream contains the section.
1.263 - /// From this stream the empty lines and comments are filtered out.
1.264 - class SectionReader {
1.265 - friend class LemonReader;
1.266 - protected:
1.267 - /// \brief Constructor for SectionReader.
1.268 - ///
1.269 - /// Constructor for SectionReader. It attach this reader to
1.270 - /// the given LemonReader.
1.271 - SectionReader(LemonReader& reader) {
1.272 - reader.attach(*this);
1.273 - }
1.274 -
1.275 - /// \brief Gives back true when the SectionReader can process
1.276 - /// the section with the given header line.
1.277 - ///
1.278 - /// It gives back true when the SectionReader can process
1.279 - /// the section with the given header line.
1.280 - virtual bool header(const std::string& line) = 0;
1.281 -
1.282 - /// \brief Reader function of the section.
1.283 - ///
1.284 - /// It reads the content of the section.
1.285 - virtual void read(std::istream& is) = 0;
1.286 - };
1.287 -
1.288 - /// \brief Constructor for LemonReader.
1.289 - ///
1.290 - /// Constructor for LemonReader which reads from the given stream.
1.291 - LemonReader(std::istream& _is)
1.292 - : is(&_is), own_is(false) {}
1.293 -
1.294 - /// \brief Constructor for LemonReader.
1.295 - ///
1.296 - /// Constructor for LemonReader which reads from the given file.
1.297 - LemonReader(const std::string& filename)
1.298 - : is(0), own_is(true) {
1.299 - is = new std::ifstream(filename.c_str());
1.300 - }
1.301 -
1.302 - /// \brief Desctructor for LemonReader.
1.303 - ///
1.304 - /// Desctructor for LemonReader.
1.305 - ~LemonReader() {
1.306 - if (own_is) {
1.307 - delete is;
1.308 - }
1.309 - }
1.310 -
1.311 - private:
1.312 - LemonReader(const LemonReader&);
1.313 - void operator=(const LemonReader&);
1.314 -
1.315 - void attach(SectionReader& reader) {
1.316 - readers.push_back(&reader);
1.317 - }
1.318 -
1.319 - public:
1.320 - /// \brief Executes the LemonReader.
1.321 - ///
1.322 - /// It executes the LemonReader.
1.323 - void run() {
1.324 - int line_num = 0;
1.325 - std::string line;
1.326 - try {
1.327 - while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
1.328 - SectionReaders::iterator it;
1.329 - for (it = readers.begin(); it != readers.end(); ++it) {
1.330 - if ((*it)->header(line)) {
1.331 - char buf[2048];
1.332 - FilterStreamBuf buffer(*is, line_num);
1.333 - buffer.pubsetbuf(buf, sizeof(buf));
1.334 - std::istream is(&buffer);
1.335 - (*it)->read(is);
1.336 - break;
1.337 - }
1.338 - }
1.339 - }
1.340 - } catch (DataFormatError& error) {
1.341 - error.line(line_num);
1.342 - throw error;
1.343 - }
1.344 - }
1.345 -
1.346 -
1.347 - private:
1.348 -
1.349 - std::istream* is;
1.350 - bool own_is;
1.351 -
1.352 - typedef std::vector<SectionReader*> SectionReaders;
1.353 - SectionReaders readers;
1.354 -
1.355 - };
1.356 -
1.357 - /// \brief Helper class for implementing the common SectionReaders.
1.358 - ///
1.359 - /// Helper class for implementing the common SectionReaders.
1.360 - class CommonSectionReaderBase : public LemonReader::SectionReader {
1.361 - typedef LemonReader::SectionReader Parent;
1.362 - protected:
1.363 -
1.364 - /// \brief Constructor for CommonSectionReaderBase.
1.365 - ///
1.366 - /// Constructor for CommonSectionReaderBase. It attach this reader to
1.367 - /// the given LemonReader.
1.368 - CommonSectionReaderBase(LemonReader& _reader)
1.369 - : Parent(_reader) {}
1.370 -
1.371 - template <typename _Item>
1.372 - class ReaderBase;
1.373 -
1.374 - template <typename _Item>
1.375 - class InverterBase : public ReaderBase<_Item> {
1.376 - public:
1.377 - typedef _Item Item;
1.378 - virtual void read(std::istream&, const Item&) = 0;
1.379 - virtual Item read(std::istream&) const = 0;
1.380 -
1.381 - virtual InverterBase<_Item>* getInverter() {
1.382 - return this;
1.383 - }
1.384 - };
1.385 -
1.386 - template <typename _Item, typename _Map, typename _Reader>
1.387 - class MapReaderInverter : public InverterBase<_Item> {
1.388 - public:
1.389 - typedef _Item Item;
1.390 - typedef _Reader Reader;
1.391 - typedef typename Reader::Value Value;
1.392 - typedef _Map Map;
1.393 - typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
1.394 -
1.395 - typename SmartReference<Map>::Type map;
1.396 - Reader reader;
1.397 - Inverse inverse;
1.398 -
1.399 - MapReaderInverter(typename SmartParameter<Map>::Type _map,
1.400 - const Reader& _reader)
1.401 - : map(_map), reader(_reader) {}
1.402 -
1.403 - virtual ~MapReaderInverter() {}
1.404 -
1.405 - virtual void read(std::istream& is, const Item& item) {
1.406 - Value value;
1.407 - reader.read(is, value);
1.408 - map.set(item, value);
1.409 - typename Inverse::iterator it = inverse.find(value);
1.410 - if (it == inverse.end()) {
1.411 - inverse.insert(std::make_pair(value, item));
1.412 - } else {
1.413 - throw DataFormatError("Multiple ID occurence");
1.414 - }
1.415 - }
1.416 -
1.417 - virtual Item read(std::istream& is) const {
1.418 - Value value;
1.419 - reader.read(is, value);
1.420 - typename Inverse::const_iterator it = inverse.find(value);
1.421 - if (it != inverse.end()) {
1.422 - return it->second;
1.423 - } else {
1.424 - throw DataFormatError("Invalid ID error");
1.425 - }
1.426 - }
1.427 - };
1.428 -
1.429 - template <typename _Item, typename _Reader>
1.430 - class SkipReaderInverter : public InverterBase<_Item> {
1.431 - public:
1.432 - typedef _Item Item;
1.433 - typedef _Reader Reader;
1.434 - typedef typename Reader::Value Value;
1.435 - typedef std::map<Value, Item, _reader_bits::Less<Value> > Inverse;
1.436 -
1.437 - Reader reader;
1.438 -
1.439 - SkipReaderInverter(const Reader& _reader)
1.440 - : reader(_reader) {}
1.441 -
1.442 - virtual ~SkipReaderInverter() {}
1.443 -
1.444 - virtual void read(std::istream& is, const Item& item) {
1.445 - Value value;
1.446 - reader.read(is, value);
1.447 - typename Inverse::iterator it = inverse.find(value);
1.448 - if (it == inverse.end()) {
1.449 - inverse.insert(std::make_pair(value, item));
1.450 - } else {
1.451 - throw DataFormatError("Multiple ID occurence error");
1.452 - }
1.453 - }
1.454 -
1.455 - virtual Item read(std::istream& is) const {
1.456 - Value value;
1.457 - reader.read(is, value);
1.458 - typename Inverse::const_iterator it = inverse.find(value);
1.459 - if (it != inverse.end()) {
1.460 - return it->second;
1.461 - } else {
1.462 - throw DataFormatError("Invalid ID error");
1.463 - }
1.464 - }
1.465 -
1.466 - private:
1.467 - Inverse inverse;
1.468 - };
1.469 -
1.470 - template <typename _Item>
1.471 - class ReaderBase {
1.472 - public:
1.473 - typedef _Item Item;
1.474 -
1.475 - virtual ~ReaderBase() {}
1.476 -
1.477 - virtual void read(std::istream& is, const Item& item) = 0;
1.478 - virtual InverterBase<_Item>* getInverter() = 0;
1.479 - };
1.480 -
1.481 - template <typename _Item, typename _Map, typename _Reader>
1.482 - class MapReader : public ReaderBase<_Item> {
1.483 - public:
1.484 - typedef _Map Map;
1.485 - typedef _Reader Reader;
1.486 - typedef typename Reader::Value Value;
1.487 - typedef _Item Item;
1.488 -
1.489 - typename SmartReference<Map>::Type map;
1.490 - Reader reader;
1.491 -
1.492 - MapReader(typename SmartParameter<Map>::Type _map,
1.493 - const Reader& _reader)
1.494 - : map(_map), reader(_reader) {}
1.495 -
1.496 - virtual ~MapReader() {}
1.497 -
1.498 - virtual void read(std::istream& is, const Item& item) {
1.499 - Value value;
1.500 - reader.read(is, value);
1.501 - map.set(item, value);
1.502 - }
1.503 -
1.504 - virtual InverterBase<_Item>* getInverter() {
1.505 - return new MapReaderInverter<Item, Map, Reader>(map, reader);
1.506 - }
1.507 - };
1.508 -
1.509 -
1.510 - template <typename _Item, typename _Reader>
1.511 - class SkipReader : public ReaderBase<_Item> {
1.512 - public:
1.513 - typedef _Reader Reader;
1.514 - typedef typename Reader::Value Value;
1.515 - typedef _Item Item;
1.516 -
1.517 - Reader reader;
1.518 - SkipReader(const Reader& _reader) : reader(_reader) {}
1.519 -
1.520 - virtual ~SkipReader() {}
1.521 -
1.522 - virtual void read(std::istream& is, const Item&) {
1.523 - Value value;
1.524 - reader.read(is, value);
1.525 - }
1.526 -
1.527 - virtual InverterBase<Item>* getInverter() {
1.528 - return new SkipReaderInverter<Item, Reader>(reader);
1.529 - }
1.530 - };
1.531 -
1.532 - template <typename _Item>
1.533 - class IdReaderBase {
1.534 - public:
1.535 - typedef _Item Item;
1.536 - virtual Item read(std::istream& is) const = 0;
1.537 - };
1.538 -
1.539 - template <typename _Item, typename _BoxedIdReader>
1.540 - class IdReader : public IdReaderBase<_Item> {
1.541 - public:
1.542 - typedef _Item Item;
1.543 - typedef _BoxedIdReader BoxedIdReader;
1.544 -
1.545 - const BoxedIdReader& boxedIdReader;
1.546 -
1.547 - IdReader(const BoxedIdReader& _boxedIdReader)
1.548 - : boxedIdReader(_boxedIdReader) {}
1.549 -
1.550 - virtual Item read(std::istream& is) const {
1.551 - return boxedIdReader.readId(is, Item());
1.552 - }
1.553 - };
1.554 -
1.555 - class ValueReaderBase {
1.556 - public:
1.557 - virtual void read(std::istream&) {};
1.558 - };
1.559 -
1.560 - template <typename _Value, typename _Reader>
1.561 - class ValueReader : public ValueReaderBase {
1.562 - public:
1.563 - typedef _Value Value;
1.564 - typedef _Reader Reader;
1.565 -
1.566 - ValueReader(Value& _value, const Reader& _reader)
1.567 - : value(_value), reader(_reader) {}
1.568 -
1.569 - virtual void read(std::istream& is) {
1.570 - reader.read(is, value);
1.571 - }
1.572 - private:
1.573 - Value& value;
1.574 - Reader reader;
1.575 - };
1.576 -
1.577 - };
1.578 -
1.579 - /// \ingroup io_group
1.580 - /// \brief SectionReader for reading a graph's nodeset.
1.581 - ///
1.582 - /// The lemon format can store multiple graph nodesets with several maps.
1.583 - /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
1.584 - /// \c nodeset_id may be empty.
1.585 - ///
1.586 - /// The first line of the section contains the names of the maps separated
1.587 - /// with white spaces. Each next lines describes a node in the nodeset, and
1.588 - /// contains the mapped values for each map.
1.589 - ///
1.590 - /// If the nodeset contains an \c "id" named map then it will be regarded
1.591 - /// as id map. This map should contain only unique values and when the
1.592 - /// \c readId() member will read a value from the given stream it will
1.593 - /// give back that node which is mapped to this value.
1.594 - ///
1.595 - /// \relates LemonReader
1.596 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.597 - class NodeSetReader : public CommonSectionReaderBase {
1.598 - typedef CommonSectionReaderBase Parent;
1.599 - public:
1.600 -
1.601 - typedef _Graph Graph;
1.602 - typedef _Traits Traits;
1.603 - typedef typename Graph::Node Node;
1.604 - typedef typename Traits::Skipper DefaultSkipper;
1.605 -
1.606 - /// \brief Constructor.
1.607 - ///
1.608 - /// Constructor for NodeSetReader. It creates the NodeSetReader and
1.609 - /// attach it into the given LemonReader. The nodeset reader will
1.610 - /// add the readed nodes to the given Graph. The reader will read
1.611 - /// the section when the \c section_id and the \c _id are the same.
1.612 - NodeSetReader(LemonReader& _reader,
1.613 - typename SmartParameter<Graph>::Type _graph,
1.614 - const std::string& _id = std::string(),
1.615 - const DefaultSkipper& _skipper = DefaultSkipper())
1.616 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {}
1.617 -
1.618 -
1.619 - /// \brief Destructor.
1.620 - ///
1.621 - /// Destructor for NodeSetReader.
1.622 - virtual ~NodeSetReader() {
1.623 - for (typename MapReaders::iterator it = readers.begin();
1.624 - it != readers.end(); ++it) {
1.625 - delete it->second;
1.626 - }
1.627 - }
1.628 -
1.629 - private:
1.630 - NodeSetReader(const NodeSetReader&);
1.631 - void operator=(const NodeSetReader&);
1.632 -
1.633 - public:
1.634 -
1.635 - /// \brief Add a new node map reader command for the reader.
1.636 - ///
1.637 - /// Add a new node map reader command for the reader.
1.638 - template <typename Map>
1.639 - NodeSetReader& readNodeMap(std::string name, Map& map) {
1.640 - return _readMap<
1.641 - typename Traits::template Reader<typename Map::Value>, Map,
1.642 - typename SmartParameter<Map>::Type>(name, map);
1.643 - }
1.644 -
1.645 - template <typename Map>
1.646 - NodeSetReader& readNodeMap(std::string name, const Map& map) {
1.647 - return _readMap<
1.648 - typename Traits::template Reader<typename Map::Value>, Map,
1.649 - typename SmartParameter<Map>::Type>(name, map);
1.650 - }
1.651 -
1.652 - /// \brief Add a new node map reader command for the reader.
1.653 - ///
1.654 - /// Add a new node map reader command for the reader.
1.655 - template <typename Reader, typename Map>
1.656 - NodeSetReader& readNodeMap(std::string name, Map& map,
1.657 - const Reader& reader = Reader()) {
1.658 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
1.659 - (name, map, reader);
1.660 - }
1.661 -
1.662 - template <typename Reader, typename Map>
1.663 - NodeSetReader& readNodeMap(std::string name, const Map& map,
1.664 - const Reader& reader = Reader()) {
1.665 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
1.666 - (name, map, reader);
1.667 - }
1.668 -
1.669 - private:
1.670 -
1.671 - template <typename Reader, typename Map, typename MapParameter>
1.672 - NodeSetReader& _readMap(std::string name, MapParameter map,
1.673 - const Reader& reader = Reader()) {
1.674 - if (readers.find(name) != readers.end()) {
1.675 - ErrorMessage msg;
1.676 - msg << "Multiple read rule for node map: " << name;
1.677 - throw IOParameterError(msg.message());
1.678 - }
1.679 - readers.insert(
1.680 - make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
1.681 - return *this;
1.682 - }
1.683 -
1.684 - public:
1.685 -
1.686 - /// \brief Add a new node map skipper command for the reader.
1.687 - ///
1.688 - /// Add a new node map skipper command for the reader.
1.689 - template <typename Reader>
1.690 - NodeSetReader& skipNodeMap(std::string name,
1.691 - const Reader& reader = Reader()) {
1.692 - if (readers.find(name) != readers.end()) {
1.693 - ErrorMessage msg;
1.694 - msg << "Multiple read rule for node map: " << name;
1.695 - throw IOParameterError(msg.message());
1.696 - }
1.697 - readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader)));
1.698 - return *this;
1.699 - }
1.700 -
1.701 - protected:
1.702 -
1.703 - /// \brief Gives back true when the SectionReader can process
1.704 - /// the section with the given header line.
1.705 - ///
1.706 - /// It gives back true when the header line starts with \c \@nodeset,
1.707 - /// and the header line's id and the nodeset's id are the same.
1.708 - virtual bool header(const std::string& line) {
1.709 - std::istringstream ls(line);
1.710 - std::string command;
1.711 - std::string name;
1.712 - ls >> command >> name;
1.713 - return command == "@nodeset" && name == id;
1.714 - }
1.715 -
1.716 - /// \brief Reader function of the section.
1.717 - ///
1.718 - /// It reads the content of the section.
1.719 - virtual void read(std::istream& is) {
1.720 - std::vector<ReaderBase<Node>* > index;
1.721 - std::string line;
1.722 -
1.723 - getline(is, line);
1.724 - std::istringstream ls(line);
1.725 - while (ls >> id) {
1.726 - typename MapReaders::iterator it = readers.find(id);
1.727 - if (it != readers.end()) {
1.728 - index.push_back(it->second);
1.729 - } else {
1.730 - index.push_back(&skipper);
1.731 - }
1.732 - if (id == "id" && inverter.get() == 0) {
1.733 - inverter.reset(index.back()->getInverter());
1.734 - index.back() = inverter.get();
1.735 - }
1.736 - }
1.737 - while (getline(is, line)) {
1.738 - Node node = graph.addNode();
1.739 - std::istringstream ls(line);
1.740 - for (int i = 0; i < (int)index.size(); ++i) {
1.741 - index[i]->read(ls, node);
1.742 - }
1.743 - }
1.744 - }
1.745 -
1.746 - public:
1.747 -
1.748 - /// \brief Returns true if the nodeset can give back the node by its id.
1.749 - ///
1.750 - /// Returns true if the nodeset can give back the node by its id.
1.751 - /// It is possible only if an "id" named map was read.
1.752 - bool isIdReader() const {
1.753 - return inverter.get() != 0;
1.754 - }
1.755 -
1.756 - /// \brief Gives back the node by its id.
1.757 - ///
1.758 - /// It reads an id from the stream and gives back which node belongs to
1.759 - /// it. It is possible only if there was read an "id" named map.
1.760 - Node readId(std::istream& is, Node = Node()) const {
1.761 - return inverter->read(is);
1.762 - }
1.763 -
1.764 - private:
1.765 -
1.766 - typedef std::map<std::string, ReaderBase<Node>*> MapReaders;
1.767 - MapReaders readers;
1.768 -
1.769 - typename SmartReference<Graph>::Type graph;
1.770 - std::string id;
1.771 - SkipReader<Node, DefaultSkipper> skipper;
1.772 -
1.773 - std::auto_ptr<InverterBase<Node> > inverter;
1.774 - };
1.775 -
1.776 - /// \ingroup io_group
1.777 - /// \brief SectionReader for reading a graph's edgeset.
1.778 - ///
1.779 - /// The lemon format can store multiple graph edgesets with several maps.
1.780 - /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
1.781 - /// \c edgeset_id may be empty.
1.782 - ///
1.783 - /// The first line of the section contains the names of the maps separated
1.784 - /// with white spaces. Each next lines describes an edge in the edgeset. The
1.785 - /// line contains the source and the target nodes' id and the mapped
1.786 - /// values for each map.
1.787 - ///
1.788 - /// If the edgeset contains an \c "id" named map then it will be regarded
1.789 - /// as id map. This map should contain only unique values and when the
1.790 - /// \c readId() member will read a value from the given stream it will
1.791 - /// give back that edge which is mapped to this value.
1.792 - ///
1.793 - /// The edgeset reader needs a node id reader to identify which nodes
1.794 - /// have to be connected. If a NodeSetReader reads an "id" named map,
1.795 - /// it will be able to resolve the nodes by ids.
1.796 - ///
1.797 - /// \relates LemonReader
1.798 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.799 - class EdgeSetReader : public CommonSectionReaderBase {
1.800 - typedef CommonSectionReaderBase Parent;
1.801 - public:
1.802 -
1.803 - typedef _Graph Graph;
1.804 - typedef _Traits Traits;
1.805 - typedef typename Graph::Node Node;
1.806 - typedef typename Graph::Edge Edge;
1.807 - typedef typename Traits::Skipper DefaultSkipper;
1.808 -
1.809 - /// \brief Constructor.
1.810 - ///
1.811 - /// Constructor for EdgeSetReader. It creates the EdgeSetReader and
1.812 - /// attach it into the given LemonReader. The edgeset reader will
1.813 - /// add the readed edges to the given Graph. It will use the given
1.814 - /// node id reader to read the source and target nodes of the edges.
1.815 - /// The reader will read the section only if the \c _id and the
1.816 - /// \c edgset_id are the same.
1.817 - template <typename NodeIdReader>
1.818 - EdgeSetReader(LemonReader& _reader,
1.819 - typename SmartParameter<Graph>::Type _graph,
1.820 - const NodeIdReader& _nodeIdReader,
1.821 - const std::string& _id = std::string(),
1.822 - const DefaultSkipper& _skipper = DefaultSkipper())
1.823 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
1.824 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
1.825 -
1.826 - /// \brief Destructor.
1.827 - ///
1.828 - /// Destructor for EdgeSetReader.
1.829 - virtual ~EdgeSetReader() {
1.830 - for (typename MapReaders::iterator it = readers.begin();
1.831 - it != readers.end(); ++it) {
1.832 - delete it->second;
1.833 - }
1.834 - }
1.835 -
1.836 - private:
1.837 - EdgeSetReader(const EdgeSetReader&);
1.838 - void operator=(const EdgeSetReader&);
1.839 -
1.840 - public:
1.841 -
1.842 - /// \brief Add a new edge map reader command for the reader.
1.843 - ///
1.844 - /// Add a new edge map reader command for the reader.
1.845 - template <typename Map>
1.846 - EdgeSetReader& readEdgeMap(std::string name, Map& map) {
1.847 - return _readMap<
1.848 - typename Traits::template Reader<typename Map::Value>, Map,
1.849 - typename SmartParameter<Map>::Type>(name, map);
1.850 - }
1.851 -
1.852 - template <typename Map>
1.853 - EdgeSetReader& readEdgeMap(std::string name, const Map& map) {
1.854 - return _readMap<
1.855 - typename Traits::template Reader<typename Map::Value>, Map,
1.856 - typename SmartParameter<Map>::Type>(name, map);
1.857 - }
1.858 -
1.859 - /// \brief Add a new edge map reader command for the reader.
1.860 - ///
1.861 - /// Add a new edge map reader command for the reader.
1.862 - template <typename Reader, typename Map>
1.863 - EdgeSetReader& readEdgeMap(std::string name, Map& map,
1.864 - const Reader& reader = Reader()) {
1.865 - return _readMap<Reader, Map,
1.866 - typename SmartParameter<Map>::Type>(name, map, reader);
1.867 - }
1.868 -
1.869 - template <typename Reader, typename Map>
1.870 - EdgeSetReader& readEdgeMap(std::string name, const Map& map,
1.871 - const Reader& reader = Reader()) {
1.872 - return _readMap<Reader, Map,
1.873 - typename SmartParameter<Map>::Type>(name, map, reader);
1.874 - }
1.875 -
1.876 - private:
1.877 -
1.878 - template <typename Reader, typename Map, typename MapParameter>
1.879 - EdgeSetReader& _readMap(std::string name, MapParameter map,
1.880 - const Reader& reader = Reader()) {
1.881 - if (readers.find(name) != readers.end()) {
1.882 - ErrorMessage msg;
1.883 - msg << "Multiple read rule for edge map: " << name;
1.884 - throw IOParameterError(msg.message());
1.885 - }
1.886 - readers.insert(
1.887 - make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
1.888 - return *this;
1.889 - }
1.890 -
1.891 - public:
1.892 -
1.893 - /// \brief Add a new edge map skipper command for the reader.
1.894 - ///
1.895 - /// Add a new edge map skipper command for the reader.
1.896 - template <typename Reader>
1.897 - EdgeSetReader& skipEdgeMap(std::string name,
1.898 - const Reader& reader = Reader()) {
1.899 - if (readers.find(name) != readers.end()) {
1.900 - ErrorMessage msg;
1.901 - msg << "Multiple read rule for edge map: " << name;
1.902 - throw IOParameterError(msg.message());
1.903 - }
1.904 - readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader)));
1.905 - return *this;
1.906 - }
1.907 -
1.908 - protected:
1.909 -
1.910 - /// \brief Gives back true when the SectionReader can process
1.911 - /// the section with the given header line.
1.912 - ///
1.913 - /// It gives back true when the header line starts with \c \@edgeset,
1.914 - /// and the header line's id and the edgeset's id are the same.
1.915 - virtual bool header(const std::string& line) {
1.916 - std::istringstream ls(line);
1.917 - std::string command;
1.918 - std::string name;
1.919 - ls >> command >> name;
1.920 - return command == "@edgeset" && name == id;
1.921 - }
1.922 -
1.923 - /// \brief Reader function of the section.
1.924 - ///
1.925 - /// It reads the content of the section.
1.926 - virtual void read(std::istream& is) {
1.927 - std::vector<ReaderBase<Edge>* > index;
1.928 - std::string line;
1.929 -
1.930 - getline(is, line);
1.931 - std::istringstream ls(line);
1.932 - while (ls >> id) {
1.933 - typename MapReaders::iterator it = readers.find(id);
1.934 - if (it != readers.end()) {
1.935 - index.push_back(it->second);
1.936 - } else {
1.937 - index.push_back(&skipper);
1.938 - }
1.939 - if (id == "id" && inverter.get() == 0) {
1.940 - inverter.reset(index.back()->getInverter());
1.941 - index.back() = inverter.get();
1.942 - }
1.943 - }
1.944 - while (getline(is, line)) {
1.945 - std::istringstream ls(line);
1.946 - Node from = nodeIdReader->read(ls);
1.947 - Node to = nodeIdReader->read(ls);
1.948 - Edge edge = graph.addEdge(from, to);
1.949 - for (int i = 0; i < (int)index.size(); ++i) {
1.950 - index[i]->read(ls, edge);
1.951 - }
1.952 - }
1.953 - }
1.954 -
1.955 - public:
1.956 -
1.957 - /// \brief Returns true if the edgeset can give back the edge by its id.
1.958 - ///
1.959 - /// Returns true if the edgeset can give back the edge by its id.
1.960 - /// It is possible only if an "id" named map was read.
1.961 - bool isIdReader() const {
1.962 - return inverter.get() != 0;
1.963 - }
1.964 -
1.965 - /// \brief Gives back the edge by its id.
1.966 - ///
1.967 - /// It reads an id from the stream and gives back which edge belongs to
1.968 - /// it. It is possible only if there was read an "id" named map.
1.969 - Edge readId(std::istream& is, Edge = Edge()) const {
1.970 - return inverter->read(is);
1.971 - }
1.972 -
1.973 - private:
1.974 -
1.975 - typedef std::map<std::string, ReaderBase<Edge>*> MapReaders;
1.976 - MapReaders readers;
1.977 -
1.978 - typename SmartReference<Graph>::Type graph;
1.979 - std::string id;
1.980 - SkipReader<Edge, DefaultSkipper> skipper;
1.981 -
1.982 - std::auto_ptr<InverterBase<Edge> > inverter;
1.983 - std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
1.984 - };
1.985 -
1.986 - /// \ingroup io_group
1.987 - /// \brief SectionReader for reading a undirected graph's edgeset.
1.988 - ///
1.989 - /// The lemon format can store multiple undirected edgesets with several
1.990 - /// maps. The undirected edgeset section's header line is \c \@undiredgeset
1.991 - /// \c undiredgeset_id, but the \c undiredgeset_id may be empty.
1.992 - ///
1.993 - /// The first line of the section contains the names of the maps separated
1.994 - /// with white spaces. Each next lines describes an edge in the edgeset. The
1.995 - /// line contains the connected nodes' id and the mapped values for each map.
1.996 - ///
1.997 - /// The section can handle the directed as a syntactical sugar. Two
1.998 - /// undirected edge map describes one directed edge map. This two maps
1.999 - /// are the forward map and the backward map and the names of this map
1.1000 - /// is near the same just with a prefix \c '+' or \c '-' character
1.1001 - /// difference.
1.1002 - ///
1.1003 - /// If the edgeset contains an \c "id" named map then it will be regarded
1.1004 - /// as id map. This map should contain only unique values and when the
1.1005 - /// \c readId() member will read a value from the given stream it will
1.1006 - /// give back that undiricted edge which is mapped to this value.
1.1007 - ///
1.1008 - /// The undirected edgeset reader needs a node id reader to identify which
1.1009 - /// nodes have to be connected. If a NodeSetReader reads an "id" named map,
1.1010 - /// it will be able to resolve the nodes by ids.
1.1011 - ///
1.1012 - /// \relates LemonReader
1.1013 - template <typename _Graph, typename _Traits = DefaultReaderTraits>
1.1014 - class UndirEdgeSetReader : public CommonSectionReaderBase {
1.1015 - typedef CommonSectionReaderBase Parent;
1.1016 - public:
1.1017 -
1.1018 - typedef _Graph Graph;
1.1019 - typedef _Traits Traits;
1.1020 - typedef typename Graph::Node Node;
1.1021 - typedef typename Graph::Edge Edge;
1.1022 - typedef typename Graph::UndirEdge UndirEdge;
1.1023 - typedef typename Traits::Skipper DefaultSkipper;
1.1024 -
1.1025 - /// \brief Constructor.
1.1026 - ///
1.1027 - /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader
1.1028 - /// and attach it into the given LemonReader. The undirected edgeset
1.1029 - /// reader will add the readed undirected edges to the given Graph. It
1.1030 - /// will use the given node id reader to read the source and target
1.1031 - /// nodes of the edges. The reader will read the section only if the
1.1032 - /// \c _id and the \c undiredgset_id are the same.
1.1033 - template <typename NodeIdReader>
1.1034 - UndirEdgeSetReader(LemonReader& _reader,
1.1035 - typename SmartParameter<Graph>::Type _graph,
1.1036 - const NodeIdReader& _nodeIdReader,
1.1037 - const std::string& _id = std::string(),
1.1038 - const DefaultSkipper& _skipper = DefaultSkipper())
1.1039 - : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
1.1040 - nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {}
1.1041 -
1.1042 - /// \brief Destructor.
1.1043 - ///
1.1044 - /// Destructor for UndirEdgeSetReader.
1.1045 - virtual ~UndirEdgeSetReader() {
1.1046 - for (typename MapReaders::iterator it = readers.begin();
1.1047 - it != readers.end(); ++it) {
1.1048 - delete it->second;
1.1049 - }
1.1050 - }
1.1051 -
1.1052 - private:
1.1053 - UndirEdgeSetReader(const UndirEdgeSetReader&);
1.1054 - void operator=(const UndirEdgeSetReader&);
1.1055 -
1.1056 - public:
1.1057 -
1.1058 - /// \brief Add a new undirected edge map reader command for the reader.
1.1059 - ///
1.1060 - /// Add a new edge undirected map reader command for the reader.
1.1061 - template <typename Map>
1.1062 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) {
1.1063 - return _readMap<
1.1064 - typename Traits::template Reader<typename Map::Value>, Map,
1.1065 - typename SmartParameter<Map>::Type>(name, map);
1.1066 - }
1.1067 -
1.1068 - template <typename Map>
1.1069 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) {
1.1070 - return _readMap<
1.1071 - typename Traits::template Reader<typename Map::Value>, Map,
1.1072 - typename SmartParameter<Map>::Type>(name, map);
1.1073 - }
1.1074 -
1.1075 - /// \brief Add a new undirected edge map reader command for the reader.
1.1076 - ///
1.1077 - /// Add a new edge undirected map reader command for the reader.
1.1078 - template <typename Reader, typename Map>
1.1079 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map,
1.1080 - const Reader& reader = Reader()) {
1.1081 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type>
1.1082 - (name, map, reader);
1.1083 - }
1.1084 -
1.1085 - template <typename Reader, typename Map>
1.1086 - UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map,
1.1087 - const Reader& reader = Reader()) {
1.1088 - return _readMap<Reader, Map, typename SmartParameter<Map>::Type >
1.1089 - (name, map, reader);
1.1090 - }
1.1091 -
1.1092 - private:
1.1093 -
1.1094 - template <typename Reader, typename Map, typename MapParameter>
1.1095 - UndirEdgeSetReader& _readMap(std::string name, MapParameter map,
1.1096 - const Reader& reader = Reader()) {
1.1097 - if (readers.find(name) != readers.end()) {
1.1098 - ErrorMessage msg;
1.1099 - msg << "Multiple read rule for edge map: " << name;
1.1100 - throw IOParameterError(msg.message());
1.1101 - }
1.1102 - readers.insert(
1.1103 - make_pair(name, new MapReader<UndirEdge, Map, Reader>(map, reader)));
1.1104 - return *this;
1.1105 - }
1.1106 -
1.1107 - public:
1.1108 -
1.1109 - /// \brief Add a new undirected edge map skipper command for the reader.
1.1110 - ///
1.1111 - /// Add a new undirected edge map skipper command for the reader.
1.1112 - template <typename Reader>
1.1113 - UndirEdgeSetReader& skipUndirEdgeMap(std::string name,
1.1114 - const Reader& reader = Reader()) {
1.1115 - if (readers.find(name) != readers.end()) {
1.1116 - ErrorMessage msg;
1.1117 - msg << "Multiple read rule for node map: " << name;
1.1118 - throw IOParameterError(msg.message());
1.1119 - }
1.1120 - readers.insert(make_pair(name,
1.1121 - new SkipReader<UndirEdge, Reader>(reader)));
1.1122 - return *this;
1.1123 - }
1.1124 -
1.1125 - /// \brief Add a new directed edge map reader command for the reader.
1.1126 - ///
1.1127 - /// Add a new directed edge map reader command for the reader.
1.1128 - template <typename Map>
1.1129 - UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) {
1.1130 - return _readDirMap<
1.1131 - typename Traits::template Reader<typename Map::Value>, Map,
1.1132 - typename SmartParameter<Map>::Type>(name, map);
1.1133 - }
1.1134 -
1.1135 - template <typename Map>
1.1136 - UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) {
1.1137 - return _readDirMap<
1.1138 - typename Traits::template Reader<typename Map::Value>, Map,
1.1139 - typename SmartParameter<Map>::Type>(name, map);
1.1140 - }
1.1141 -
1.1142 - /// \brief Add a new directed edge map reader command for the reader.
1.1143 - ///
1.1144 - /// Add a new directed edge map reader command for the reader.
1.1145 - template <typename Reader, typename Map>
1.1146 - UndirEdgeSetReader& readEdgeMap(std::string name, Map& map,
1.1147 - const Reader& reader = Reader()) {
1.1148 - return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
1.1149 - (name, map, reader);
1.1150 - }
1.1151 -
1.1152 - template <typename Reader, typename Map>
1.1153 - UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map,
1.1154 - const Reader& reader = Reader()) {
1.1155 - return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type>
1.1156 - (name, map, reader);
1.1157 - }
1.1158 -
1.1159 - private:
1.1160 -
1.1161 - template <typename Reader, typename Map, typename MapParameter>
1.1162 - UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map,
1.1163 - const Reader& reader = Reader()) {
1.1164 - readMap("+" + name,
1.1165 - _reader_bits::writeComposeMap(map, forwardMap(graph)), reader);
1.1166 - readMap("-" + name,
1.1167 - _reader_bits::writeComposeMap(map, backwardMap(graph)), reader);
1.1168 - return *this;
1.1169 - }
1.1170 -
1.1171 - public:
1.1172 -
1.1173 - /// \brief Add a new directed edge map skipper command for the reader.
1.1174 - ///
1.1175 - /// Add a new directed edge map skipper command for the reader.
1.1176 - template <typename Reader>
1.1177 - UndirEdgeSetReader& skipEdgeMap(std::string name,
1.1178 - const Reader& reader = Reader()) {
1.1179 - skipMap("+" + name, reader);
1.1180 - skipMap("-" + name, reader);
1.1181 - return *this;
1.1182 - }
1.1183 -
1.1184 - protected:
1.1185 -
1.1186 - /// \brief Gives back true when the SectionReader can process
1.1187 - /// the section with the given header line.
1.1188 - ///
1.1189 - /// It gives back true when the header line starts with \c \@undiredgeset,
1.1190 - /// and the header line's id and the edgeset's id are the same.
1.1191 - virtual bool header(const std::string& line) {
1.1192 - std::istringstream ls(line);
1.1193 - std::string command;
1.1194 - std::string name;
1.1195 - ls >> command >> name;
1.1196 - return command == "@undiredgeset" && name == id;
1.1197 - }
1.1198 -
1.1199 - /// \brief Reader function of the section.
1.1200 - ///
1.1201 - /// It reads the content of the section.
1.1202 - virtual void read(std::istream& is) {
1.1203 - std::vector<ReaderBase<UndirEdge>* > index;
1.1204 - std::string line;
1.1205 -
1.1206 - getline(is, line);
1.1207 - std::istringstream ls(line);
1.1208 - while (ls >> id) {
1.1209 - typename MapReaders::iterator it = readers.find(id);
1.1210 - if (it != readers.end()) {
1.1211 - index.push_back(it->second);
1.1212 - } else {
1.1213 - index.push_back(&skipper);
1.1214 - }
1.1215 - if (id == "id" && inverter.get() == 0) {
1.1216 - inverter.reset(index.back()->getInverter());
1.1217 - index.back() = inverter.get();
1.1218 - }
1.1219 - }
1.1220 - while (getline(is, line)) {
1.1221 - std::istringstream ls(line);
1.1222 - Node from = nodeIdReader->read(ls);
1.1223 - Node to = nodeIdReader->read(ls);
1.1224 - UndirEdge edge = graph.addEdge(from, to);
1.1225 - for (int i = 0; i < (int)index.size(); ++i) {
1.1226 - index[i]->read(ls, edge);
1.1227 - }
1.1228 - }
1.1229 - }
1.1230 -
1.1231 - public:
1.1232 -
1.1233 - /// \brief Returns true if the edgeset can give back the edge by its id.
1.1234 - ///
1.1235 - /// Returns true if the edgeset can give back the undirected edge by its
1.1236 - /// id. It is possible only if an "id" named map was read.
1.1237 - bool isIdReader() const {
1.1238 - return inverter.get() != 0;
1.1239 - }
1.1240 -
1.1241 - /// \brief Gives back the undirected edge by its id.
1.1242 - ///
1.1243 - /// It reads an id from the stream and gives back which undirected edge
1.1244 - /// belongs to it. It is possible only if there was read an "id" named map.
1.1245 - UndirEdge readId(std::istream& is, UndirEdge = UndirEdge()) const {
1.1246 - return inverter->read(is);
1.1247 - }
1.1248 -
1.1249 - /// \brief Gives back the directed edge by its id.
1.1250 - ///
1.1251 - /// It reads an id from the stream and gives back which directed edge
1.1252 - /// belongs to it. The directed edge id is the \c '+' or \c '-' character
1.1253 - /// and the undirected edge id. It is possible only if there was read
1.1254 - /// an "id" named map.
1.1255 - Edge readId(std::istream& is, Edge = Edge()) const {
1.1256 - char c;
1.1257 - is >> c;
1.1258 - UndirEdge undirEdge = inverter->read(is);
1.1259 - if (c == '+') {
1.1260 - return graph.edgeWithSource(undirEdge, graph.source(undirEdge));
1.1261 - } else if (c == '-') {
1.1262 - return graph.edgeWithSource(undirEdge, graph.target(undirEdge));
1.1263 - } else {
1.1264 - throw DataFormatError("Wrong id format for edge "
1.1265 - "in undirected edgeset");
1.1266 - }
1.1267 - }
1.1268 -
1.1269 - private:
1.1270 -
1.1271 - typedef std::map<std::string, ReaderBase<UndirEdge>*> MapReaders;
1.1272 - MapReaders readers;
1.1273 -
1.1274 - typename SmartReference<Graph>::Type graph;
1.1275 - std::string id;
1.1276 - SkipReader<UndirEdge, DefaultSkipper> skipper;
1.1277 -
1.1278 - std::auto_ptr<InverterBase<UndirEdge> > inverter;
1.1279 - std::auto_ptr<IdReaderBase<Node> > nodeIdReader;
1.1280 - };
1.1281 -
1.1282 - /// \ingroup io_group
1.1283 - /// \brief SectionReader for reading labeled nodes.
1.1284 - ///
1.1285 - /// The nodes section's header line is \c \@nodes \c nodes_id, but the
1.1286 - /// \c nodes_id may be empty.
1.1287 - ///
1.1288 - /// Each line in the section contains the name of the node
1.1289 - /// and then the node id.
1.1290 - ///
1.1291 - /// \relates LemonReader
1.1292 - template <typename _Graph>
1.1293 - class NodeReader : public CommonSectionReaderBase {
1.1294 - typedef CommonSectionReaderBase Parent;
1.1295 - typedef _Graph Graph;
1.1296 - typedef typename Graph::Node Node;
1.1297 - public:
1.1298 -
1.1299 - /// \brief Constructor.
1.1300 - ///
1.1301 - /// Constructor for NodeReader. It creates the NodeReader and
1.1302 - /// attach it into the given LemonReader. It will use the given
1.1303 - /// node id reader to give back the nodes. The reader will read the
1.1304 - /// section only if the \c _id and the \c nodes_id are the same.
1.1305 - template <typename _IdReader>
1.1306 - NodeReader(LemonReader& _reader, const _IdReader& _idReader,
1.1307 - const std::string& _id = std::string())
1.1308 - : Parent(_reader), id(_id),
1.1309 - idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {}
1.1310 -
1.1311 - /// \brief Destructor.
1.1312 - ///
1.1313 - /// Destructor for NodeReader.
1.1314 - virtual ~NodeReader() {}
1.1315 -
1.1316 - private:
1.1317 - NodeReader(const NodeReader&);
1.1318 - void operator=(const NodeReader&);
1.1319 -
1.1320 - public:
1.1321 -
1.1322 - /// \brief Add a node reader command for the NodeReader.
1.1323 - ///
1.1324 - /// Add a node reader command for the NodeReader.
1.1325 - void readNode(const std::string& name, Node& item) {
1.1326 - if (readers.find(name) != readers.end()) {
1.1327 - ErrorMessage msg;
1.1328 - msg << "Multiple read rule for node: " << name;
1.1329 - throw IOParameterError(msg.message());
1.1330 - }
1.1331 - readers.insert(make_pair(name, &item));
1.1332 - }
1.1333 -
1.1334 - protected:
1.1335 -
1.1336 - /// \brief Gives back true when the SectionReader can process
1.1337 - /// the section with the given header line.
1.1338 - ///
1.1339 - /// It gives back true when the header line start with \c \@nodes,
1.1340 - /// and the header line's id and the reader's id are the same.
1.1341 - virtual bool header(const std::string& line) {
1.1342 - std::istringstream ls(line);
1.1343 - std::string command;
1.1344 - std::string name;
1.1345 - ls >> command >> name;
1.1346 - return command == "@nodes" && name == id;
1.1347 - }
1.1348 -
1.1349 - /// \brief Reader function of the section.
1.1350 - ///
1.1351 - /// It reads the content of the section.
1.1352 - virtual void read(std::istream& is) {
1.1353 - std::string line;
1.1354 - while (getline(is, line)) {
1.1355 - std::istringstream ls(line);
1.1356 - std::string id;
1.1357 - ls >> id;
1.1358 - typename NodeReaders::iterator it = readers.find(id);
1.1359 - if (it != readers.end()) {
1.1360 - *(it->second) = idReader->read(ls);
1.1361 - }
1.1362 - }
1.1363 - }
1.1364 -
1.1365 - private:
1.1366 -
1.1367 - std::string id;
1.1368 -
1.1369 - typedef std::map<std::string, Node*> NodeReaders;
1.1370 - NodeReaders readers;
1.1371 - std::auto_ptr<IdReaderBase<Node> > idReader;
1.1372 - };
1.1373 -
1.1374 - /// \ingroup io_group
1.1375 - /// \brief SectionReader for reading labeled edges.
1.1376 - ///
1.1377 - /// The edges section's header line is \c \@edges \c edges_id, but the
1.1378 - /// \c edges_id may be empty.
1.1379 - ///
1.1380 - /// Each line in the section contains the name of the edge
1.1381 - /// and then the edge id.
1.1382 - ///
1.1383 - /// \relates LemonReader
1.1384 - template <typename _Graph>
1.1385 - class EdgeReader : public CommonSectionReaderBase {
1.1386 - typedef CommonSectionReaderBase Parent;
1.1387 - typedef _Graph Graph;
1.1388 - typedef typename Graph::Edge Edge;
1.1389 - public:
1.1390 -
1.1391 - /// \brief Constructor.
1.1392 - ///
1.1393 - /// Constructor for EdgeReader. It creates the EdgeReader and
1.1394 - /// attach it into the given LemonReader. It will use the given
1.1395 - /// edge id reader to give back the edges. The reader will read the
1.1396 - /// section only if the \c _id and the \c edges_id are the same.
1.1397 - template <typename _IdReader>
1.1398 - EdgeReader(LemonReader& _reader, const _IdReader& _idReader,
1.1399 - const std::string& _id = std::string())
1.1400 - : Parent(_reader), id(_id),
1.1401 - idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {}
1.1402 -
1.1403 - /// \brief Destructor.
1.1404 - ///
1.1405 - /// Destructor for EdgeReader.
1.1406 - virtual ~EdgeReader() {}
1.1407 - private:
1.1408 - EdgeReader(const EdgeReader&);
1.1409 - void operator=(const EdgeReader&);
1.1410 -
1.1411 - public:
1.1412 -
1.1413 - /// \brief Add an edge reader command for the EdgeReader.
1.1414 - ///
1.1415 - /// Add an edge reader command for the EdgeReader.
1.1416 - void readEdge(const std::string& name, Edge& item) {
1.1417 - if (readers.find(name) != readers.end()) {
1.1418 - ErrorMessage msg;
1.1419 - msg << "Multiple read rule for edge: " << name;
1.1420 - throw IOParameterError(msg.message());
1.1421 - }
1.1422 - readers.insert(make_pair(name, &item));
1.1423 - }
1.1424 -
1.1425 - protected:
1.1426 -
1.1427 - /// \brief Gives back true when the SectionReader can process
1.1428 - /// the section with the given header line.
1.1429 - ///
1.1430 - /// It gives back true when the header line start with \c \@edges,
1.1431 - /// and the header line's id and the reader's id are the same.
1.1432 - virtual bool header(const std::string& line) {
1.1433 - std::istringstream ls(line);
1.1434 - std::string command;
1.1435 - std::string name;
1.1436 - ls >> command >> name;
1.1437 - return command == "@edges" && name == id;
1.1438 - }
1.1439 -
1.1440 - /// \brief Reader function of the section.
1.1441 - ///
1.1442 - /// It reads the content of the section.
1.1443 - virtual void read(std::istream& is) {
1.1444 - std::string line;
1.1445 - while (getline(is, line)) {
1.1446 - std::istringstream ls(line);
1.1447 - std::string id;
1.1448 - ls >> id;
1.1449 - typename EdgeReaders::iterator it = readers.find(id);
1.1450 - if (it != readers.end()) {
1.1451 - *(it->second) = idReader->read(ls);
1.1452 - }
1.1453 - }
1.1454 - }
1.1455 -
1.1456 - private:
1.1457 -
1.1458 - std::string id;
1.1459 -
1.1460 - typedef std::map<std::string, Edge*> EdgeReaders;
1.1461 - EdgeReaders readers;
1.1462 - std::auto_ptr<IdReaderBase<Edge> > idReader;
1.1463 - };
1.1464 -
1.1465 - /// \ingroup io_group
1.1466 - /// \brief SectionReader for reading labeled undirected edges.
1.1467 - ///
1.1468 - /// The undirected edges section's header line is \c \@undiredges
1.1469 - /// \c undiredges_id, but the \c undiredges_id may be empty.
1.1470 - ///
1.1471 - /// Each line in the section contains the name of the undirected edge
1.1472 - /// and then the undirected edge id.
1.1473 - ///
1.1474 - /// \relates LemonReader
1.1475 - template <typename _Graph>
1.1476 - class UndirEdgeReader : public CommonSectionReaderBase {
1.1477 - typedef CommonSectionReaderBase Parent;
1.1478 - typedef _Graph Graph;
1.1479 - typedef typename Graph::Edge Edge;
1.1480 - typedef typename Graph::UndirEdge UndirEdge;
1.1481 - public:
1.1482 -
1.1483 - /// \brief Constructor.
1.1484 - ///
1.1485 - /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and
1.1486 - /// attach it into the given LemonReader. It will use the given
1.1487 - /// undirected edge id reader to give back the edges. The reader will
1.1488 - /// read the section only if the \c _id and the \c undiredges_id are
1.1489 - /// the same.
1.1490 - template <typename _IdReader>
1.1491 - UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader,
1.1492 - const std::string& _id = std::string())
1.1493 - : Parent(_reader), id(_id),
1.1494 - undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
1.1495 - edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
1.1496 - {}
1.1497 -
1.1498 - /// \brief Destructor.
1.1499 - ///
1.1500 - /// Destructor for UndirEdgeReader.
1.1501 - virtual ~UndirEdgeReader() {}
1.1502 - private:
1.1503 - UndirEdgeReader(const UndirEdgeReader&);
1.1504 - void operator=(const UndirEdgeReader&);
1.1505 -
1.1506 - public:
1.1507 -
1.1508 - /// \brief Add an undirected edge reader command for the UndirEdgeReader.
1.1509 - ///
1.1510 - /// Add an undirected edge reader command for the UndirEdgeReader.
1.1511 - void readUndirEdge(const std::string& name, UndirEdge& item) {
1.1512 - if (undirEdgeReaders.find(name) != undirEdgeReaders.end()) {
1.1513 - ErrorMessage msg;
1.1514 - msg << "Multiple read rule for undirected edge: " << name;
1.1515 - throw IOParameterError(msg.message());
1.1516 - }
1.1517 - undirEdgeReaders.insert(make_pair(name, &item));
1.1518 - }
1.1519 -
1.1520 - /// \brief Add an edge reader command for the UndirEdgeReader.
1.1521 - ///
1.1522 - /// Add an edge reader command for the UndirEdgeReader.
1.1523 - void readEdge(const std::string& name, Edge& item) {
1.1524 - if (edgeReaders.find(name) != edgeReaders.end()) {
1.1525 - ErrorMessage msg;
1.1526 - msg << "Multiple read rule for edge: " << name;
1.1527 - throw IOParameterError(msg.message());
1.1528 - }
1.1529 - edgeReaders.insert(make_pair(name, &item));
1.1530 - }
1.1531 -
1.1532 - protected:
1.1533 -
1.1534 - /// \brief Gives back true when the SectionReader can process
1.1535 - /// the section with the given header line.
1.1536 - ///
1.1537 - /// It gives back true when the header line start with \c \@edges,
1.1538 - /// and the header line's id and the reader's id are the same.
1.1539 - virtual bool header(const std::string& line) {
1.1540 - std::istringstream ls(line);
1.1541 - std::string command;
1.1542 - std::string name;
1.1543 - ls >> command >> name;
1.1544 - return command == "@undiredges" && name == id;
1.1545 - }
1.1546 -
1.1547 - /// \brief Reader function of the section.
1.1548 - ///
1.1549 - /// It reads the content of the section.
1.1550 - virtual void read(std::istream& is) {
1.1551 - std::string line;
1.1552 - while (getline(is, line)) {
1.1553 - std::istringstream ls(line);
1.1554 - std::string id;
1.1555 - ls >> id;
1.1556 - {
1.1557 - typename UndirEdgeReaders::iterator it = undirEdgeReaders.find(id);
1.1558 - if (it != undirEdgeReaders.end()) {
1.1559 - *(it->second) = undirEdgeIdReader->read(ls);
1.1560 - break;
1.1561 - }
1.1562 - } {
1.1563 - typename EdgeReaders::iterator it = edgeReaders.find(id);
1.1564 - if (it != edgeReaders.end()) {
1.1565 - *(it->second) = edgeIdReader->read(ls);
1.1566 - break;
1.1567 - }
1.1568 - }
1.1569 - }
1.1570 - }
1.1571 -
1.1572 - private:
1.1573 -
1.1574 - std::string id;
1.1575 -
1.1576 - typedef std::map<std::string, UndirEdge*> UndirEdgeReaders;
1.1577 - UndirEdgeReaders undirEdgeReaders;
1.1578 - std::auto_ptr<IdReaderBase<UndirEdge> > undirEdgeIdReader;
1.1579 -
1.1580 - typedef std::map<std::string, Edge*> EdgeReaders;
1.1581 - EdgeReaders edgeReaders;
1.1582 - std::auto_ptr<IdReaderBase<Edge> > edgeIdReader;
1.1583 - };
1.1584 -
1.1585 - /// \ingroup io_group
1.1586 - /// \brief SectionReader for attributes.
1.1587 - ///
1.1588 - /// The lemon format can store multiple attribute set. Each set has
1.1589 - /// the header line \c \@attributes \c attributeset_id, but the
1.1590 - /// attributeset_id may be empty.
1.1591 - ///
1.1592 - /// The attributeset section contains several lines. Each of them starts
1.1593 - /// with an attribute and then a the value for the id.
1.1594 - ///
1.1595 - /// \relates LemonReader
1.1596 - template <typename _Traits = DefaultReaderTraits>
1.1597 - class AttributeReader : public CommonSectionReaderBase {
1.1598 - typedef CommonSectionReaderBase Parent;
1.1599 - typedef _Traits Traits;
1.1600 - public:
1.1601 - /// \brief Constructor.
1.1602 - ///
1.1603 - /// Constructor for AttributeReader. It creates the AttributeReader and
1.1604 - /// attach it into the given LemonReader. The reader process a section
1.1605 - /// only if the \c section_id and the \c _id are the same.
1.1606 - AttributeReader(LemonReader& _reader,
1.1607 - const std::string& _id = std::string())
1.1608 - : Parent(_reader), id(_id) {}
1.1609 -
1.1610 - /// \brief Destructor.
1.1611 - ///
1.1612 - /// Destructor for AttributeReader.
1.1613 - virtual ~AttributeReader() {
1.1614 - for (typename Readers::iterator it = readers.begin();
1.1615 - it != readers.end(); ++it) {
1.1616 - delete it->second;
1.1617 - }
1.1618 - }
1.1619 -
1.1620 - private:
1.1621 - AttributeReader(const AttributeReader&);
1.1622 - void operator=(AttributeReader&);
1.1623 -
1.1624 - public:
1.1625 - /// \brief Add an attribute reader command for the reader.
1.1626 - ///
1.1627 - /// Add an attribute reader command for the reader.
1.1628 - template <typename Value>
1.1629 - AttributeReader& readAttribute(const std::string& id, Value& value) {
1.1630 - return readAttribute<typename Traits::template Reader<Value> >
1.1631 - (id, value);
1.1632 - }
1.1633 -
1.1634 - /// \brief Add an attribute reader command for the reader.
1.1635 - ///
1.1636 - /// Add an attribute reader command for the reader.
1.1637 - template <typename Reader, typename Value>
1.1638 - AttributeReader& readAttribute(const std::string& name, Value& value,
1.1639 - const Reader& reader = Reader()) {
1.1640 - if (readers.find(name) != readers.end()) {
1.1641 - ErrorMessage msg;
1.1642 - msg << "Multiple read rule for attribute: " << name;
1.1643 - throw IOParameterError(msg.message());
1.1644 - }
1.1645 - readers.insert(make_pair(name, new ValueReader<Value, Reader>
1.1646 - (value, reader)));
1.1647 - return *this;
1.1648 - }
1.1649 -
1.1650 - protected:
1.1651 -
1.1652 - /// \brief Gives back true when the SectionReader can process
1.1653 - /// the section with the given header line.
1.1654 - ///
1.1655 - /// It gives back true when the header line start with \c \@attributes,
1.1656 - /// and the header line's id and the attributeset's id are the same.
1.1657 - bool header(const std::string& line) {
1.1658 - std::istringstream ls(line);
1.1659 - std::string command;
1.1660 - std::string name;
1.1661 - ls >> command >> name;
1.1662 - return command == "@attributes" && name == id;
1.1663 - }
1.1664 -
1.1665 - /// \brief Reader function of the section.
1.1666 - ///
1.1667 - /// It reads the content of the section.
1.1668 - void read(std::istream& is) {
1.1669 - std::string line;
1.1670 - while (getline(is, line)) {
1.1671 - std::istringstream ls(line);
1.1672 - std::string id;
1.1673 - ls >> id;
1.1674 - typename Readers::iterator it = readers.find(id);
1.1675 - if (it != readers.end()) {
1.1676 - it->second->read(ls);
1.1677 - }
1.1678 - }
1.1679 - }
1.1680 -
1.1681 - private:
1.1682 - std::string id;
1.1683 -
1.1684 - typedef std::map<std::string, ValueReaderBase*> Readers;
1.1685 - Readers readers;
1.1686 - };
1.1687 -
1.1688 - /// \ingroup io_group
1.1689 - /// \brief SectionReader for retrieve what is in the file.
1.1690 - ///
1.1691 - /// SectionReader for retrieve what is in the file. If you want
1.1692 - /// to know which sections, maps and items are in the file
1.1693 - /// use the next code:
1.1694 - /// \code
1.1695 - /// LemonReader reader("input.lgf");
1.1696 - /// ContentReader content(reader);
1.1697 - /// reader.run();
1.1698 - /// \endcode
1.1699 - class ContentReader : public LemonReader::SectionReader {
1.1700 - typedef LemonReader::SectionReader Parent;
1.1701 - public:
1.1702 - /// \brief Constructor.
1.1703 - ///
1.1704 - /// Constructor for
1.1705 - ContentReader(LemonReader& _reader) : Parent(_reader) {}
1.1706 -
1.1707 - /// \brief Desctructor.
1.1708 - ///
1.1709 - /// Desctructor.
1.1710 - virtual ~ContentReader() {}
1.1711 -
1.1712 - /// \brief Gives back how many nodesets are in the file.
1.1713 - ///
1.1714 - /// Gives back how many nodesets are in the file.
1.1715 - int nodeSetNum() const {
1.1716 - return nodesets.size();
1.1717 - }
1.1718 -
1.1719 - /// \brief Gives back the name of nodeset on the indiced position.
1.1720 - ///
1.1721 - /// Gives back the name of nodeset on the indiced position.
1.1722 - std::string nodeSetName(int index) const {
1.1723 - return nodesets[index].name;
1.1724 - }
1.1725 -
1.1726 - /// \brief Gives back the map names of nodeset on the indiced position.
1.1727 - ///
1.1728 - /// Gives back the map names of nodeset on the indiced position.
1.1729 - const std::vector<std::string>& nodeSetMaps(int index) const {
1.1730 - return nodesets[index].items;
1.1731 - }
1.1732 -
1.1733 - /// \brief Gives back how many edgesets are in the file.
1.1734 - ///
1.1735 - /// Gives back how many edgesets are in the file.
1.1736 - int edgeSetNum() const {
1.1737 - return edgesets.size();
1.1738 - }
1.1739 -
1.1740 - /// \brief Gives back the name of edgeset on the indiced position.
1.1741 - ///
1.1742 - /// Gives back the name of edgeset on the indiced position.
1.1743 - std::string edgeSetName(int index) const {
1.1744 - return edgesets[index].name;
1.1745 - }
1.1746 -
1.1747 - /// \brief Gives back the map names of edgeset on the indiced position.
1.1748 - ///
1.1749 - /// Gives back the map names of edgeset on the indiced position.
1.1750 - const std::vector<std::string>& edgeSetMaps(int index) const {
1.1751 - return edgesets[index].items;
1.1752 - }
1.1753 -
1.1754 - /// \brief Gives back how many undirected edgesets are in the file.
1.1755 - ///
1.1756 - /// Gives back how many undirected edgesets are in the file.
1.1757 - int undirEdgeSetNum() const {
1.1758 - return undiredgesets.size();
1.1759 - }
1.1760 -
1.1761 - /// \brief Gives back the name of undirected edgeset on the indiced
1.1762 - /// position.
1.1763 - ///
1.1764 - /// Gives back the name of undirected edgeset on the indiced position.
1.1765 - std::string undirEdgeSetName(int index) const {
1.1766 - return undiredgesets[index].name;
1.1767 - }
1.1768 -
1.1769 - /// \brief Gives back the map names of undirected edgeset on the indiced
1.1770 - /// position.
1.1771 - ///
1.1772 - /// Gives back the map names of undirected edgeset on the indiced position.
1.1773 - const std::vector<std::string>& undirEdgeSetMaps(int index) const {
1.1774 - return undiredgesets[index].items;
1.1775 - }
1.1776 -
1.1777 - /// \brief Gives back how many labeled nodes section are in the file.
1.1778 - ///
1.1779 - /// Gives back how many labeled nodes section are in the file.
1.1780 - int nodesNum() const {
1.1781 - return nodes.size();
1.1782 - }
1.1783 -
1.1784 - /// \brief Gives back the name of labeled nodes section on the indiced
1.1785 - /// position.
1.1786 - ///
1.1787 - /// Gives back the name of labeled nodes section on the indiced position.
1.1788 - std::string nodesName(int index) const {
1.1789 - return nodes[index].name;
1.1790 - }
1.1791 -
1.1792 - /// \brief Gives back the names of the labeled nodes in the indiced
1.1793 - /// section.
1.1794 - ///
1.1795 - /// Gives back the names of the labeled nodes in the indiced section.
1.1796 - const std::vector<std::string>& nodesItems(int index) const {
1.1797 - return nodes[index].items;
1.1798 - }
1.1799 -
1.1800 - /// \brief Gives back how many labeled edges section are in the file.
1.1801 - ///
1.1802 - /// Gives back how many labeled edges section are in the file.
1.1803 - int edgesNum() const {
1.1804 - return edges.size();
1.1805 - }
1.1806 -
1.1807 - /// \brief Gives back the name of labeled edges section on the indiced
1.1808 - /// position.
1.1809 - ///
1.1810 - /// Gives back the name of labeled edges section on the indiced position.
1.1811 - std::string edgesName(int index) const {
1.1812 - return edges[index].name;
1.1813 - }
1.1814 -
1.1815 - /// \brief Gives back the names of the labeled edges in the indiced
1.1816 - /// section.
1.1817 - ///
1.1818 - /// Gives back the names of the labeled edges in the indiced section.
1.1819 - const std::vector<std::string>& edgesItems(int index) const {
1.1820 - return edges[index].items;
1.1821 - }
1.1822 -
1.1823 - /// \brief Gives back how many labeled undirected edges section are
1.1824 - /// in the file.
1.1825 - ///
1.1826 - /// Gives back how many labeled undirected edges section are in the file.
1.1827 - int undirEdgesNum() const {
1.1828 - return undiredges.size();
1.1829 - }
1.1830 -
1.1831 - /// \brief Gives back the name of labeled undirected edges section
1.1832 - /// on the indiced position.
1.1833 - ///
1.1834 - /// Gives back the name of labeled undirected edges section on the
1.1835 - /// indiced position.
1.1836 - std::string undirEdgesName(int index) const {
1.1837 - return undiredges[index].name;
1.1838 - }
1.1839 -
1.1840 - /// \brief Gives back the names of the labeled undirected edges in
1.1841 - /// the indiced section.
1.1842 - ///
1.1843 - /// Gives back the names of the labeled undirected edges in the
1.1844 - /// indiced section.
1.1845 - const std::vector<std::string>& undirEdgesItems(int index) const {
1.1846 - return undiredges[index].items;
1.1847 - }
1.1848 -
1.1849 -
1.1850 - /// \brief Gives back how many attributes section are in the file.
1.1851 - ///
1.1852 - /// Gives back how many attributes section are in the file.
1.1853 - int attributesNum() const {
1.1854 - return attributes.size();
1.1855 - }
1.1856 -
1.1857 - /// \brief Gives back the name of attributes section on the indiced
1.1858 - /// position.
1.1859 - ///
1.1860 - /// Gives back the name of attributes section on the indiced position.
1.1861 - std::string attributesName(int index) const {
1.1862 - return attributes[index].name;
1.1863 - }
1.1864 -
1.1865 - /// \brief Gives back the names of the attributes in the indiced section.
1.1866 - ///
1.1867 - /// Gives back the names of the attributes in the indiced section.
1.1868 - const std::vector<std::string>& attributesItems(int index) const {
1.1869 - return attributes[index].items;
1.1870 - }
1.1871 -
1.1872 - const std::vector<std::string>& otherSections() const {
1.1873 - return sections;
1.1874 - }
1.1875 -
1.1876 - protected:
1.1877 -
1.1878 - /// \brief Gives back true when the SectionReader can process
1.1879 - /// the section with the given header line.
1.1880 - ///
1.1881 - /// It gives back true when the section is common section.
1.1882 - bool header(const std::string& line) {
1.1883 - std::istringstream ls(line);
1.1884 - std::string command, name;
1.1885 - ls >> command >> name;
1.1886 - if (command == "@nodeset") {
1.1887 - current = command;
1.1888 - nodesets.push_back(SectionInfo(name));
1.1889 - } else if (command == "@edgeset") {
1.1890 - current = command;
1.1891 - edgesets.push_back(SectionInfo(name));
1.1892 - } else if (command == "@undiredgeset") {
1.1893 - current = command;
1.1894 - undiredgesets.push_back(SectionInfo(name));
1.1895 - } else if (command == "@nodes") {
1.1896 - current = command;
1.1897 - nodes.push_back(SectionInfo(name));
1.1898 - } else if (command == "@edges") {
1.1899 - current = command;
1.1900 - edges.push_back(SectionInfo(name));
1.1901 - } else if (command == "@undiredges") {
1.1902 - current = command;
1.1903 - undiredges.push_back(SectionInfo(name));
1.1904 - } else if (command == "@attributes") {
1.1905 - current = command;
1.1906 - attributes.push_back(SectionInfo(name));
1.1907 - } else {
1.1908 - sections.push_back(line);
1.1909 - return false;
1.1910 - }
1.1911 - return true;
1.1912 - }
1.1913 -
1.1914 - /// \brief Retrieve the items from various sections.
1.1915 - ///
1.1916 - /// Retrieve the items from various sections.
1.1917 - void read(std::istream& is) {
1.1918 - if (current == "@nodeset") {
1.1919 - readMapNames(is, nodesets.back().items);
1.1920 - } else if (current == "@edgeset") {
1.1921 - readMapNames(is, edgesets.back().items);
1.1922 - } else if (current == "@undiredgeset") {
1.1923 - readMapNames(is, undiredgesets.back().items);
1.1924 - } else if (current == "@nodes") {
1.1925 - readItemNames(is, nodes.back().items);
1.1926 - } else if (current == "@edges") {
1.1927 - readItemNames(is, edges.back().items);
1.1928 - } else if (current == "@undiredges") {
1.1929 - readItemNames(is, undiredges.back().items);
1.1930 - } else if (current == "@attributes") {
1.1931 - readItemNames(is, attributes.back().items);
1.1932 - }
1.1933 - }
1.1934 -
1.1935 - private:
1.1936 -
1.1937 - void readMapNames(std::istream& is, std::vector<std::string>& maps) {
1.1938 - std::string line, id;
1.1939 - std::getline(is, line);
1.1940 - std::istringstream ls(line);
1.1941 - while (ls >> id) {
1.1942 - maps.push_back(id);
1.1943 - }
1.1944 - while (getline(is, line));
1.1945 - }
1.1946 -
1.1947 - void readItemNames(std::istream& is, std::vector<std::string>& maps) {
1.1948 - std::string line, id;
1.1949 - while (std::getline(is, line)) {
1.1950 - std::istringstream ls(line);
1.1951 - ls >> id;
1.1952 - maps.push_back(id);
1.1953 - }
1.1954 - }
1.1955 -
1.1956 - struct SectionInfo {
1.1957 - std::string name;
1.1958 - std::vector<std::string> items;
1.1959 -
1.1960 - SectionInfo(const std::string& _name) : name(_name) {}
1.1961 - };
1.1962 -
1.1963 - std::vector<SectionInfo> nodesets;
1.1964 - std::vector<SectionInfo> edgesets;
1.1965 - std::vector<SectionInfo> undiredgesets;
1.1966 -
1.1967 - std::vector<SectionInfo> nodes;
1.1968 - std::vector<SectionInfo> edges;
1.1969 - std::vector<SectionInfo> undiredges;
1.1970 -
1.1971 - std::vector<SectionInfo> attributes;
1.1972 -
1.1973 - std::vector<std::string> sections;
1.1974 -
1.1975 - std::string current;
1.1976 -
1.1977 - };
1.1978 -
1.1979 -}
1.1980 -#endif