COIN-OR::LEMON - Graph Library

Ticket #225: blgf.patch

File blgf.patch, 117.6 KB (added by Frantisek Csajka, 14 years ago)
  • new file doc/blgf.dox

    # HG changeset patch
    # User Frantisek Csajka <csferi27@gmail.com>
    # Date 1286198489 -7200
    # Node ID 454f0c2a380c72615d988f0baa3655301cc7ed11
    # Parent  a93f1a27d83125233114f2052c1e523c5e2f26e1
    Blgf
    
    diff -r a93f1a27d831 -r 454f0c2a380c doc/blgf.dox
    - +  
     1/* -*- mode: C++; indent-tabs-mode: nil; -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library.
     4 *
     5 * Copyright (C) 2003-2009
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19namespace lemon {
     20/*!
     21
     22
     23
     24\page blgf-format Binary LEMON Graph Format (BLGF)
     25
     26The \e BLGF is a <em>binary</em>
     27file format for storing graphs and associated data like
     28node and edge maps.
     29
     30Each BLGF file starts with a signature, which are the "BLGF" letters followed by the two digit
     31version number.
     32After that, the file consists of several blocks.
     33Each block is preceded by its type, which is a 2 byte unsigned integer value (UINT16).
     34Currently, there are three types of blocks:
     35
     36- Nodes block
     37- Arcs block
     38- Attributes block
     39
     40Note: There may be several Nodes and Arcs blocks but only one Attributes block.
     41
     42\section Nodes Nodes block
     43
     44This type of block describes a set of nodes and associated maps.
     45It consists of two parts, the header and the data terminated by a null byte.
     46The header contains the name of the block and
     47the number of nodes described (i.e. the item count in each map) stored as a 4 byte unsigned integer (UINT32).
     48The data part contains the maps stored one after the other. The first map in the Nodes
     49block is a special one, called \c Label, which contains unique id (label) for each node.
     50When describing end points of an arc, these ids are used to refer to the target and
     51the source node. \c Label map has an empty name (i.e. only NULL byte) and it must
     52not be absent! The order of nodes in each map must be the same (e.g. the i. item
     53in each map describes the node labeled by the i. item in the \c Label map)!
     54
     55
     56\section Arcs Arcs block
     57
     58This type of block is very similar to the Nodes block. It again starts with a
     59header containing the name of the block and the number of items described (i.e. the
     60number of arcs or edges). The difference between these two types of blocks is the following: the
     61\c Label map is optional here and the first map in this block must be the \c From-To map,
     62which contains node pairs describing the source and the destination for each arc.
     63The \c From-To map has also an empty name. If there is a \c Label map in Arcs block,
     64it must be on the second place right after the \c From-To map.
     65
     66As in the Nodes block, the order of the arcs in the maps must be the same!
     67
     68\section Attributes Attributes  block
     69
     70As it was mentioned before, only one Attributes block can take place in the
     71BLGF file. This block contains a null-terminated sequence of key-value pairs. The
     72Attributes block contains no header, since the name is not necessary, and the type
     73of the values is fixed (STRING).
     74
     75
     76\section Limitations Limitations
     77
     78Compared to LGF, the implementation of BLGF has some limitations:
     79- Using real types with their default value converters, the BLGF becomes portable
     80only on machines with the same memory endianness (i.e. big-endian or little-
     81endian).
     82- Long double type is not supported yet.
     83- The values of the label maps must be fundamental types (integer, real or
     84string).
     85
     86*/
     87}
     88
     89//  LocalWords:  whitespace whitespaces
  • doc/groups.dox

    diff -r a93f1a27d831 -r 454f0c2a380c doc/groups.dox
    a b  
    659659postscript (EPS) format.
    660660*/
    661661
     662
    662663/**
    663 @defgroup lemon_io LEMON Graph Format
     664@defgroup lemon_io LEMON Graph Formats
    664665@ingroup io_group
    665 \brief Reading and writing LEMON Graph Format.
     666\brief Reading and writing LEMON Graph Format and its binary version.
    666667
    667668This group contains methods for reading and writing
    668 \ref lgf-format "LEMON Graph Format".
     669\ref lgf-format "LEMON Graph Format" and \ref blgf-format "Binary LEMON Graph Format".
    669670*/
    670671
    671672/**
  • new file doc/references.dox

    diff -r a93f1a27d831 -r 454f0c2a380c doc/references.dox
    - +  
     1/**
     2\page references References
     3
     4\section amo93networkflows [AMO93]
     5<div style="margin-top: -4ex; margin-left: 8em;">
     6Ravindra K. Ahuja, Thomas L. Magnanti, and James B. Orlin.
     7<em>Network Flows: Theory, Algorithms, and Applications</em>.
     8Prentice-Hall, Inc.,
     9February 1993.
     10</div>
     11
     12\section boost [Boost]
     13<div style="margin-top: -4ex; margin-left: 8em;">
     14Boost C++ Libraries.
     15<a href="http://www.boost.org/">http://www.boost.org/</a>.
     16</div>
     17
     18\section bunnagel98efficient [BKV98]
     19<div style="margin-top: -4ex; margin-left: 8em;">
     20Ursula B&uuml;nnagel, Bernhard Korte, and Jens Vygen.
     21Efficient implementation of the Goldberg-Tarjan minimum-cost flow algorithm.
     22<em>Optimization Methods and Software</em>,
     2310:157-174,
     241998.
     25</div>
     26
     27\section cmake [CMake]
     28<div style="margin-top: -4ex; margin-left: 8em;">
     29CMake -- Cross Platform Make.
     30<a href="http://www.cmake.org/">http://www.cmake.org/</a>.
     31</div>
     32
     33\section coinor [COIN-OR]
     34<div style="margin-top: -4ex; margin-left: 8em;">
     35COIN-OR -- Computational Infrastructure for Operations Research.
     36<a href="http://www.coin-or.org/">http://www.coin-or.org/</a>.
     37</div>
     38
     39\section cplex [CPLEX]
     40<div style="margin-top: -4ex; margin-left: 8em;">
     41ILOG CPLEX.
     42<a href="http://www.ilog.com/">http://www.ilog.com/</a>.
     43</div>
     44
     45\section cbc [Cbc]
     46<div style="margin-top: -4ex; margin-left: 8em;">
     47Cbc -- Coin-Or Branch and Cut.
     48<a href="http://projects.coin-or.org/Cbc/">http://projects.coin-or.org/Cbc/</a>.
     49</div>
     50
     51\section clp [Clp]
     52<div style="margin-top: -4ex; margin-left: 8em;">
     53Clp -- Coin-Or Linear Programming.
     54<a href="http://projects.coin-or.org/Clp/">http://projects.coin-or.org/Clp/</a>.
     55</div>
     56
     57\section clrs01algorithms [CLRS01]
     58<div style="margin-top: -4ex; margin-left: 8em;">
     59Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein.
     60<em>Introduction to Algorithms</em>.
     61The MIT Press,
     622nd edition,
     632001.
     64</div>
     65
     66\section dantzig63linearprog [Dan63]
     67<div style="margin-top: -4ex; margin-left: 8em;">
     68George B. Dantzig.
     69<em>Linear Programming and Extensions</em>.
     70Princeton University Press,
     711963.
     72</div>
     73
     74\section dasdan98minmeancycle [DG98]
     75<div style="margin-top: -4ex; margin-left: 8em;">
     76Ali Dasdan and Rajesh K. Gupta.
     77Faster maximum and minimum mean cycle alogrithms for system performance analysis.
     78<em>IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems</em>,
     7917(10):889-899,
     801998.
     81</div>
     82
     83\section dinic70algorithm [Din70]
     84<div style="margin-top: -4ex; margin-left: 8em;">
     85E. A. Dinic.
     86Algorithm for solution of a problem of maximum flow in a network with power estimation.
     87<em>Soviet Math. Doklady</em>,
     8811:1277-1280,
     891970.
     90</div>
     91
     92\section doxygen [Doxygen]
     93<div style="margin-top: -4ex; margin-left: 8em;">
     94Doxygen -- Source code documentation generator tool.
     95<a href="http://www.doxygen.org/">http://www.doxygen.org/</a>.
     96</div>
     97
     98\section egres [EGRES]
     99<div style="margin-top: -4ex; margin-left: 8em;">
     100EGRES -- Egerv&aacute;ry Research Group on Combinatorial Optimization.
     101<a href="http://www.cs.elte.hu/egres/">http://www.cs.elte.hu/egres/</a>.
     102</div>
     103
     104\section edmondskarp72theoretical [EK72]
     105<div style="margin-top: -4ex; margin-left: 8em;">
     106Jack Edmonds and Richard M. Karp.
     107Theoretical improvements in algorithmic efficiency for network flow problems.
     108<em>Journal of the ACM</em>,
     10919(2):248-264,
     1101972.
     111</div>
     112
     113\section glpk [GLPK]
     114<div style="margin-top: -4ex; margin-left: 8em;">
     115GLPK -- GNU Linear Programming Kit.
     116<a href="http://www.gnu.org/software/glpk/">http://www.gnu.org/software/glpk/</a>.
     117</div>
     118
     119\section goldberg97efficient [Gol97]
     120<div style="margin-top: -4ex; margin-left: 8em;">
     121Andrew V. Goldberg.
     122An efficient implementation of a scaling minimum-cost flow algorithm.
     123<em>Journal of Algorithms</em>,
     12422(1):1-29,
     1251997.
     126</div>
     127
     128\section goldberg08partial [Gol08]
     129<div style="margin-top: -4ex; margin-left: 8em;">
     130Andrew V. Goldberg.
     131The partial augment-relabel algorithm for the maximum flow problem.
     132<em>16th Annual European Symposium on Algorithms</em>,
     133pages 466-477,
     1342008.
     135</div>
     136
     137\section goldberg88newapproach [GT88]
     138<div style="margin-top: -4ex; margin-left: 8em;">
     139Andrew V. Goldberg and Robert E. Tarjan.
     140A new approach to the maximum flow problem.
     141<em>Journal of the ACM</em>,
     14235(4):921-940,
     1431988.
     144</div>
     145
     146\section goldberg89cyclecanceling [GT89]
     147<div style="margin-top: -4ex; margin-left: 8em;">
     148Andrew V. Goldberg and Robert E. Tarjan.
     149Finding minimum-cost circulations by canceling negative cycles.
     150<em>Journal of the ACM</em>,
     15136(4):873-886,
     1521989.
     153</div>
     154
     155\section goldberg90approximation [GT90]
     156<div style="margin-top: -4ex; margin-left: 8em;">
     157Andrew V. Goldberg and Robert E. Tarjan.
     158Finding minimum-cost circulations by successive approximation.
     159<em>Mathematics of Operations Research</em>,
     16015(3):430-466,
     1611990.
     162</div>
     163
     164\section karp78characterization [Kar78]
     165<div style="margin-top: -4ex; margin-left: 8em;">
     166Richard M. Karp.
     167A characterization of the minimum cycle mean in a digraph.
     168<em>Discrete Math.</em>,
     16923:309-311,
     1701978.
     171</div>
     172
     173\section kellyoneill91netsimplex [KO91]
     174<div style="margin-top: -4ex; margin-left: 8em;">
     175Damian J. Kelly and Garrett M. O'Neill.
     176The minimum cost flow problem and the network simplex method.
     177Master's thesis,
     178University College,
     179Dublin, Ireland,
     180September 1991.
     181</div>
     182
     183\section klein67primal [Kle67]
     184<div style="margin-top: -4ex; margin-left: 8em;">
     185Morton Klein.
     186A primal method for minimal cost flows with applications to the assignment and transportation problems.
     187<em>Management Science</em>,
     18814:205-220,
     1891967.
     190</div>
     191
     192\section leda [LEDA]
     193<div style="margin-top: -4ex; margin-left: 8em;">
     194LEDA -- Library of Efficient Data Types and Algorithms.
     195<a href="http://www.algorithmic-solutions.com/">http://www.algorithmic-solutions.com/</a>.
     196</div>
     197
     198\section lemon [LEMON]
     199<div style="margin-top: -4ex; margin-left: 8em;">
     200LEMON -- Library for Efficient Modeling and Optimization in Networks.
     201<a href="http://lemon.cs.elte.hu/">http://lemon.cs.elte.hu/</a>,
     2022009.
     203</div>
     204
     205\section ledabook [MN99]
     206<div style="margin-top: -4ex; margin-left: 8em;">
     207Kurt Mehlhorn and Stefan N&auml;her.
     208<em>LEDA: A platform for combinatorial and geometric computing</em>.
     209Cambridge University Press,
     210New York, NY, USA,
     2111999.
     212</div>
     213
     214\section schrijver03combinatorial [Sch03]
     215<div style="margin-top: -4ex; margin-left: 8em;">
     216Alexander Schrijver.
     217<em>Combinatorial Optimization: Polyhedra and Efficiency</em>.
     218Springer-Verlag,
     2192003.
     220</div>
     221
     222\section bglbook [SLL02]
     223<div style="margin-top: -4ex; margin-left: 8em;">
     224Jeremy G. Siek, Lee-Quan Lee, and Andrew Lumsdaine.
     225<em>The Boost Graph Library: User Guide and Reference Manual</em>.
     226Addison-Wesley,
     2272002.
     228</div>
     229
     230\section sleator83dynamic [ST83]
     231<div style="margin-top: -4ex; margin-left: 8em;">
     232Daniel D. Sleator and Robert E. Tarjan.
     233A data structure for dynamic trees.
     234<em>Journal of Computer and System Sciences</em>,
     23526(3):362-391,
     2361983.
     237</div>
     238
     239\section soplex [SoPlex]
     240<div style="margin-top: -4ex; margin-left: 8em;">
     241SoPlex -- The Sequential Object-Oriented Simplex.
     242<a href="http://soplex.zib.de/">http://soplex.zib.de/</a>.
     243</div>
     244
     245\section stroustrup00cpp [Str00]
     246<div style="margin-top: -4ex; margin-left: 8em;">
     247Bjarne Stroustrup.
     248<em>The C++ Programming Language</em>.
     249Addison-Wesley Professional,
     2503rd edition,
     251February 2000.
     252</div>
     253
     254*/
  • lemon/Makefile.am

    diff -r a93f1a27d831 -r 454f0c2a380c lemon/Makefile.am
    a b  
    9595        lemon/karp.h \
    9696        lemon/kruskal.h \
    9797        lemon/hao_orlin.h \
     98        lemon/blgf.h \
    9899        lemon/lgf_reader.h \
    99100        lemon/lgf_writer.h \
    100101        lemon/list_graph.h \
  • new file lemon/blgf.h

    diff -r a93f1a27d831 -r 454f0c2a380c lemon/blgf.h
    - +  
     1/* -*- mode: C++; indent-tabs-mode: nil; -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library.
     4 *
     5 * Copyright (C) 2003-2009
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19/// \ingroup lemon_io
     20/// \file
     21/// \brief \ref blgf-format "Binary LEMON Graph Format"'s common
     22/// interfaces and constats.
     23
     24#ifndef _BLGF_H
     25#define _BLGF_H
     26
     27#include <limits>
     28#include <sstream>
     29#include <cstring>
     30#include <lemon/config.h>
     31#include <lemon/error.h>
     32
     33
     34namespace lemon {
     35  namespace _blgf_bits {
     36
     37#if LEMON_HAVE_LONG_LONG
     38    typedef unsigned long long ULInt;
     39    typedef long long int LInt;
     40#else
     41    typedef unsigned long ULInt;
     42    typedef long int LInt;
     43#endif
     44
     45    const char BLGF_VERSION[] = "BLGF01";
     46
     47    //----------------------------------------------
     48    const unsigned int TYPE_GROUP_MASK = 0x0F0;
     49    const unsigned int TYPE_UNSIGNED_BASE = 0x00;
     50    const unsigned int TYPE_SIGNED_BASE = 0x10;
     51    const unsigned int TYPE_REAL_BASE = 0x20;
     52    const unsigned int TYPE_OTHER_BASE = 0x40;
     53
     54
     55    enum BlgfType {
     56      UINT8 = TYPE_UNSIGNED_BASE + 1,
     57      UINT16,
     58      UINT32,
     59      UINT64,
     60
     61      INT8 = TYPE_SIGNED_BASE + 1,
     62      INT16,
     63      INT32,
     64      INT64,
     65
     66      FLOAT = TYPE_REAL_BASE + 1,
     67      DOUBLE,
     68      //LONG_DOUBLE,
     69      STRING = TYPE_OTHER_BASE + 1,
     70      DATA
     71    };
     72
     73    enum BlgfBlockType {
     74      ATTRIBUTES,
     75      NODES,
     76      ARCS
     77    };
     78
     79    const unsigned int UINT8_SIZE = 1;
     80    const unsigned int INT8_SIZE = 1;
     81
     82    const unsigned int UINT16_SIZE = 2;
     83    const unsigned int INT16_SIZE = 2;
     84
     85    const unsigned int UINT32_SIZE = 4;
     86    const unsigned int INT32_SIZE = 4;
     87
     88    const unsigned int UINT64_SIZE = 8;
     89    const unsigned int INT64_SIZE = 8;
     90
     91    const unsigned int FLOAT_SIZE = 4;
     92    const unsigned int DOUBLE_SIZE = 8;
     93    const unsigned int LONG_DOUBLE_SIZE = 8;
     94
     95    const unsigned int TYPE_SPEC_SIZE = UINT16_SIZE;
     96    const BlgfType TYPE_SPEC_TYPE = UINT16;
     97
     98    const unsigned int BLOCK_SPEC_SIZE = UINT16_SIZE;
     99    const BlgfType BLOCK_SPEC_TYPE = UINT16;
     100
     101    const unsigned int SIZE_SPEC_SIZE = UINT32_SIZE;
     102    const BlgfType SIZE_SPEC_TYPE = INT32;
     103
     104    inline bool is_signed(BlgfType type) {
     105      return (((type) & TYPE_GROUP_MASK) == TYPE_SIGNED_BASE);
     106    }
     107
     108    inline bool is_unsigned(BlgfType type) {
     109      return (((type) & TYPE_GROUP_MASK) == TYPE_UNSIGNED_BASE);
     110    }
     111
     112    inline bool is_integer(BlgfType type) {
     113      return (is_signed(type) || is_unsigned(type));
     114    }
     115
     116    inline bool is_real(BlgfType type) {
     117      return (((type) & TYPE_GROUP_MASK) == TYPE_REAL_BASE);
     118    }
     119
     120    inline int get_type_size(BlgfType type) {
     121      switch (type) {
     122        case INT8:
     123        case UINT8:
     124          return INT8_SIZE;
     125
     126        case INT16:
     127        case UINT16:
     128          return INT16_SIZE;
     129
     130        case INT32:
     131        case UINT32:
     132          return INT32_SIZE;
     133
     134        case INT64:
     135        case UINT64:
     136          return INT64_SIZE;
     137
     138        case FLOAT:
     139          return FLOAT_SIZE;
     140
     141        case DOUBLE:
     142          return DOUBLE_SIZE;
     143
     144        case DATA:
     145        case STRING:
     146          return -1;
     147
     148        default:
     149          throw ("Unknown type");
     150      }
     151
     152    }
     153  };
     154
     155  namespace _reader_bits {
     156
     157    template <typename Value>
     158    struct DefaultValueConverter {
     159
     160      Value operator()(const std::string & str) {
     161        std::istringstream is(str);
     162        Value value;
     163        if (!(is >> value)) {
     164          throw FormatError("Cannot read token");
     165        }
     166
     167        char c;
     168        if (is >> std::ws >> c) {
     169          throw FormatError("Remaining characters in token");
     170        }
     171        return value;
     172      }
     173    };
     174
     175    template <>
     176    struct DefaultValueConverter<std::string> {
     177
     178      std::string operator()(const std::string & str) {
     179        return str;
     180      }
     181    };
     182
     183    class SuperType {
     184    private:
     185
     186      union {
     187        _blgf_bits::ULInt _uint;
     188        _blgf_bits::LInt _sint;
     189
     190        double _double;
     191        float _float;
     192      } _value;
     193
     194      _blgf_bits::BlgfType _type;
     195      std::string _strvalue;
     196      char *_cdata;
     197
     198      template <typename CppType>
     199      void fromBinary(const char* array, int n, bool is_signed,
     200        CppType& value) {
     201        value = 0;
     202        if (n < static_cast <int>( sizeof(CppType)) && is_signed &&
     203          (array[0] & static_cast<char>(0x80)) != 0) {
     204          value = -1;
     205        }
     206        for (register int i = 0; i != n; i++) {
     207          value = value << static_cast<CppType>(8);
     208          value = value | static_cast<CppType>(static_cast<CppType>(array[i]) & static_cast<CppType>(0xff));
     209        }
     210      }
     211
     212
     213    public:
     214
     215      SuperType() {
     216      }
     217
     218      void read(const _blgf_bits::BlgfType type, const char* buffer) {
     219        _type = type;
     220 
     221        if (_blgf_bits::is_signed(_type)) {
     222          fromBinary(buffer, get_type_size(type), is_signed(type), _value._sint);
     223        } else if (_blgf_bits::is_unsigned(_type)) {
     224          //if ((_type & _blgf_bits::TYPE_GROUP_MASK) == _blgf_bits::TYPE_UNSIGNED_BASE) {
     225          fromBinary(buffer, get_type_size(type), is_signed(type), _value._uint);
     226        } else if (_type == static_cast<unsigned int>(_blgf_bits::DOUBLE)) {
     227          _value._double = *(reinterpret_cast<double*>(const_cast<char*>(buffer)));
     228        } else if (_type == static_cast<unsigned int>(_blgf_bits::FLOAT)) {
     229          _value._float = *(reinterpret_cast<float*>(const_cast<char*>(buffer)));//*(float*) (const_cast<char*>(buffer));
     230        } else if (_type == static_cast<unsigned int>(_blgf_bits::STRING)) {
     231          _strvalue = std::string(buffer);
     232        } else if (_type == static_cast<unsigned int>(_blgf_bits::DATA)) {
     233
     234        } else {
     235          throw FormatError("Unknown data type");
     236        }
     237
     238      }
     239
     240      template<typename T>
     241      operator T() {
     242        if (_blgf_bits::is_signed(_type)) {
     243          _blgf_bits::LInt val = _value._sint;
     244
     245          //check unsigned long long becouse it's size can not be converted to LInt
     246          if (!std::numeric_limits<T>::is_signed) {
     247            if (val >= 0 && static_cast<_blgf_bits::ULInt>(val)
     248              <= static_cast<_blgf_bits::ULInt>(std::numeric_limits<T>::max()))
     249              return val;
     250            else
     251              throw FormatError("Value out of range");
     252          } else {
     253            if (val <= std::numeric_limits<T>::max() && val
     254              >= std::numeric_limits<T>::min())
     255              return val;
     256            else
     257              throw FormatError("Value out of range");
     258          }
     259
     260        } else if (_blgf_bits::is_unsigned(_type)) {
     261          if (_value._uint <= static_cast<_blgf_bits::ULInt>(std::numeric_limits<T>::max()))
     262            return _value._uint;
     263          else
     264            throw FormatError("Value out of range");
     265
     266        } else if (_type == _blgf_bits::STRING)
     267          return DefaultValueConverter<T > ()(_strvalue);
     268
     269        else {
     270          throw FormatError("Can not convert this type of value");
     271        }
     272
     273      }
     274
     275      operator float() {
     276        if (_type == _blgf_bits::FLOAT)
     277          return _value._float;
     278        else if (_type == _blgf_bits::DOUBLE){
     279          if (_value._double > static_cast<double>(std::numeric_limits<float>::max()) ||
     280            _value._double < static_cast<double>(std::numeric_limits<float>::min()))
     281            throw FormatError("Float value out of range");
     282          return _value._double;
     283        }else if (_blgf_bits::is_signed(_type))
     284          return _value._sint;
     285        else if (_blgf_bits::is_unsigned(_type))
     286          return _value._uint;
     287        else if (_type == _blgf_bits::STRING)
     288          return DefaultValueConverter<float>()(_strvalue);
     289        else
     290          throw FormatError("Not a float value");
     291      };
     292
     293      operator double() {
     294
     295        if (_type == _blgf_bits::DOUBLE)
     296          return _value._double;
     297        else if (_type == _blgf_bits::FLOAT)
     298          return _value._float;
     299        else if (_blgf_bits::is_signed(_type))
     300          return _value._sint;
     301        else if (_blgf_bits::is_unsigned(_type))
     302          return _value._uint;
     303        else if (_type == _blgf_bits::STRING)
     304          return DefaultValueConverter<double>()(_strvalue);
     305        else
     306          throw FormatError("Not a double value");
     307      }
     308
     309      operator std::string() {
     310        std::ostringstream os;
     311        if (_blgf_bits::is_signed(_type)) {
     312          os << this->operator _blgf_bits::LInt();
     313        } else if (_blgf_bits::is_unsigned(_type)) {
     314          os << _value._uint;
     315        } else if (_type == _blgf_bits::DOUBLE) {
     316          os << _value._double;
     317        } else if (_type == _blgf_bits::FLOAT) {
     318          os << _value._float;
     319        } else if (_type == _blgf_bits::STRING) {
     320          os << _strvalue;
     321        } else {
     322          throw FormatError("Cannot convert this type of data to string");
     323        }
     324
     325        return os.str();
     326      }
     327
     328
     329    };
     330
     331    template <typename Value>
     332    struct DefaultBinaryConverter {
     333
     334      Value operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
     335        SuperType t;
     336        t.read(blgfType, data);
     337        Value val = t.operator Value();
     338        return val;
     339      };
     340    };
     341
     342    template <>
     343    struct DefaultBinaryConverter<float> {
     344
     345      float operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
     346        SuperType t;
     347        t.read(blgfType, data);
     348        return t.operator float();
     349
     350      };
     351    };
     352
     353    template <>
     354    struct DefaultBinaryConverter<double> {
     355
     356      double operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
     357        SuperType t;
     358        t.read(blgfType, data);
     359        return t.operator double();
     360
     361      };
     362    };
     363
     364    template <>
     365    struct DefaultBinaryConverter<std::string> {
     366
     367      std::string operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
     368        SuperType t;
     369        t.read(blgfType, data);
     370        return t.operator std::string();
     371
     372      };
     373    };
     374
     375    inline std::istream& readStrBinary(std::istream& is, std::string& str) {
     376      std::ostringstream os;
     377      char c;
     378
     379      is.get(c);
     380
     381      while (is && c != 0) {
     382        os << c;
     383        is.get(c);
     384      }
     385      str = os.str();
     386      if (!is)
     387        throw FormatError("String not properly ended");
     388      return is;
     389    }
     390
     391    class BinaryToken {
     392    private:
     393      char* _data;
     394      int _size;
     395
     396      char* read(std::istream& _is, const _blgf_bits::BlgfType type) {
     397        if (_data != 0)
     398          delete _data;
     399
     400        if ((type & _blgf_bits::TYPE_GROUP_MASK) == _blgf_bits::TYPE_OTHER_BASE) {
     401
     402          if (type == _blgf_bits::STRING) {
     403            std::string s;
     404            _reader_bits::readStrBinary(_is, s);
     405            _size = s.length() + 1;
     406            _data = new char[_size];
     407            s.copy(_data, s.length(), 0);
     408
     409          } else if (type == _blgf_bits::DATA) {
     410            char valueBuffer[16];
     411            _is.read(valueBuffer, _blgf_bits::SIZE_SPEC_SIZE);
     412            _size = _reader_bits::DefaultBinaryConverter<int>()(_blgf_bits::SIZE_SPEC_TYPE, valueBuffer);
     413            _data = new char[_size];
     414            _is.read(_data, _size);
     415          }
     416        } else {
     417
     418          _size = _blgf_bits::get_type_size(type);
     419          _data = new char[_size];
     420          _is.read(_data, _size);
     421
     422        }
     423
     424        if (!_is)
     425          throw FormatError("Unexpected end of file");
     426
     427        return _data;
     428      }
     429    public:
     430
     431      BinaryToken() : _data(0), _size(0) {
     432      }
     433
     434      BinaryToken(const BinaryToken& other) : _data(0), _size(0) {
     435        if (this != &other && other.getSize() > 0) {
     436          _data = new char[_size = other.getSize()];
     437
     438          std::memcpy(_data, other.getData(), _size);
     439        }
     440      }
     441
     442      BinaryToken & operator=(const BinaryToken& other) {
     443        if (this != &other) {
     444          delete _data;
     445          _data = 0;
     446
     447          if ((_size = other.getSize()) > 0) {
     448            _data = new char[_size];
     449            std::memcpy(_data, other.getData(), _size);
     450          }
     451        }
     452
     453        return *this;
     454      }
     455
     456      ~BinaryToken() {
     457        delete _data;
     458      }
     459
     460      char const * getData() const {
     461        return _data;
     462      }
     463
     464      int getSize() const {
     465        return _size;
     466      }
     467
     468      friend inline std::istream& readTokenBinary(std::istream& is, BinaryToken& token, const _blgf_bits::BlgfType type);
     469    };
     470
     471    inline std::istream& readTokenBinary(std::istream& is, BinaryToken& token, const _blgf_bits::BlgfType type) {
     472      token.read(is, type);
     473      return is;
     474    }
     475
     476    template<typename Value>
     477    inline std::istream& readValueBinary(std::istream& is, _blgf_bits::BlgfType type, Value& value) {
     478      _reader_bits::BinaryToken token;
     479      readTokenBinary(is, token, type);
     480      value = _reader_bits::DefaultBinaryConverter<Value > ()(type, token.getData());
     481      return is;
     482    }
     483  };
     484
     485  namespace _writer_bits {
     486
     487    template <typename CppType>
     488    void toBinary(CppType value, char* array, int n) {
     489      //TODO: assert ??
     490      throw FormatError("Not an integer type ");
     491    };
     492
     493
     494#define MK_INTEGER_TO_BINARY(CppType)\
     495    template <> inline void toBinary<CppType>(CppType value, char* array, int n) {\
     496      for (register int i = n - 1; i >= 0; i--) {\
     497        array[i] = static_cast<char> (value & static_cast<CppType> (0xff));\
     498        value = value >> static_cast<CppType>(8);\
     499      }\
     500    };
     501
     502    /*MK_INTEGER_TO_BINARY:
     503     * Avoiding compilation error when using only specialised text converter.
     504     * In this case default binary converter is defined even if it is not used
     505     * and it causes a compilation error becouse the & operator is not defined
     506     * for most custom data types. So template toBinary() used for serializing
     507     * integer types is defined throught these macros only for integer types,
     508     * for others it throws error.
     509    */
     510
     511    MK_INTEGER_TO_BINARY(char)
     512    MK_INTEGER_TO_BINARY(signed char)
     513    MK_INTEGER_TO_BINARY(unsigned char)
     514
     515    MK_INTEGER_TO_BINARY(signed short)
     516    MK_INTEGER_TO_BINARY(unsigned short)
     517
     518    MK_INTEGER_TO_BINARY(signed int)
     519    MK_INTEGER_TO_BINARY(unsigned int)
     520
     521    MK_INTEGER_TO_BINARY(signed long)
     522    MK_INTEGER_TO_BINARY(unsigned long)
     523
     524#if LEMON_HAVE_LONG_LONG
     525    MK_INTEGER_TO_BINARY(signed long long)
     526    MK_INTEGER_TO_BINARY(unsigned long long)
     527#endif
     528
     529    /// \ingroup lemon_io
     530    ///
     531    /// \brief Common interface for manipulating with specialized value
     532    /// converters used in \ref blgf-format "BLGF" writer.
     533    ///
     534    /// This class defines an interface for manipulating with binary
     535    /// representation of the data.
     536    class BinaryTokenBase {
     537    public:
     538      /// \brief Destructor
     539      ///
     540      virtual ~BinaryTokenBase(){}
     541
     542      ///  \brief Get the \ref blgf-format "BLGF" type of the data.
     543      ///
     544      /// Get the \ref blgf-format "BLGF" type of the data.
     545      virtual _blgf_bits::BlgfType getType() const {
     546        return _blgf_bits::DATA;
     547      };
     548
     549      /// \brief Get the binary representation's size (in bytes).
     550      ///
     551      /// Get the binary representation's size (in bytes).
     552      virtual int getSize() const = 0;
     553
     554      /// \brief Copy converted data to buffer.
     555      ///
     556      /// Copy converted data to a specified buffer with a given size.
     557      virtual int write(char* buffer, int buffer_size) const = 0;
     558    };
     559
     560    /// \ingroup lemon_io
     561    ///
     562    /// \brief Base class for specialized value converters used in
     563    ///  \ref blgf-format "BLGF" writer.
     564    ///
     565    /// This class is a base class for all binary converters used in
     566    /// \ref blgf-format "BLGF" writer.
     567    /// It defines an interface for value conversions and for
     568    /// manipulations with the data.
     569    template <typename Value>
     570    class DefaultBinaryConverterBase : public BinaryTokenBase {
     571    public:
     572      /// \brief Set a new value for the converter.
     573      ///
     574      /// Set a new value for the converter. The \ref blgf-format "BLGF"
     575      /// type will be determined automatically.
     576      virtual void setValue(const Value& value) = 0;
     577
     578      /// \brief Set a new value for the converter
     579      ///
     580      /// Sets a new value for the binary converter and specifies \ref blgf-format "BLGF"
     581      /// type in which the data will be converted to.
     582      virtual void setValue(const Value& value, const _blgf_bits::BlgfType type){
     583        if (type != _blgf_bits::DATA)
     584          throw FormatError("Error custom converter data type");
     585
     586        setValue(value);
     587      }
     588    };
     589
     590    //Used for integer types
     591    template <typename Value>
     592    class DefaultBinaryConverter : public DefaultBinaryConverterBase<Value> {
     593    protected:
     594      Value _value;
     595      _blgf_bits::BlgfType _type;
     596    public:
     597
     598      DefaultBinaryConverter() {
     599      }
     600
     601      DefaultBinaryConverter(const Value& value) {
     602        setValue(value);
     603      }
     604
     605      void setValue(const Value& value, const _blgf_bits::BlgfType type) {
     606        if (std::numeric_limits<Value>::is_integer && _blgf_bits::is_integer(type)) {
     607          _value = value;
     608          _type = type;
     609          //TODO range check ?
     610
     611        } else
     612          throw FormatError("Not an integer type");
     613
     614      }
     615
     616      virtual void setValue(const Value& value) {
     617        _value = value;
     618        if (std::numeric_limits<Value>::is_integer) {
     619          if (std::numeric_limits<Value>::is_signed) {
     620            if (sizeof (Value) <= _blgf_bits::INT8_SIZE)
     621              _type = _blgf_bits::INT8;
     622            else if (sizeof (Value) <= _blgf_bits::INT16_SIZE)
     623              _type = _blgf_bits::INT16;
     624            else if (sizeof (Value) <= _blgf_bits::INT32_SIZE)
     625              _type = _blgf_bits::INT32;
     626            else if (sizeof (Value) <= _blgf_bits::INT64_SIZE)
     627              _type = _blgf_bits::INT64;
     628            else
     629              throw FormatError("Integer format too big");
     630
     631          } else {
     632            if (sizeof (Value) <= _blgf_bits::UINT8_SIZE)
     633              _type = _blgf_bits::UINT8;
     634            else if (sizeof (Value) <= _blgf_bits::UINT16_SIZE)
     635              _type = _blgf_bits::UINT16;
     636            else if (sizeof (Value) <= _blgf_bits::UINT32_SIZE)
     637              _type = _blgf_bits::UINT32;
     638            else if (sizeof (Value) <= _blgf_bits::UINT64_SIZE)
     639              _type = _blgf_bits::UINT64;
     640            else
     641              throw FormatError("Integer format too big");
     642          }
     643        } else if (std::numeric_limits<Value>::is_iec559) {
     644          if (sizeof (Value) == _blgf_bits::FLOAT_SIZE)
     645            _type = _blgf_bits::FLOAT;
     646          else if (sizeof (Value) == _blgf_bits::DOUBLE_SIZE)
     647            _type = _blgf_bits::DOUBLE;
     648          else
     649            throw FormatError("Unknown real type");
     650        } else {
     651          throw FormatError("Unknown type");
     652        }
     653
     654
     655      }
     656
     657      virtual _blgf_bits::BlgfType getType() const {
     658        return _type;
     659      }
     660
     661      virtual int getSize()const {
     662        return _blgf_bits::get_type_size(_type);
     663      }
     664
     665      virtual int write(char* buffer, const int buffer_size) const {
     666        int size = getSize();
     667        if (buffer_size < size) {
     668          throw FormatError("Buffer too small");
     669        }
     670
     671        if ((_blgf_bits::is_signed(_type)) ||
     672          (_blgf_bits::is_unsigned(_type))) {
     673
     674          toBinary(_value, buffer, size);
     675
     676        } else if (_blgf_bits::is_real(_type)) {
     677          for (register unsigned int i = 0; i< sizeof (Value); i++)
     678            buffer[i] = (reinterpret_cast<char*>(const_cast<Value*>(& _value)))[i];
     679        } else {
     680          throw FormatError("Error");
     681        }
     682
     683        return size;
     684      }
     685
     686
     687    };
     688
     689    template<>
     690    class DefaultBinaryConverter<float> : public DefaultBinaryConverterBase<float> {
     691    private:
     692      float _value;
     693      double _dvalue;
     694      _blgf_bits::BlgfType _type;
     695
     696    public:
     697
     698      DefaultBinaryConverter() {
     699
     700      }
     701
     702      DefaultBinaryConverter(const float& value) {
     703        setValue(value);
     704      }
     705
     706      virtual void setValue(const float& value, const _blgf_bits::BlgfType type){
     707        _type = type;
     708        if (type == _blgf_bits::FLOAT){
     709          _value = value;
     710        }else if (type == _blgf_bits::DOUBLE){
     711          _dvalue = value;
     712        }else
     713          throw FormatError("Can not convert float to this type");
     714      }
     715     
     716      virtual void setValue(const float& value) {
     717        setValue(value,_blgf_bits::FLOAT);
     718      }
     719
     720      virtual _blgf_bits::BlgfType getType() const {
     721        return _type;
     722      }
     723
     724      virtual int getSize()const {
     725        return _blgf_bits::get_type_size(_type);
     726      }
     727
     728      virtual int write(char* buffer, const int buffer_size) const {
     729        char* data = 0;
     730        int size = getSize();
     731
     732        if (getType() == _blgf_bits::FLOAT)
     733          data = reinterpret_cast<char*>(const_cast<float *>(&_value));
     734        else if (getType() == _blgf_bits::DOUBLE)
     735          data = reinterpret_cast<char*>(const_cast<double*>(&_dvalue));
     736        else
     737          throw FormatError("Can not convert float to this type of data");
     738
     739        if (buffer_size < size) {
     740          throw FormatError("Buffer too small");
     741        }
     742        if (_blgf_bits::is_real(_type)) {
     743          for (register int i = 0; i< size; i++)
     744            buffer[i] = (data)[i];
     745        } else {
     746          throw FormatError("Error float converter");
     747        }
     748        return size;
     749
     750      }
     751    };
     752
     753    template<>
     754    class DefaultBinaryConverter<double> : public DefaultBinaryConverterBase<double> {
     755    private:
     756      double _value;
     757      float _fvalue;
     758      _blgf_bits::BlgfType _type;
     759
     760    public:
     761
     762      DefaultBinaryConverter() {
     763
     764      }
     765
     766      DefaultBinaryConverter(const double& value) {
     767        setValue(value);
     768      }
     769
     770      virtual void setValue(const double& value, const _blgf_bits::BlgfType type){
     771         _type = type;
     772        if (type == _blgf_bits::FLOAT){
     773          if (value > static_cast<double>(std::numeric_limits<float>::max()) ||
     774            value < static_cast<double>(std::numeric_limits<float>::min()))
     775            throw FormatError("Float value out of range");
     776          _fvalue = value;
     777        }else if (type == _blgf_bits::DOUBLE){
     778          _value = value;
     779        }else
     780          throw FormatError("Can not convert double to this type");
     781      }
     782
     783      virtual void setValue(const double& value) {
     784        setValue(value,_blgf_bits::DOUBLE);
     785      }
     786
     787   
     788      virtual _blgf_bits::BlgfType getType() const {
     789        return _type;
     790      }
     791
     792      virtual int getSize()const {
     793        return _blgf_bits::get_type_size(_type);
     794      }
     795
     796      virtual int write(char* buffer, const int buffer_size) const {
     797        char * data = 0;
     798        int size = getSize();
     799        if (buffer_size < size) {
     800          throw FormatError("Buffer too small");
     801        }
     802
     803        if (getType() == _blgf_bits::FLOAT)
     804          data = reinterpret_cast<char*>(const_cast<float*>(&_fvalue));
     805        else if (getType() == _blgf_bits::DOUBLE)
     806          data = reinterpret_cast<char*>(const_cast<double*>(&_value));
     807        else
     808          throw FormatError("Can not convert double to this type of data");
     809
     810        if (_blgf_bits::is_real(_type)) {
     811          for (register int i = 0; i< size; i++)
     812            buffer[i] = (data)[i];
     813        } else {
     814          throw FormatError("Error double converter");
     815        }
     816 
     817        return size;
     818
     819      }
     820    };
     821
     822    template<>
     823    class DefaultBinaryConverter<std::string> : public DefaultBinaryConverterBase<std::string> {
     824    private:
     825      std::string _value;
     826      _blgf_bits::BlgfType _type;
     827    public:
     828
     829      DefaultBinaryConverter() {
     830
     831      }
     832
     833      DefaultBinaryConverter(const std::string& value) {
     834        setValue(value);
     835      }
     836
     837
     838      virtual void setValue(const std::string& value, const _blgf_bits::BlgfType type){
     839        if (type != _blgf_bits::STRING)
     840          throw FormatError("Cannot convert string to other type than STRING");
     841        setValue(value);
     842      }
     843
     844      void setValue(const std::string& value) {
     845        _value = value;
     846        _type = _blgf_bits::STRING;
     847      }
     848
     849      virtual int write(char* buffer, const int buffer_size) const {
     850        int size = getSize();
     851        if (buffer_size < size) {
     852          throw FormatError("Buffer too small");
     853        }
     854        for (register int i = 0; i < size; i++)
     855          buffer[i] = _value.c_str()[i];
     856        return size;
     857      }
     858
     859      virtual int getSize()const {
     860        return _value.length() + 1;
     861      }
     862
     863      virtual _blgf_bits::BlgfType getType() const {
     864        return _blgf_bits::STRING;
     865      }
     866    };
     867
     868    inline void writeDataBinary(std::ostream& os, const BinaryTokenBase& conv) {
     869      int size = conv.getSize();
     870      char *buff = new char[size];
     871      conv.write(buff, conv.getSize());
     872      os.write(buff, conv.getSize());
     873      delete buff;
     874    }
     875
     876  };
     877
     878};
     879
     880#endif  /* _BLGF_H */
     881
  • lemon/lgf_reader.h

    diff -r a93f1a27d831 -r 454f0c2a380c lemon/lgf_reader.h
    a b  
    1818
    1919///\ingroup lemon_io
    2020///\file
    21 ///\brief \ref lgf-format "LEMON Graph Format" reader.
     21///\brief \ref lgf-format "LEMON Graph Format" and
     22///\ref blgf-format "Binary LEMON Graph Format" reader.
    2223
    2324
    2425#ifndef LEMON_LGF_READER_H
    2526#define LEMON_LGF_READER_H
    2627
     28#include  <string>
     29
    2730#include <iostream>
    2831#include <fstream>
    2932#include <sstream>
     
    3336
    3437#include <lemon/core.h>
    3538
     39#include <lemon/blgf.h>
    3640#include <lemon/lgf_writer.h>
    3741
    3842#include <lemon/concept_check.h>
    3943#include <lemon/concepts/maps.h>
    4044
     45
     46//#include <limits>
     47
    4148namespace lemon {
    42 
     49 
    4350  namespace _reader_bits {
    4451
    4552    template <typename Value>
     
    7683      virtual ~MapStorageBase() {}
    7784
    7885      virtual void set(const Item& item, const std::string& value) = 0;
     86      virtual void setBinary(const Item& item ,const  char* data, const _blgf_bits::BlgfType blgfType) = 0;
    7987
    8088    };
    8189
    8290    template <typename _Item, typename _Map,
    83               typename _Converter = DefaultConverter<typename _Map::Value> >
     91              typename _Converter = DefaultConverter<typename _Map::Value>,
     92              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
    8493    class MapStorage : public MapStorageBase<_Item> {
    8594    public:
    8695      typedef _Map Map;
    8796      typedef _Converter Converter;
     97      typedef _BinaryConverter BinaryConverter;
    8898      typedef _Item Item;
    8999
    90100    private:
    91101      Map& _map;
    92102      Converter _converter;
     103      BinaryConverter _binaryConverter;
    93104
    94105    public:
    95       MapStorage(Map& map, const Converter& converter = Converter())
    96         : _map(map), _converter(converter) {}
     106      MapStorage(Map& map, const Converter& converter = Converter(),
     107              const BinaryConverter& binaryConverter = BinaryConverter())
     108        : _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
    97109      virtual ~MapStorage() {}
    98110
    99111      virtual void set(const Item& item ,const std::string& value) {
    100112        _map.set(item, _converter(value));
    101113      }
     114
     115      virtual void setBinary(const Item& item ,const  char* data, const _blgf_bits::BlgfType blgfType) {
     116        _map.set(item, _binaryConverter(blgfType,data));
     117      }
    102118    };
    103119
    104120    template <typename _GR, bool _dir, typename _Map,
    105               typename _Converter = DefaultConverter<typename _Map::Value> >
     121              typename _Converter = DefaultConverter<typename _Map::Value>,
     122              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
    106123    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
    107124    public:
    108125      typedef _Map Map;
    109126      typedef _Converter Converter;
     127      typedef _BinaryConverter BinaryConverter;
    110128      typedef _GR GR;
    111129      typedef typename GR::Edge Item;
    112130      static const bool dir = _dir;
     
    115133      const GR& _graph;
    116134      Map& _map;
    117135      Converter _converter;
     136      BinaryConverter _binaryConverter;
    118137
    119138    public:
    120139      GraphArcMapStorage(const GR& graph, Map& map,
    121                          const Converter& converter = Converter())
    122         : _graph(graph), _map(map), _converter(converter) {}
     140                         const Converter& converter = Converter(),
     141                         const BinaryConverter& binaryConverter = BinaryConverter())
     142        : _graph(graph), _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
    123143      virtual ~GraphArcMapStorage() {}
    124144
    125145      virtual void set(const Item& item ,const std::string& value) {
    126146        _map.set(_graph.direct(item, dir), _converter(value));
    127147      }
     148
     149      virtual void setBinary(const Item& item ,const char* data, const _blgf_bits::BlgfType blgfType) {
     150        _map.set(_graph.direct(item, dir), _binaryConverter(blgfType,data));
     151      }
    128152    };
    129153
    130154    class ValueStorageBase {
     
    147171
    148172    public:
    149173      ValueStorage(Value& value, const Converter& converter = Converter())
    150         : _value(value), _converter(converter) {}
     174        : _value(value), _converter(converter)
     175        {}
    151176
    152177      virtual void set(const std::string& value) {
    153178        _value = _converter(value);
     
    285310      }
    286311    }
    287312
     313   
     314
     315   
    288316    inline std::istream& readToken(std::istream& is, std::string& str) {
    289317      std::ostringstream os;
    290318
     
    399427
    400428  /// \ingroup lemon_io
    401429  ///
    402   /// \brief \ref lgf-format "LGF" reader for directed graphs
     430  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF"
     431  /// reader for directed graphs.
    403432  ///
    404   /// This utility reads an \ref lgf-format "LGF" file.
     433  /// This utility reads an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
     434  /// It automatically recognizes whether it is an \ref lgf-format "LGF" or
     435  /// a \ref blgf-format "BLGF" format.
    405436  ///
    406437  /// The reading method does a batch processing. The user creates a
    407438  /// reader object, then various reading rules can be added to the
    408439  /// reader, and eventually the reading is executed with the \c run()
    409440  /// member function. A map reading rule can be added to the reader
    410441  /// with the \c nodeMap() or \c arcMap() members. An optional
    411   /// converter parameter can also be added as a standard functor
    412   /// converting from \c std::string to the value type of the map. If it
    413   /// is set, it will determine how the tokens in the file should be
    414   /// converted to the value type of the map. If the functor is not set,
    415   /// then a default conversion will be used. One map can be read into
    416   /// multiple map objects at the same time. The \c attribute(), \c
    417   /// node() and \c arc() functions are used to add attribute reading
    418   /// rules.
     442  /// converter parameters can also be added as a standard
     443  /// functors converting from \c std::string or binary data
     444  /// to the value type of the map. If it is set, it will determine how
     445  /// the tokens in the file should be converted to the value type of
     446  /// the map. If the functor is not set, then a default conversion will
     447  /// be used. One map can be read into multiple map objects at the same time.
     448  /// The \c attribute(), \c node() and \c arc() functions are used to add
     449  /// attribute reading rules.
    419450  ///
    420451  ///\code
    421452  /// DigraphReader<DGR>(digraph, std::cin).
     
    427458  ///   run();
    428459  ///\endcode
    429460  ///
    430   /// By default, the reader uses the first section in the file of the
    431   /// proper type. If a section has an optional name, then it can be
     461  /// By default, the reader uses the first section/block in the file of the
     462  /// proper type. If a section/block has an optional name, then it can be
    432463  /// selected for reading by giving an optional name parameter to the
    433464  /// \c nodes(), \c arcs() or \c attributes() functions.
    434465  ///
     
    437468  /// graph) during the reading, but instead the label map of the items
    438469  /// are given as a parameter of these functions. An
    439470  /// application of these functions is multipass reading, which is
    440   /// important if two \c \@arcs sections must be read from the
     471  /// important if two \c \@arcs sections/blocks must be read from the
    441472  /// file. In this case the first phase would read the node set and one
    442473  /// of the arc sets, while the second phase would read the second arc
    443474  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
     
    609640
    610641    /// \brief Node map reading rule
    611642    ///
    612     /// Add a node map reading rule with specialized converter to the
     643    /// Add a node map reading rule with specialized text converter to the
    613644    /// reader.
    614645    template <typename Map, typename Converter>
    615646    DigraphReader& nodeMap(const std::string& caption, Map& map,
     
    621652      return *this;
    622653    }
    623654
     655
     656     /// \brief Node map reading rule
     657    ///
     658    /// Add a node map reading rule with specialized text and  binary converters
     659    /// to the reader.
     660    template <typename Map, typename Converter, typename BinaryConverter>
     661    DigraphReader& nodeMap(const std::string& caption, Map& map,
     662                           const Converter& converter = Converter(),
     663                            const BinaryConverter& binaryConverter = BinaryConverter()) {
     664      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
     665      _reader_bits::MapStorageBase<Node>* storage =
     666        new _reader_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     667      _node_maps.push_back(std::make_pair(caption, storage));
     668      return *this;
     669    }
     670
     671
    624672    /// \brief Arc map reading rule
    625673    ///
    626674    /// Add an arc map reading rule to the reader.
     
    635683
    636684    /// \brief Arc map reading rule
    637685    ///
    638     /// Add an arc map reading rule with specialized converter to the
     686    /// Add an arc map reading rule with specialized text and binary converters
     687    /// to the reader.
     688    template <typename Map, typename Converter, typename BinaryConverter>
     689    DigraphReader& arcMap(const std::string& caption, Map& map,
     690                          const Converter& converter = Converter(),
     691                            const BinaryConverter& binaryConverter = BinaryConverter()) {
     692      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
     693      _reader_bits::MapStorageBase<Arc>* storage =
     694        new _reader_bits::MapStorage<Arc, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     695      _arc_maps.push_back(std::make_pair(caption, storage));
     696      return *this;
     697    }
     698
     699    /// \brief Arc map reading rule
     700    ///
     701    /// Add an arc map reading rule with specialized text converter to the
    639702    /// reader.
    640703    template <typename Map, typename Converter>
    641704    DigraphReader& arcMap(const std::string& caption, Map& map,
     
    851914      }
    852915    }
    853916
     917    void skipMap(int itemCount, bool readCaption = true) {
     918      std::string caption;
     919      std::string str;
     920
     921      if (readCaption) {
     922        _reader_bits::readStrBinary(*_is, caption);
     923      }
     924     
     925      int type;
     926      _reader_bits::readValueBinary(*_is,_blgf_bits::TYPE_SPEC_TYPE, type);
     927
     928      if (type == _blgf_bits::STRING) {
     929        for (int i = 0; i < itemCount && readSuccess(); i++) {
     930          _reader_bits::readStrBinary(*_is, str);
     931        }
     932      } else if (type == _blgf_bits::DATA) {
     933        for (int i = 0; i < itemCount && readSuccess(); i++) {
     934          int size;
     935          _reader_bits::readValueBinary(*_is,_blgf_bits::SIZE_SPEC_TYPE, size);
     936          _is->seekg(size, std::ios_base::cur);
     937        }
     938      } else {
     939        _is->seekg(itemCount * _blgf_bits::get_type_size((_blgf_bits::BlgfType)type), std::ios_base::cur);
     940      }
     941
     942     
     943      if (!readSuccess())
     944        throw FormatError("Unexpected end of file.");
     945
     946    }
     947
     948    void skipBlock(_blgf_bits::BlgfBlockType type) {
     949      int count;
     950      char c;
     951      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, count);
     952
     953
     954      /* As the Label and From-To maps are obligatory and have empty names(only 0 byte)
     955       * they have to be read before the loop.
     956       */
     957      if (type == _blgf_bits::ARCS)
     958        skipMap(count * 2); //skip From-To map
     959      if (type == _blgf_bits::NODES)
     960        skipMap(count);  //skip Label map
     961
     962      _is->get(c);
     963      while (readSuccess() && c != 0) {
     964        _is->putback(c);
     965        skipMap(count);
     966        _is->get(c);
     967      }
     968     
     969      if (!readSuccess())
     970        throw FormatError("Unexpected end of file.");
     971      if (c != 0)
     972        throw FormatError("Map is not properly closed");
     973
     974    }
     975
     976    void readNodesBinary() {
     977      char c;
     978      int size;
     979      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
     980      std::vector<Node> nodes(size);
     981      std::set<std::string> maps;
     982      std::string map_name;
     983      int map_type;
     984      bool label_map = true;
     985
     986      _is->get(c);
     987      while (readSuccess() && (c!=0 || label_map) ) {
     988        _is->putback(c);
     989        //
     990        _reader_bits::readStrBinary(*_is, map_name);
     991        if (label_map) {
     992          if (!map_name.empty())
     993            throw FormatError("Label map not found");
     994          map_name = "label";
     995        }
     996        //
     997        std::set<std::string>::iterator mit = maps.find(map_name);
     998
     999        if (mit != maps.end()) {
     1000          std::ostringstream ss;
     1001          ss << "Multiple occurence of map: " << map_name;
     1002          throw FormatError(ss.str());
     1003        } else
     1004          maps.insert(map_name);
     1005        //
     1006        int map_index = 0;
     1007        for (map_index = 0; map_index < _node_maps.size() && _node_maps[map_index].first != map_name; map_index++);
     1008        //
     1009        if (!label_map && map_index == _node_maps.size()) {
     1010          skipMap(size, false);
     1011        } else {
     1012          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
     1013          for (int i = 0; i < size; i++) {
     1014            _reader_bits::BinaryToken token;
     1015            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
     1016
     1017            Node n;
     1018            if (label_map) {
     1019              if (!_use_nodes) {
     1020                n = _digraph.addNode();
     1021
     1022                _node_index.insert(
     1023                  std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
     1024                  , n));
     1025              } else {
     1026                typename std::map<std::string, Node>::iterator it =
     1027                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData()));
     1028                n = it->second;
     1029              }
     1030              nodes[i] = n;
     1031
     1032              //save to label map if exists
     1033              if (map_index < _node_maps.size())
     1034                _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
     1035
     1036            } else {
     1037              n = nodes[i];
     1038              _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
     1039            }
     1040
     1041          }
     1042        }
     1043        //
     1044        label_map = false;
     1045        _is->get(c);
     1046      }
     1047
     1048      if (!readSuccess())
     1049        throw FormatError("Unexpected end of file.");
     1050     
     1051      if (c != 0)
     1052        throw FormatError("Nodes block is not properly closed.");
     1053
     1054      if (maps.size()< _node_maps.size())
     1055        throw FormatError("Not all maps have been read.");
     1056    }
     1057
     1058 
    8541059    void readNodes() {
    8551060
    8561061      std::vector<int> map_index(_node_maps.size());
     
    9441149      }
    9451150    }
    9461151
     1152    void readArcsBinary(){
     1153      char c;
     1154      int size;
     1155      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
     1156      std::vector<Arc> arcs(size);
     1157      std::vector<std::string> labels(size);
     1158      std::set<std::string> maps;
     1159      std::string map_name;
     1160      int map_type;
     1161      bool from_to_map = true;
     1162
     1163      if(_use_arcs){
     1164        skipMap(2 * size);
     1165        from_to_map = false;
     1166      }
     1167
     1168      //
     1169      _is->get(c);
     1170      while (readSuccess() && (c != 0 || from_to_map)) {
     1171        _is->putback(c);
     1172        //
     1173        _reader_bits::readStrBinary(*_is, map_name);
     1174        if (from_to_map) {
     1175          if (!map_name.empty())
     1176            throw FormatError("From-to map not found");
     1177        }
     1178        //
     1179        std::set<std::string>::iterator mit = maps.find(map_name);
     1180
     1181        if (mit != maps.end()) {
     1182          std::ostringstream ss;
     1183          ss << "Multiple occurence of map: " << map_name;
     1184          throw FormatError(ss.str());
     1185        } else{
     1186          if (!map_name.empty())
     1187            maps.insert(map_name);
     1188        }
     1189        //
     1190        int map_index = 0;
     1191        for (map_index = 0; map_index < _arc_maps.size() && _arc_maps[map_index].first != map_name; map_index++);
     1192        //
     1193
     1194        if (!from_to_map && map_index == _arc_maps.size() && map_name !="label") {
     1195          skipMap(size, false);
     1196        } else {
     1197          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
     1198
     1199          for (int i = 0; i < size; i++) {
     1200            _reader_bits::BinaryToken token;
     1201            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
     1202
     1203            Arc a;
     1204            if (from_to_map) {
     1205             
     1206                typename std::map<std::string, Node>::iterator it =
     1207                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token.getData()));
     1208   
     1209                if (it == _node_index.end())
     1210                  throw FormatError("Source node not found");
     1211                Node source = it->second;
     1212
     1213                _reader_bits::BinaryToken token2;
     1214                _reader_bits::readTokenBinary(*_is,token2,(_blgf_bits::BlgfType)map_type);
     1215
     1216                it = _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token2.getData()));
     1217                if (it == _node_index.end())
     1218                  throw FormatError("Node u not found");
     1219                Node target = it->second;
     1220           
     1221                a = _digraph.addArc(source, target);
     1222
     1223                arcs[i] = a;
     1224            } else {
     1225
     1226              if (!_use_arcs){
     1227                a = arcs[i];
     1228                if (map_name =="label"){
     1229                 
     1230                  _arc_index.insert(
     1231                    std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
     1232                    , a));
     1233                }
     1234              }else{
     1235                if (map_name =="label"){
     1236                  labels[i] = _reader_bits::DefaultBinaryConverter<std::string>()((_blgf_bits::BlgfType)map_type,token.getData());
     1237                }
     1238
     1239                typename std::map<std::string, Arc>::iterator it =
     1240                  _arc_index.find(labels[i]);
     1241                if (it == _arc_index.end()) {
     1242                  std::ostringstream msg;
     1243                  msg << "Arc with label not found: " << labels[i];
     1244                  throw FormatError(msg.str());
     1245
     1246                }
     1247                a = it->second;
     1248              }
     1249             
     1250              //becouse of the label map
     1251              if (map_index < _arc_maps.size())
     1252                _arc_maps[map_index].second->setBinary(a, token.getData(), (_blgf_bits::BlgfType)map_type);
     1253            }
     1254          }
     1255        }
     1256        from_to_map = false;
     1257        //
     1258        _is->get(c);
     1259      }
     1260
     1261      if (!readSuccess())
     1262        throw FormatError("Unexpected end of file.");
     1263      if (c != 0)
     1264        throw FormatError("Arcs block is not properly closed");
     1265
     1266      if (maps.size()< _arc_maps.size())
     1267        throw FormatError("Not all maps have been read.");
     1268
     1269    }
     1270 
     1271   
    9471272    void readArcs() {
    9481273
    9491274      std::vector<int> map_index(_arc_maps.size());
     
    10651390      }
    10661391    }
    10671392
     1393    void readAttributesBinary() {
     1394        std::set<std::string> read_attr;
     1395        char c;
     1396        std::string attr_name;
     1397        std::string attr_value;
     1398       
     1399        _is->get(c);
     1400        while (readSuccess() && c != 0) {
     1401        _is->putback(c);
     1402       
     1403        _reader_bits::readStrBinary(*_is, attr_name);
     1404        if (!readSuccess())
     1405          throw FormatError("Attribute name not found");
     1406        _reader_bits::readStrBinary(*_is, attr_value);
     1407        if (!readSuccess())
     1408          throw FormatError("Attribute value not found");
     1409        {
     1410          std::set<std::string>::iterator it = read_attr.find(attr_name);
     1411          if (it != read_attr.end()) {
     1412            std::ostringstream msg;
     1413            msg << "Multiple occurence of attribute: " << attr_name;
     1414            throw FormatError(msg.str());
     1415          }
     1416          read_attr.insert(attr_name);
     1417        }
     1418
     1419        {
     1420          typename Attributes::iterator it = _attributes.lower_bound(attr_name);
     1421          while (it != _attributes.end() && it->first == attr_name) {
     1422            it->second->set(attr_value);
     1423            ++it;
     1424          }
     1425        }
     1426
     1427        _is->get(c);
     1428      }
     1429
     1430      if (c != 0)
     1431        throw FormatError("Attribute block is not properly closed");
     1432    }
     1433
    10681434    void readAttributes() {
    10691435
    10701436      std::set<std::string> read_attr;
     
    11131479      }
    11141480    }
    11151481
    1116   public:
    1117 
    1118     /// \name Execution of the Reader
    1119     /// @{
    1120 
    1121     /// \brief Start the batch processing
    1122     ///
    1123     /// This function starts the batch processing
    1124     void run() {
    1125       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
     1482    void runBinary() {
     1483      bool nodes_done = _skip_nodes;
     1484      bool arcs_done = _skip_arcs;
     1485      bool attributes_done = false;
     1486      char version[7];
     1487      std::string caption;
     1488
     1489      _is->read(version, 6);
     1490      version[7] = 0;
     1491      std::string s(version);
     1492
     1493      if (s.compare(0, 4, _blgf_bits::BLGF_VERSION, 0, 4) != 0)
     1494        throw FormatError("Unknown file format");
     1495
     1496      char c;
     1497      _is->get(c);
     1498     
     1499      while (readSuccess()){
     1500
     1501        _is->putback(c);
     1502
     1503        try {
     1504          int blockType = 0;
     1505         
     1506          if (!_reader_bits::readValueBinary(*_is,_blgf_bits::BLOCK_SPEC_TYPE,blockType))
     1507            throw FormatError("Unexpectedend of file");
     1508
     1509          if (blockType == _blgf_bits::NODES) {
     1510            _reader_bits::readStrBinary(*_is, caption);
     1511           
     1512            if ((!nodes_done) && (_nodes_caption.empty() || _nodes_caption == caption)) {
     1513              readNodesBinary();
     1514              nodes_done = true;
     1515            } else
     1516              skipBlock((_blgf_bits::BlgfBlockType) blockType);
     1517
     1518          } else if (blockType == _blgf_bits::ARCS) {
     1519            _reader_bits::readStrBinary(*_is, caption);
     1520            if ((!arcs_done) && (_arcs_caption.empty() || _arcs_caption == caption)) {
     1521              readArcsBinary();
     1522              arcs_done = true;
     1523            } else
     1524              skipBlock((_blgf_bits::BlgfBlockType)blockType);
     1525
     1526          } else if (blockType == _blgf_bits::ATTRIBUTES) {
     1527            readAttributesBinary();
     1528            attributes_done = true;
     1529          } else {
     1530            throw FormatError("Unrecognized type of block");
     1531          }
     1532
     1533        } catch (FormatError& error) {
     1534          error.file(_filename);
     1535          throw error;
     1536        }
     1537        _is->get(c);
     1538
     1539       
     1540      }
     1541
     1542     
     1543      if (!nodes_done) {
     1544        throw FormatError("Nodes block not found");
     1545      }
     1546
     1547      if (!arcs_done) {
     1548        throw FormatError("Arcs block not found");
     1549      }
     1550
     1551      if (!attributes_done && !_attributes.empty()) {
     1552        throw FormatError("Attributes block not found");
     1553      }
     1554    }
     1555
     1556    void runText() {
    11261557
    11271558      bool nodes_done = _skip_nodes;
    11281559      bool arcs_done = _skip_arcs;
     
    11741605        throw FormatError("Section @nodes not found");
    11751606      }
    11761607
    1177       if (!arcs_done) {
     1608      if (!arcs_done) { 
    11781609        throw FormatError("Section @arcs not found");
    11791610      }
    11801611
     
    11831614      }
    11841615
    11851616    }
     1617  public:
     1618
     1619    /// \name Execution of the Reader
     1620    /// @{
     1621
     1622    /// \brief Start the batch processing
     1623    ///
     1624    /// This function starts the batch processing
     1625    void run() {
     1626
     1627      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
     1628
     1629      char c;
     1630     _is->get(c);
     1631      _is->putback(c);
     1632
     1633      if (c == _blgf_bits::BLGF_VERSION[0]){
     1634          runBinary();
     1635      }else{
     1636          runText();
     1637      }
     1638
     1639
     1640
     1641    }
    11861642
    11871643    /// @}
    11881644
     
    11951651  /// This function just returns a \ref DigraphReader class.
    11961652  ///
    11971653  /// With this function a digraph can be read from an
    1198   /// \ref lgf-format "LGF" file or input stream with several maps and
    1199   /// attributes. For example, there is network flow problem on a
     1654  /// \ref lgf-format "LGF" or an \ref blgf-format "BLGF" file or input stream
     1655  /// with several maps and attributes.
     1656  /// For example, there is network flow problem on a
    12001657  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
    12011658  /// \e source and \e target nodes. This digraph can be read with the
    12021659  /// following code:
     
    12471704    return tmp;
    12481705  }
    12491706
    1250   template <typename GR>
     1707  template <typename GR> 
    12511708  class GraphReader;
    12521709 
    12531710  template <typename TGR>
     
    12591716
    12601717  /// \ingroup lemon_io
    12611718  ///
    1262   /// \brief \ref lgf-format "LGF" reader for undirected graphs
     1719  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" reader for
     1720  /// undirected graphs
    12631721  ///
    1264   /// This utility reads an \ref lgf-format "LGF" file.
     1722  /// This utility reads an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
     1723  /// It automatically recognizes whether it is an \ref lgf-format "LGF" or
     1724  /// a \ref blgf-format "BLGF" format.
    12651725  ///
    12661726  /// It can be used almost the same way as \c DigraphReader.
    12671727  /// The only difference is that this class can handle edges and
     
    14321892
    14331893    /// \brief Node map reading rule
    14341894    ///
     1895    /// Add a node map reading rule with specialized converters to the
     1896    /// reader.
     1897    template <typename Map, typename Converter, typename BinaryConverter>
     1898    GraphReader& nodeMap(const std::string& caption, Map& map,
     1899                           const Converter& converter = Converter(),
     1900                            const BinaryConverter& binaryConverter = BinaryConverter()) {
     1901      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
     1902      _reader_bits::MapStorageBase<Node>* storage =
     1903        new _reader_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     1904      _node_maps.push_back(std::make_pair(caption, storage));
     1905      return *this;
     1906    }
     1907
     1908    /// \brief Node map reading rule
     1909    ///
    14351910    /// Add a node map reading rule with specialized converter to the
    14361911    /// reader.
    14371912    template <typename Map, typename Converter>
     
    14561931      return *this;
    14571932    }
    14581933
     1934     /// \brief Edge map reading rule
     1935    ///
     1936    /// Add an edge map reading rule with specialized converters to the
     1937    /// reader.
     1938    template <typename Map, typename Converter,typename BinaryConverter>
     1939    GraphReader& edgeMap(const std::string& caption, Map& map,
     1940                          const Converter& converter = Converter(),
     1941                            const BinaryConverter& binaryConverter = BinaryConverter()) {
     1942      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
     1943      _reader_bits::MapStorageBase<Edge>* storage =
     1944        new _reader_bits::MapStorage<Edge, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     1945      _edge_maps.push_back(std::make_pair(caption, storage));
     1946      return *this;
     1947    }
    14591948    /// \brief Edge map reading rule
    14601949    ///
    14611950    /// Add an edge map reading rule with specialized converter to the
     
    14871976
    14881977    /// \brief Arc map reading rule
    14891978    ///
     1979    /// Add an arc map reading rule with specialized converters to the
     1980    /// reader.
     1981    template <typename Map, typename Converter, typename BinaryConverter>
     1982    GraphReader& arcMap(const std::string& caption, Map& map,
     1983                          const Converter& converter = Converter(),
     1984                            const BinaryConverter& binaryConverter = BinaryConverter()) {
     1985      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
     1986      _reader_bits::MapStorageBase<Edge>* forward_storage =
     1987        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter, BinaryConverter>
     1988        (_graph, map, converter, binaryConverter);
     1989      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
     1990      _reader_bits::MapStorageBase<Edge>* backward_storage =
     1991        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter,BinaryConverter>
     1992        (_graph, map, converter,binaryConverter);
     1993      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
     1994      return *this;
     1995    }
     1996
     1997    /// \brief Arc map reading rule
     1998    ///
    14901999    /// Add an arc map reading rule with specialized converter to the
    14912000    /// reader.
    14922001    template <typename Map, typename Converter>
     
    15152024      return *this;
    15162025    }
    15172026
     2027
    15182028    /// \brief Attribute reading rule
    15192029    ///
    15202030    /// Add an attribute reading rule with specialized converter to the
     
    17212231      }
    17222232    }
    17232233
     2234    void skipMap(int itemCount, bool readCaption = true) {
     2235      std::string caption;
     2236      std::string str;
     2237
     2238      if (readCaption) {
     2239        _reader_bits::readStrBinary(*_is, caption);
     2240      }
     2241
     2242      int type;
     2243      _reader_bits::readValueBinary(*_is,_blgf_bits::TYPE_SPEC_TYPE, type);
     2244
     2245      if (type == _blgf_bits::STRING) {
     2246        for (int i = 0; i < itemCount && readSuccess(); i++) {
     2247          _reader_bits::readStrBinary(*_is, str);
     2248        }
     2249      } else if (type == _blgf_bits::DATA) {
     2250        for (int i = 0; i < itemCount && readSuccess(); i++) {
     2251          int size;
     2252          _reader_bits::readValueBinary(*_is,_blgf_bits::SIZE_SPEC_TYPE, size);
     2253          _is->seekg(size, std::ios_base::cur);
     2254        }
     2255      } else {
     2256        _is->seekg(itemCount * _blgf_bits::get_type_size((_blgf_bits::BlgfType)type), std::ios_base::cur);
     2257      }
     2258
     2259
     2260      if (!readSuccess())
     2261        throw FormatError("Unexpected end of file.");
     2262
     2263    }
     2264
     2265    void skipBlock(_blgf_bits::BlgfBlockType type) {
     2266      int count;
     2267      char c;
     2268      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, count);
     2269
     2270      /* As the Label and From-To maps are obligatory and have empty names(only 0 byte)
     2271       * they have to be read before the loop.
     2272       */
     2273      if (type == _blgf_bits::ARCS)
     2274        skipMap(count * 2); //skip From-To map
     2275      if (type == _blgf_bits::NODES)
     2276        skipMap(count);  //skip Label map
     2277
     2278      _is->get(c);
     2279      while (readSuccess() && c != 0) {
     2280        _is->putback(c);
     2281        skipMap(count);
     2282        _is->get(c);
     2283      }
     2284
     2285      if (!readSuccess())
     2286        throw FormatError("Unexpected end of file.");
     2287      if (c != 0)
     2288        throw FormatError("Map is not properly closed");
     2289
     2290    }
     2291
     2292    void readNodesBinary() {
     2293      char c;
     2294      int size;
     2295      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
     2296      std::vector<Node> nodes(size);
     2297      std::set<std::string> maps;
     2298      std::string map_name;
     2299      int map_type;
     2300      bool label_map = true;
     2301
     2302      _is->get(c);
     2303      while (readSuccess() && (c!=0 || label_map) ) {
     2304        _is->putback(c);
     2305        //
     2306        _reader_bits::readStrBinary(*_is, map_name);
     2307        if (label_map) {
     2308          if (!map_name.empty())
     2309            throw FormatError("Label map not found");
     2310          map_name = "label";
     2311        }
     2312        //
     2313        std::set<std::string>::iterator mit = maps.find(map_name);
     2314
     2315        if (mit != maps.end()) {
     2316          std::ostringstream ss;
     2317          ss << "Multiple occurence of map: " << map_name;
     2318          throw FormatError(ss.str());
     2319        } else
     2320          maps.insert(map_name);
     2321        //
     2322        int map_index = 0;
     2323        for (map_index = 0; map_index < _node_maps.size() && _node_maps[map_index].first != map_name; map_index++);
     2324        //
     2325        if (!label_map && map_index == _node_maps.size()) {
     2326          skipMap(size, false);
     2327        } else {
     2328
     2329          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
     2330          for (int i = 0; i < size; i++) {
     2331            _reader_bits::BinaryToken token;
     2332            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
     2333
     2334            Node n;
     2335            if (label_map) {
     2336              if (!_use_nodes) {
     2337                n = _graph.addNode();
     2338
     2339                _node_index.insert(
     2340                  std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
     2341                  , n));
     2342              } else {
     2343                typename std::map<std::string, Node>::iterator it =
     2344                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData()));
     2345                n = it->second;
     2346              }
     2347              nodes[i] = n;
     2348
     2349              //save to label map if exists
     2350              if (map_index < _node_maps.size())
     2351                _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
     2352
     2353            } else {
     2354              n = nodes[i];
     2355              _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
     2356            }
     2357
     2358          }
     2359        }
     2360        //
     2361        label_map = false;
     2362        _is->get(c);
     2363      }
     2364
     2365      if (!readSuccess())
     2366        throw FormatError("Unexpected end of file.");
     2367
     2368      if (c != 0)
     2369        throw FormatError("Nodes block is not properly closed.");
     2370
     2371      if (maps.size()< _node_maps.size())
     2372        throw FormatError("Not all maps have been read.");
     2373    }
     2374
     2375 
     2376
    17242377    void readNodes() {
    17252378
    17262379      std::vector<int> map_index(_node_maps.size());
     
    18142467      }
    18152468    }
    18162469
     2470    void readEdgesBinary() {
     2471      char c;
     2472      int size;
     2473      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
     2474      std::vector<Edge> edges(size);
     2475      std::vector<std::string> labels(size);
     2476      std::set<std::string> maps;
     2477      std::string map_name;
     2478      int map_type;
     2479      bool from_to_map = true;
     2480
     2481      if(_use_edges){
     2482        skipMap(2 * size);
     2483        from_to_map = false;
     2484      }
     2485
     2486      //
     2487      _is->get(c);
     2488      while (readSuccess() && (c != 0 || from_to_map)) {
     2489        _is->putback(c);
     2490        //
     2491        _reader_bits::readStrBinary(*_is, map_name);
     2492        if (from_to_map) {
     2493          if (!map_name.empty())
     2494            throw FormatError("From-to map not found");
     2495        }
     2496        //
     2497        std::set<std::string>::iterator mit = maps.find(map_name);
     2498
     2499        if (mit != maps.end()) {
     2500          std::ostringstream ss;
     2501          ss << "Multiple occurence of map: " << map_name;
     2502          throw FormatError(ss.str());
     2503        } else{
     2504          if (!map_name.empty())
     2505            maps.insert(map_name);
     2506        }
     2507        //
     2508        int map_index = 0;
     2509        for (map_index = 0; map_index < _edge_maps.size() && _edge_maps[map_index].first != map_name; map_index++);
     2510        //
     2511
     2512        if (!from_to_map && map_index == _edge_maps.size() && map_name !="label") {
     2513          skipMap(size, false);
     2514        } else {
     2515          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
     2516
     2517          for (int i = 0; i < size; i++) {
     2518            _reader_bits::BinaryToken token;
     2519            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
     2520
     2521            Edge e;
     2522            if (from_to_map) {
     2523
     2524                typename std::map<std::string, Node>::iterator it =
     2525                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token.getData()));
     2526
     2527                if (it == _node_index.end())
     2528                  throw FormatError("Source node not found");
     2529                Node u = it->second;
     2530
     2531                _reader_bits::BinaryToken token2;
     2532                _reader_bits::readTokenBinary(*_is,token2,(_blgf_bits::BlgfType)map_type);
     2533               
     2534                it = _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token2.getData()));
     2535                if (it == _node_index.end())
     2536                  throw FormatError("Node u not found");
     2537                Node v = it->second;
     2538
     2539                e = _graph.addEdge(u, v);
     2540
     2541                edges[i] = e;
     2542            } else {
     2543
     2544              if (!_use_edges){
     2545                e = edges[i];
     2546                if (map_name =="label"){
     2547
     2548                  _edge_index.insert(
     2549                    std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
     2550                    , e));
     2551                }
     2552              }else{
     2553                if (map_name =="label"){
     2554                  labels[i] = _reader_bits::DefaultBinaryConverter<std::string>()((_blgf_bits::BlgfType)map_type,token.getData());
     2555                }
     2556
     2557                typename std::map<std::string, Edge>::iterator it =
     2558                  _edge_index.find(labels[i]);
     2559                if (it == _edge_index.end()) {
     2560                  std::ostringstream msg;
     2561                  msg << "Edge with label not found: " << labels[i];
     2562                  throw FormatError(msg.str());
     2563
     2564                }
     2565                e = it->second;
     2566              }
     2567
     2568              //becouse of the label map
     2569              if (map_index < _edge_maps.size())
     2570                _edge_maps[map_index].second->setBinary(e, token.getData(), (_blgf_bits::BlgfType)map_type);
     2571            }
     2572          }
     2573        }
     2574        from_to_map = false;
     2575        //
     2576        _is->get(c);
     2577      }
     2578
     2579      if (!readSuccess())
     2580        throw FormatError("Unexpected end of file.");
     2581      if (c != 0)
     2582        throw FormatError("Edge block is not properly closed");
     2583
     2584      if (maps.size()< _edge_maps.size())
     2585        throw FormatError("Not all maps have been read.");
     2586
     2587    }
     2588
     2589
     2590
    18172591    void readEdges() {
    18182592
    18192593      std::vector<int> map_index(_edge_maps.size());
     
    19352709      }
    19362710    }
    19372711
     2712    void readAttributesBinary() {
     2713        std::set<std::string> read_attr;
     2714        char c;
     2715        std::string attr_name;
     2716        std::string attr_value;
     2717
     2718        _is->get(c);
     2719        while (readSuccess() && c != 0) {
     2720        _is->putback(c);
     2721
     2722        _reader_bits::readStrBinary(*_is, attr_name);
     2723        if (!readSuccess())
     2724          throw FormatError("Attribute name not found");
     2725        _reader_bits::readStrBinary(*_is, attr_value);
     2726        if (!readSuccess())
     2727          throw FormatError("Attribute value not found");
     2728        {
     2729          std::set<std::string>::iterator it = read_attr.find(attr_name);
     2730          if (it != read_attr.end()) {
     2731            std::ostringstream msg;
     2732            msg << "Multiple occurence of attribute: " << attr_name;
     2733            throw FormatError(msg.str());
     2734          }
     2735          read_attr.insert(attr_name);
     2736        }
     2737
     2738        {
     2739          typename Attributes::iterator it = _attributes.lower_bound(attr_name);
     2740          while (it != _attributes.end() && it->first == attr_name) {
     2741            it->second->set(attr_value);
     2742            ++it;
     2743          }
     2744        }
     2745
     2746        _is->get(c);
     2747      }
     2748
     2749      if (c != 0)
     2750        throw FormatError("Attribute block is not properly closed");
     2751    }
     2752
    19382753    void readAttributes() {
    19392754
    19402755      std::set<std::string> read_attr;
     
    19832798      }
    19842799    }
    19852800
    1986   public:
    1987 
    1988     /// \name Execution of the Reader
    1989     /// @{
    1990 
    1991     /// \brief Start the batch processing
    1992     ///
    1993     /// This function starts the batch processing
    1994     void run() {
    1995 
    1996       LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
    1997 
     2801    void run_binary() {
    19982802      bool nodes_done = _skip_nodes;
    19992803      bool edges_done = _skip_edges;
    20002804      bool attributes_done = false;
    2001 
     2805      char version[7];
     2806      std::string caption;
     2807
     2808      _is->read(version, 6);
     2809      version[7] = 0;
     2810      std::string s(version);
     2811
     2812      //TODO testing of the version number ??
     2813      if (s.compare(0, 4, _blgf_bits::BLGF_VERSION, 0, 4) != 0)
     2814        throw FormatError("Unknown file format");
     2815
     2816      char c;
     2817      _is->get(c);
     2818     
     2819      while (readSuccess()){
     2820        _is->putback(c);
     2821
     2822        try {
     2823          int blockType = 0;
     2824
     2825          if (!_reader_bits::readValueBinary(*_is,_blgf_bits::BLOCK_SPEC_TYPE,blockType))
     2826            throw FormatError("Unexpectedend of file");
     2827
     2828          if (blockType == _blgf_bits::NODES) {
     2829            _reader_bits::readStrBinary(*_is, caption);
     2830
     2831            if ((!nodes_done) && (_nodes_caption.empty() || _nodes_caption == caption)) {
     2832              readNodesBinary();
     2833              nodes_done = true;
     2834            } else
     2835              skipBlock((_blgf_bits::BlgfBlockType) blockType);
     2836
     2837          } else if (blockType == _blgf_bits::ARCS) {
     2838            _reader_bits::readStrBinary(*_is, caption);
     2839            if ((!edges_done) && (_edges_caption.empty() || _edges_caption == caption)) {
     2840              readEdgesBinary();
     2841              edges_done = true;
     2842            } else
     2843              skipBlock((_blgf_bits::BlgfBlockType)blockType);
     2844
     2845          } else if (blockType == _blgf_bits::ATTRIBUTES) {
     2846            readAttributesBinary();
     2847            attributes_done = true;
     2848          } else {
     2849            throw FormatError("Unrecognized type of block");
     2850          }
     2851
     2852        } catch (FormatError& error) {
     2853          error.file(_filename);
     2854          throw error;
     2855        }
     2856        _is->get(c);
     2857
     2858      }
     2859
     2860
     2861      if (!nodes_done) {
     2862        throw FormatError("Nodes block not found");
     2863      }
     2864
     2865      if (!edges_done) {
     2866        throw FormatError("Arcs block not found");
     2867      }
     2868
     2869      if (!attributes_done && !_attributes.empty()) {
     2870        throw FormatError("Attributes block not found");
     2871      }
     2872    }
     2873
     2874
     2875    void run_text() {
     2876
     2877      bool nodes_done = _skip_nodes;
     2878      bool edges_done = _skip_edges;
     2879      bool attributes_done = false;
     2880     
    20022881      line_num = 0;
    20032882      readLine();
    20042883      skipSection();
     
    20522931      if (!attributes_done && !_attributes.empty()) {
    20532932        throw FormatError("Section @attributes not found");
    20542933      }
     2934     
     2935    }
     2936
     2937
     2938  public:
     2939
     2940
     2941
     2942    /// \name Execution of the Reader
     2943    /// @{
     2944
     2945    /// \brief Start the batch processing
     2946    ///
     2947    /// This function starts the batch processing
     2948    void run() {
     2949
     2950      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
     2951
     2952      char c;
     2953     _is->get(c);
     2954      _is->putback(c);
     2955
     2956      if (c == _blgf_bits::BLGF_VERSION[0]){
     2957          run_binary();
     2958      }else{
     2959          run_text();
     2960      }
     2961
     2962     
    20552963
    20562964    }
    20572965
     
    20662974  /// This function just returns a \ref GraphReader class.
    20672975  ///
    20682976  /// With this function a graph can be read from an
    2069   /// \ref lgf-format "LGF" file or input stream with several maps and
     2977  /// \ref lgf-format "LGF" or an \ref blgf-format "BLGF" file or input stream with several maps and
    20702978  /// attributes. For example, there is weighted matching problem on a
    20712979  /// graph, i.e. a graph with a \e weight map on the edges. This
    20722980  /// graph can be read with the following code:
  • lemon/lgf_writer.h

    diff -r a93f1a27d831 -r 454f0c2a380c lemon/lgf_writer.h
    a b  
    3939#include <lemon/concept_check.h>
    4040#include <lemon/concepts/maps.h>
    4141
     42#include <lemon/blgf.h>
     43
    4244namespace lemon {
    4345
    44   namespace _writer_bits {
     46  namespace _writer_bits { 
    4547
    4648    template <typename Value>
    4749    struct DefaultConverter {
     
    105107      virtual ~MapStorageBase() {}
    106108
    107109      virtual std::string get(const Item& item) = 0;
     110     
     111      virtual BinaryTokenBase const* getBinary(const Item& item) = 0;
     112
    108113      virtual void sort(std::vector<Item>&) = 0;
    109114    };
    110115
     116
    111117    template <typename _Item, typename _Map,
    112               typename _Converter = DefaultConverter<typename _Map::Value> >
     118              typename _Converter = DefaultConverter<typename _Map::Value>,
     119              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
    113120    class MapStorage : public MapStorageBase<_Item> {
    114121    public:
    115122      typedef _Map Map;
    116123      typedef _Converter Converter;
     124      typedef _BinaryConverter BinaryConverter;
    117125      typedef _Item Item;
    118126
    119127    private:
    120128      const Map& _map;
    121129      Converter _converter;
     130      BinaryConverter _binaryConverter;
    122131
    123132    public:
    124       MapStorage(const Map& map, const Converter& converter = Converter())
    125         : _map(map), _converter(converter) {}
     133      MapStorage(const Map& map, const Converter& converter = Converter(),
     134        const BinaryConverter& binaryConverter = BinaryConverter())
     135        : _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
    126136      virtual ~MapStorage() {}
    127137
    128138      virtual std::string get(const Item& item) {
    129139        return _converter(_map[item]);
    130140      }
     141
     142      virtual BinaryTokenBase* getBinary(const Item& item) {
     143        _binaryConverter.setValue(_map[item]);
     144        return &_binaryConverter;
     145        //return _converter(_map[item]);
     146      }
     147
    131148      virtual void sort(std::vector<Item>& items) {
    132149        MapLess<Map> less(_map);
    133150        std::sort(items.begin(), items.end(), less);
    134151      }
    135152    };
    136153
     154
    137155    template <typename _Graph, bool _dir, typename _Map,
    138               typename _Converter = DefaultConverter<typename _Map::Value> >
     156              typename _Converter = DefaultConverter<typename _Map::Value>,
     157              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
    139158    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
    140159    public:
    141160      typedef _Map Map;
    142161      typedef _Converter Converter;
     162      typedef _BinaryConverter BinaryConverter;
    143163      typedef _Graph Graph;
    144164      typedef typename Graph::Edge Item;
    145165      static const bool dir = _dir;
     
    148168      const Graph& _graph;
    149169      const Map& _map;
    150170      Converter _converter;
     171      BinaryConverter _binaryConverter;
    151172
    152173    public:
    153174      GraphArcMapStorage(const Graph& graph, const Map& map,
    154                          const Converter& converter = Converter())
    155         : _graph(graph), _map(map), _converter(converter) {}
     175                         const Converter& converter = Converter(),
     176                         const BinaryConverter& binaryConverter = BinaryConverter())
     177        : _graph(graph), _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
    156178      virtual ~GraphArcMapStorage() {}
    157179
    158180      virtual std::string get(const Item& item) {
    159181        return _converter(_map[_graph.direct(item, dir)]);
    160182      }
     183
     184      virtual BinaryTokenBase* getBinary(const Item& item) {
     185       ///_binaryConverter.setValue(_map[item]);
     186        _binaryConverter.setValue(_map[_graph.direct(item, dir)]);
     187        return &_binaryConverter;
     188      }
     189
    161190      virtual void sort(std::vector<Item>& items) {
    162191        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
    163192        std::sort(items.begin(), items.end(), less);
     
    172201      virtual std::string get() = 0;
    173202    };
    174203
     204
    175205    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
    176206    class ValueStorage : public ValueStorageBase {
    177207    public:
     
    184214
    185215    public:
    186216      ValueStorage(const Value& value, const Converter& converter = Converter())
    187         : _value(value), _converter(converter) {}
     217        : _value(value), _converter(converter)
     218        {}
    188219
    189220      virtual std::string get() {
    190221        return _converter(_value);
    191222      }
     223
    192224    };
    193225
    194226    template <typename Value>
     
    206238        }
    207239        return it->second;
    208240      }
     241
     242
    209243    };
    210244
    211245    template <typename Graph>
     
    362396
    363397  /// \ingroup lemon_io
    364398  ///
    365   /// \brief \ref lgf-format "LGF" writer for directed graphs
     399  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for directed graphs
    366400  ///
    367   /// This utility writes an \ref lgf-format "LGF" file.
     401  /// This utility writes an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
    368402  ///
    369403  /// The writing method does a batch processing. The user creates a
    370404  /// writer object, then various writing rules can be added to the
    371   /// writer, and eventually the writing is executed with the \c run()
    372   /// member function. A map writing rule can be added to the writer
     405  /// writer, and eventually the writing is executed with the
     406  /// \c run(bool binary = false, bool append = false))
     407  /// member function, where the \c binary parameter determines the file format and
     408  /// the \c append tells the writer whether the file should be appended or not.
     409  /// A map writing rule can be added to the writer
    373410  /// with the \c nodeMap() or \c arcMap() members. An optional
    374411  /// converter parameter can also be added as a standard functor
    375412  /// converting from the value type of the map to \c std::string. If it
     
    392429  ///
    393430  ///
    394431  /// By default, the writer does not write additional captions to the
    395   /// sections, but they can be give as an optional parameter of
     432  /// sections/blocks, but they can be given as an optional parameters of
    396433  /// the \c nodes(), \c arcs() or \c
    397434  /// attributes() functions.
    398435  ///
    399436  /// The \c skipNodes() and \c skipArcs() functions forbid the
    400   /// writing of the sections. If two arc sections should be written
     437  /// writing of the sections/blocks. If two arc sections/blocks should be written
    401438  /// to the output, it can be done in two passes, the first pass
    402   /// writes the node section and the first arc section, then the
    403   /// second pass skips the node section and writes just the arc
    404   /// section to the stream. The output stream can be retrieved with
     439  /// writes the node section/block and the first arc section/block, then the
     440  /// second pass skips the node section/block and writes just the arc
     441  /// section/block to the stream. The output stream can be retrieved with
    405442  /// the \c ostream() function, hence the second pass can append its
    406   /// output to the output of the first pass.
     443  /// output to the output of the first pass. In this case, if writing data binary,
     444  /// \c run() method has to be called with both parameters set to true.
    407445  template <typename DGR>
    408446  class DigraphWriter {
    409447  public:
     
    565603      return *this;
    566604    }
    567605
     606    /// \brief Node map writing rule
     607    ///
     608    /// Add a node map writing rule with specialized converters to the
     609    /// writer.
     610    template <typename Map, typename Converter,typename BinaryConverter>
     611    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
     612                           const Converter& converter = Converter(),
     613                           const BinaryConverter& binaryConverter = BinaryConverter()) {
     614      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     615      _writer_bits::MapStorageBase<Node>* storage =
     616        new _writer_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     617      _node_maps.push_back(std::make_pair(caption, storage));
     618      return *this;
     619    }
     620
    568621    /// \brief Arc map writing rule
    569622    ///
    570623    /// Add an arc map writing rule to the writer.
     
    591644      return *this;
    592645    }
    593646
     647    /// \brief Arc map writing rule
     648    ///
     649    /// Add an arc map writing rule with specialized converters to the
     650    /// writer.
     651    template <typename Map, typename Converter, typename BinaryConverter>
     652    DigraphWriter& arcMap(const std::string& caption, const Map& map,
     653                          const Converter& converter = Converter(),
     654                          const BinaryConverter& binaryConverter = BinaryConverter()) {
     655      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
     656      _writer_bits::MapStorageBase<Arc>* storage =
     657        new _writer_bits::MapStorage<Arc, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     658      _arc_maps.push_back(std::make_pair(caption, storage));
     659      return *this;
     660    }
     661
    594662    /// \brief Attribute writing rule
    595663    ///
    596664    /// Add an attribute writing rule to the writer.
     
    615683      return *this;
    616684    }
    617685
     686
    618687    /// \brief Node writing rule
    619688    ///
    620689    /// Add a node writing rule to the writer.
    621690    DigraphWriter& node(const std::string& caption, const Node& node) {
    622691      typedef _writer_bits::MapLookUpConverter<Node> Converter;
     692
    623693      Converter converter(_node_index);
     694
    624695      _writer_bits::ValueStorageBase* storage =
    625696        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
    626697      _attributes.push_back(std::make_pair(caption, storage));
     
    691762
    692763  private:
    693764
     765    void writeNodesBinary() {
     766      _writer_bits::MapStorageBase<Node>* label = 0;
     767
     768      for (typename NodeMaps::iterator it = _node_maps.begin();
     769        it != _node_maps.end(); ++it) {
     770        if (it->first == "label") {
     771          label = it->second;
     772          break;
     773        }
     774      }
     775
     776      std::vector<Node> nodes;
     777      for (NodeIt n(_digraph); n != INVALID; ++n) {
     778        nodes.push_back(n);
     779      }
     780
     781      if (nodes.size() == 0)
     782        return;
     783
     784      if (label == 0) {
     785        IdMap<DGR, Node> id_map(_digraph);
     786        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
     787        std::sort(nodes.begin(), nodes.end(), id_less);
     788      } else {
     789        label->sort(nodes);
     790      }
     791
     792      //BLOCK
     793      //Type
     794      {
     795        _writer_bits::DefaultBinaryConverter<int> conv;
     796        conv.setValue(_blgf_bits::NODES,_blgf_bits::BLOCK_SPEC_TYPE);
     797        _writer_bits::writeDataBinary(*_os,conv);
     798      }
     799      //Caption
     800      {
     801
     802        _writer_bits::DefaultBinaryConverter<std::string> conv(_nodes_caption);
     803        _writer_bits::writeDataBinary(*_os,conv);
     804      }
     805      //Size
     806      {
     807        _writer_bits::DefaultBinaryConverter<int> conv;
     808        //int size  = static_cast<int>(nodes.size());
     809        conv.setValue(static_cast<int>(nodes.size()),_blgf_bits::SIZE_SPEC_TYPE);
     810        _writer_bits::writeDataBinary(*_os,conv);
     811      }
     812      //LABEL
     813      //name
     814      _os->put(0);
     815      //type
     816      {
     817        _blgf_bits::BlgfType type;
     818        if (label == 0 || static_cast<int>(nodes.size()) == 0)
     819          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     820        else{
     821          _writer_bits::BinaryTokenBase const*conv = label->getBinary(nodes[0]);
     822          type = conv->getType();
     823        }
     824        //TODO: Documentatnion
     825        if (type == _blgf_bits::DATA)
     826          throw  FormatError("Labels must be a fundemental type");
     827
     828        _writer_bits::DefaultBinaryConverter<int> conv;
     829        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
     830        _writer_bits::writeDataBinary(*_os,conv);
     831      }
     832      //data
     833      for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
     834        Node n = nodes[i];
     835        if (label == 0) {
     836          std::ostringstream os;
     837          int id = _digraph.id(n);
     838          os << id;
     839         
     840          _writer_bits::DefaultBinaryConverter<int> conv(id);
     841          _writer_bits::writeDataBinary(*_os,conv);
     842
     843          _node_index.insert(std::make_pair(n, os.str()));
     844        } else {
     845          //TODO: Documentation - get es nem getBinary
     846          std::string value = label->get(n);
     847
     848          _writer_bits::BinaryTokenBase const* c = label->getBinary(n);
     849          _writer_bits::writeDataBinary(*_os,*c);
     850
     851          _node_index.insert(std::make_pair(n, value));
     852        }
     853      }
     854
     855      for (typename NodeMaps::iterator it = _node_maps.begin();
     856        it != _node_maps.end(); ++it) {
     857        if (it->first == "label")
     858          continue;
     859       
     860        //Name
     861        {
     862          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
     863          _writer_bits::writeDataBinary(*_os,conv);
     864        }
     865        //type
     866        {
     867          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
     868          if (nodes.size()>0)
     869            type = it->second->getBinary(nodes[0])->getType();
     870
     871          _writer_bits::DefaultBinaryConverter<int> conv;
     872          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     873          _writer_bits::writeDataBinary(*_os, conv);
     874        }
     875        //Data
     876        for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
     877          Node n = nodes[i];
     878          //
     879          _writer_bits::BinaryTokenBase const * c = it->second->getBinary(n);
     880          if (c->getType() == _blgf_bits::DATA){
     881            _writer_bits::DefaultBinaryConverter<int> conv;
     882            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
     883            _writer_bits::writeDataBinary(*_os,conv);
     884          }
     885          _writer_bits::writeDataBinary(*_os,*c);
     886        }
     887      }
     888
     889      _os->put(0);
     890    }
     891
    694892    void writeNodes() {
    695893      _writer_bits::MapStorageBase<Node>* label = 0;
    696894      for (typename NodeMaps::iterator it = _node_maps.begin();
     
    775973      }
    776974    }
    777975
     976    void writeArcsBinary() {
     977      _writer_bits::MapStorageBase<Arc>* label = 0;
     978      _writer_bits::MapStorageBase<Node>* node_labels = 0;
     979
     980      for (typename ArcMaps::iterator it = _arc_maps.begin();
     981        it != _arc_maps.end(); ++it) {
     982        if (it->first == "label") {
     983          label = it->second;
     984          break;
     985        }
     986      }
     987
     988      for (typename NodeMaps::iterator it = _node_maps.begin();
     989        it != _node_maps.end(); ++it) {
     990        if (it->first == "label") {
     991          node_labels = it->second;
     992          break;
     993        }
     994      }
     995
     996      std::vector<Arc> arcs;
     997      for (ArcIt a(_digraph); a != INVALID; ++a) {
     998        arcs.push_back(a);
     999      }
     1000
     1001      if (arcs.size() == 0)
     1002        return;
     1003
     1004      if (label == 0) {
     1005        IdMap<DGR, Arc> id_map(_digraph);
     1006        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
     1007        std::sort(arcs.begin(), arcs.end(), id_less);
     1008      } else {
     1009        label->sort(arcs);
     1010      }
     1011
     1012      //BLOCK
     1013      //Type
     1014      {
     1015        _writer_bits::DefaultBinaryConverter<int> conv;
     1016        conv.setValue(_blgf_bits::ARCS,_blgf_bits::BLOCK_SPEC_TYPE);
     1017        _writer_bits::writeDataBinary(*_os,conv);
     1018      }
     1019      //Caption
     1020      {
     1021
     1022        _writer_bits::DefaultBinaryConverter<std::string> conv(_arcs_caption);
     1023        _writer_bits::writeDataBinary(*_os,conv);
     1024      }
     1025      //Size
     1026      {
     1027        _writer_bits::DefaultBinaryConverter<int> conv;
     1028        conv.setValue(static_cast<int>(arcs.size()),_blgf_bits::SIZE_SPEC_TYPE);
     1029        _writer_bits::writeDataBinary(*_os,conv);
     1030      }
     1031
     1032      //FROM_TO
     1033      //name
     1034      _os->put(0);
     1035      //type
     1036      {
     1037        _blgf_bits::BlgfType type;
     1038        if (node_labels == 0 || static_cast<int> (arcs.size()) == 0)
     1039          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     1040        else{
     1041
     1042          _writer_bits::BinaryTokenBase const* conv = node_labels->getBinary(_digraph.source(arcs[0]));
     1043          type = conv->getType();
     1044        }
     1045
     1046        if (type == _blgf_bits::DATA)
     1047          throw FormatError("Labels must be a fundemental type");
     1048       
     1049        _writer_bits::DefaultBinaryConverter<int> conv;
     1050        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
     1051        _writer_bits::writeDataBinary(*_os,conv);
     1052      }
     1053      //data
     1054      for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
     1055        Arc a = arcs[i];
     1056
     1057        if (node_labels != 0) {
     1058          _writer_bits::BinaryTokenBase const * source = node_labels->getBinary(_digraph.source(a));
     1059          _writer_bits::writeDataBinary(*_os,*source);
     1060          _writer_bits::BinaryTokenBase const * target = node_labels->getBinary(_digraph.target(a));
     1061          _writer_bits::writeDataBinary(*_os,*target);
     1062
     1063        } else {
     1064          int source = _digraph.id(_digraph.source(a));
     1065          int target = _digraph.id(_digraph.target(a));
     1066          _writer_bits::DefaultBinaryConverter<int> conv;
     1067
     1068          conv.setValue(source);
     1069          _writer_bits::writeDataBinary(*_os,conv);
     1070
     1071          conv.setValue(target);
     1072          _writer_bits::writeDataBinary(*_os,conv);
     1073        }
     1074      }
     1075
     1076      if (label != 0) {
     1077        //Label
     1078        //name
     1079        {
     1080          _writer_bits::DefaultBinaryConverter<std::string> conv("label");
     1081          _writer_bits::writeDataBinary(*_os,conv);
     1082        }
     1083        //type
     1084        {
     1085          _blgf_bits::BlgfType type;
     1086          if (static_cast<int> (arcs.size()) == 0)
     1087            type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     1088          else {
     1089            _writer_bits::BinaryTokenBase const * conv = label->getBinary(arcs[0]);
     1090            type = conv->getType();
     1091          }
     1092
     1093          if (type == _blgf_bits::DATA)
     1094            throw FormatError("Labels must be a fundemental type");
     1095         
     1096          _writer_bits::DefaultBinaryConverter<int> conv;
     1097          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     1098          _writer_bits::writeDataBinary(*_os, conv);
     1099        }
     1100        //data
     1101        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
     1102          Arc a = arcs[i];
     1103            _writer_bits::BinaryTokenBase const *conv = label->getBinary(a) ;
     1104            _writer_bits::writeDataBinary(*_os, *conv);
     1105
     1106             std::string value = label->get(a);
     1107            _arc_index.insert(std::make_pair(a, value));
     1108          }
     1109      }else{
     1110        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
     1111          Arc a = arcs[i];
     1112          std::ostringstream os;
     1113          int id = _digraph.id(a);
     1114          os << id;
     1115
     1116          _arc_index.insert(std::make_pair(a, os.str()));
     1117        }
     1118      }
     1119
     1120
     1121      for (typename ArcMaps::iterator it = _arc_maps.begin();
     1122        it != _arc_maps.end(); ++it) {
     1123        if (it->first == "label")
     1124          continue;
     1125
     1126        //Name
     1127        {
     1128          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
     1129          _writer_bits::writeDataBinary(*_os,conv);
     1130        }
     1131        //type
     1132        {
     1133          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
     1134          if (arcs.size()>0)
     1135            type = it->second->getBinary(arcs[0])->getType();
     1136
     1137          _writer_bits::DefaultBinaryConverter<int> conv;
     1138          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     1139          _writer_bits::writeDataBinary(*_os, conv);
     1140        }
     1141        //Data
     1142        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
     1143          Arc n = arcs[i];
     1144          //
     1145          _writer_bits::BinaryTokenBase const *c = it->second->getBinary(n);
     1146          if (c->getType() == _blgf_bits::DATA){
     1147            _writer_bits::DefaultBinaryConverter<int> conv;
     1148            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
     1149            _writer_bits::writeDataBinary(*_os,conv);
     1150          }
     1151          _writer_bits::writeDataBinary(*_os,*c);
     1152        }
     1153      }
     1154     
     1155      _os->put(0);
     1156    }
     1157
    7781158    void writeArcs() {
    7791159      _writer_bits::MapStorageBase<Arc>* label = 0;
    7801160      for (typename ArcMaps::iterator it = _arc_maps.begin();
     
    8661246      }
    8671247    }
    8681248
     1249
     1250    void writeAttributesBinary() {
     1251      if (_attributes.size() == 0)
     1252        return;
     1253      //BLOCK
     1254      //Type
     1255      {
     1256        _writer_bits::DefaultBinaryConverter<int> conv;
     1257        conv.setValue(_blgf_bits::ATTRIBUTES,_blgf_bits::BLOCK_SPEC_TYPE);
     1258        _writer_bits::writeDataBinary(*_os,conv);
     1259      }
     1260
     1261      for (typename Attributes::iterator it = _attributes.begin();
     1262           it != _attributes.end(); ++it) {
     1263
     1264        _writer_bits::DefaultBinaryConverter<std::string> cstr(it->first);
     1265        _writer_bits::writeDataBinary(*_os,cstr);
     1266       
     1267        cstr.setValue(it->second->get());
     1268        _writer_bits::writeDataBinary(*_os,cstr);
     1269       
     1270      }
     1271
     1272      _os->put(0);
     1273    }
     1274
    8691275    void writeAttributes() {
    8701276      if (_attributes.empty()) return;
    8711277      *_os << "@attributes";
     
    8891295    /// \brief Start the batch processing
    8901296    ///
    8911297    /// This function starts the batch processing.
    892     void run() {
     1298    void run(bool binary = false, bool append = false) {
     1299
     1300      if (binary && !append){
     1301        _os->write(_blgf_bits::BLGF_VERSION,6);
     1302      }
     1303
     1304
    8931305      if (!_skip_nodes) {
    894         writeNodes();
     1306        if (!binary)
     1307          writeNodes();
     1308        else
     1309          writeNodesBinary();
    8951310      } else {
    8961311        createNodeIndex();
    8971312      }
    8981313      if (!_skip_arcs) {
    899         writeArcs();
     1314        if (!binary)
     1315          writeArcs();
     1316        else
     1317          writeArcsBinary();
    9001318      } else {
    9011319        createArcIndex();
    9021320      }
    903       writeAttributes();
     1321      if (!binary)
     1322        writeAttributes();
     1323      else
     1324        writeAttributesBinary();
     1325
     1326      //if (binary)
     1327      //  _os->put(0);
    9041328    }
    9051329
    9061330    /// \brief Give back the stream of the writer
     
    9201344  /// This function just returns a \ref DigraphWriter class.
    9211345  ///
    9221346  /// With this function a digraph can be write to a file or output
    923   /// stream in \ref lgf-format "LGF" format with several maps and
     1347  /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and
    9241348  /// attributes. For example, with the following code a network flow
    9251349  /// problem can be written to the standard output, i.e. a digraph
    9261350  /// with a \e capacity map on the arcs and \e source and \e target
     
    9861410
    9871411  /// \ingroup lemon_io
    9881412  ///
    989   /// \brief \ref lgf-format "LGF" writer for directed graphs
     1413  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for undirected graphs
    9901414  ///
    991   /// This utility writes an \ref lgf-format "LGF" file.
     1415  /// This utility writes an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
    9921416  ///
    9931417  /// It can be used almost the same way as \c DigraphWriter.
    9941418  /// The only difference is that this class can handle edges and
     
    9971421  /// The arc maps are written into the file as two columns, the
    9981422  /// caption of the columns are the name of the map prefixed with \c
    9991423  /// '+' and \c '-'. The arcs are written into the \c \@attributes
    1000   /// section as a \c '+' or a \c '-' prefix (depends on the direction
     1424  /// section/block as a \c '+' or a \c '-' prefix (depends on the direction
    10011425  /// of the arc) and the label of corresponding edge.
    10021426  template <typename GR>
    10031427  class GraphWriter {
     
    11441568      return *this;
    11451569    }
    11461570
     1571
     1572    /// \brief Node map writing rule
     1573    ///
     1574    /// Add a node map writing rule with specialized converters to the
     1575    /// writer.
     1576    template <typename Map, typename Converter,typename BinaryConverter>
     1577    GraphWriter& nodeMap(const std::string& caption, const Map& map,
     1578                           const Converter& converter = Converter(),
     1579                           const BinaryConverter& binaryConverter = BinaryConverter()) {
     1580      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     1581      _writer_bits::MapStorageBase<Node>* storage =
     1582        new _writer_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     1583      _node_maps.push_back(std::make_pair(caption, storage));
     1584      return *this;
     1585    }
     1586
    11471587    /// \brief Node map writing rule
    11481588    ///
    11491589    /// Add a node map writing rule with specialized converter to the
     
    11721612
    11731613    /// \brief Edge map writing rule
    11741614    ///
     1615    /// Add an edge map writing rule with specialized converters to the
     1616    /// writer.
     1617    template <typename Map, typename Converter, typename BinaryConverter>
     1618    GraphWriter& edgeMap(const std::string& caption, const Map& map,
     1619                          const Converter& converter = Converter(),
     1620                          const BinaryConverter& binaryConverter = BinaryConverter()) {
     1621      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
     1622      _writer_bits::MapStorageBase<Edge>* storage =
     1623        new _writer_bits::MapStorage<Edge, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
     1624      _edge_maps.push_back(std::make_pair(caption, storage));
     1625      return *this;
     1626    }
     1627
     1628    /// \brief Edge map writing rule
     1629    ///
    11751630    /// Add an edge map writing rule with specialized converter to the
    11761631    /// writer.
    11771632    template <typename Map, typename Converter>
     
    12011656
    12021657    /// \brief Arc map writing rule
    12031658    ///
     1659    /// Add an arc map writing rule with specialized converters to the
     1660    /// writer.
     1661    template <typename Map, typename Converter, typename BinaryConverter>
     1662    GraphWriter& arcMap(const std::string& caption, const Map& map,
     1663                          const Converter& converter = Converter(),
     1664                          const BinaryConverter& binaryConverter = BinaryConverter()) {
     1665      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
     1666
     1667      _writer_bits::MapStorageBase<Edge>* forward_storage =
     1668        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter,BinaryConverter>
     1669        (_graph, map, converter,binaryConverter);
     1670      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
     1671      _writer_bits::MapStorageBase<Edge>* backward_storage =
     1672        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter,BinaryConverter>
     1673        (_graph, map, converter,binaryConverter);
     1674      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
     1675
     1676
     1677      return *this;
     1678    }
     1679
     1680    /// \brief Arc map writing rule
     1681    ///
    12041682    /// Add an arc map writing rule with specialized converter to the
    12051683    /// writer.
    12061684    template <typename Map, typename Converter>
     
    12181696      return *this;
    12191697    }
    12201698
     1699
     1700
     1701
    12211702    /// \brief Attribute writing rule
    12221703    ///
    12231704    /// Add an attribute writing rule to the writer.
     
    13301811
    13311812  private:
    13321813
     1814    void writeNodesBinary() {
     1815      _writer_bits::MapStorageBase<Node>* label = 0;
     1816
     1817      for (typename NodeMaps::iterator it = _node_maps.begin();
     1818        it != _node_maps.end(); ++it) {
     1819        if (it->first == "label") {
     1820          label = it->second;
     1821          break;
     1822        }
     1823      }
     1824
     1825      std::vector<Node> nodes;
     1826      for (NodeIt n(_graph); n != INVALID; ++n) {
     1827        nodes.push_back(n);
     1828      }
     1829
     1830      if (nodes.size() == 0)
     1831        return;
     1832
     1833      if (label == 0) {
     1834        IdMap<GR, Node> id_map(_graph);
     1835        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
     1836        std::sort(nodes.begin(), nodes.end(), id_less);
     1837      } else {
     1838        label->sort(nodes);
     1839      }
     1840
     1841      //BLOCK
     1842      //Type
     1843      {
     1844        _writer_bits::DefaultBinaryConverter<int> conv;
     1845        conv.setValue(_blgf_bits::NODES,_blgf_bits::BLOCK_SPEC_TYPE);
     1846        _writer_bits::writeDataBinary(*_os,conv);
     1847      }
     1848      //Caption
     1849      {
     1850
     1851        _writer_bits::DefaultBinaryConverter<std::string> conv(_nodes_caption);
     1852        _writer_bits::writeDataBinary(*_os,conv);
     1853      }
     1854      //Size
     1855      {
     1856        _writer_bits::DefaultBinaryConverter<int> conv;
     1857        conv.setValue(static_cast<int>(nodes.size()),_blgf_bits::SIZE_SPEC_TYPE);
     1858        _writer_bits::writeDataBinary(*_os,conv);
     1859      }
     1860      //LABEL
     1861      //name
     1862      _os->put(0);
     1863      //type
     1864      {
     1865        _blgf_bits::BlgfType type;
     1866        if (label == 0 || static_cast<int>(nodes.size()) == 0)
     1867          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     1868        else{
     1869          _writer_bits::BinaryTokenBase const*conv = label->getBinary(nodes[0]);
     1870          type = conv->getType();
     1871        }
     1872
     1873        if (type == _blgf_bits::DATA)
     1874          throw  FormatError("Labels must be a fundemental type");
     1875
     1876        _writer_bits::DefaultBinaryConverter<int> conv;
     1877        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
     1878        _writer_bits::writeDataBinary(*_os,conv);
     1879      }
     1880      //data
     1881      for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
     1882        Node n = nodes[i];
     1883        if (label == 0) {
     1884          std::ostringstream os;
     1885          int id = _graph.id(n);
     1886          os << id;
     1887
     1888          _writer_bits::DefaultBinaryConverter<int> conv(id);
     1889          _writer_bits::writeDataBinary(*_os,conv);
     1890
     1891          _node_index.insert(std::make_pair(n, os.str()));
     1892        } else {
     1893
     1894          std::string value = label->get(n);
     1895
     1896          _writer_bits::BinaryTokenBase const* c = label->getBinary(n);
     1897          _writer_bits::writeDataBinary(*_os,*c);
     1898
     1899          _node_index.insert(std::make_pair(n, value));
     1900        }
     1901      }
     1902
     1903      for (typename NodeMaps::iterator it = _node_maps.begin();
     1904        it != _node_maps.end(); ++it) {
     1905        if (it->first == "label")
     1906          continue;
     1907
     1908        //Name
     1909        {
     1910          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
     1911          _writer_bits::writeDataBinary(*_os,conv);
     1912        }
     1913        //type
     1914        {
     1915          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
     1916          if (nodes.size()>0)
     1917            type = it->second->getBinary(nodes[0])->getType();
     1918
     1919          _writer_bits::DefaultBinaryConverter<int> conv;
     1920          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     1921          _writer_bits::writeDataBinary(*_os, conv);
     1922        }
     1923        //Data
     1924        for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
     1925          Node n = nodes[i];
     1926          //
     1927          _writer_bits::BinaryTokenBase const * c = it->second->getBinary(n);
     1928          if (c->getType() == _blgf_bits::DATA){
     1929            _writer_bits::DefaultBinaryConverter<int> conv;
     1930            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
     1931            _writer_bits::writeDataBinary(*_os,conv);
     1932          }
     1933          _writer_bits::writeDataBinary(*_os,*c);
     1934        }
     1935      }
     1936
     1937      _os->put(0);
     1938    }
     1939
    13331940    void writeNodes() {
    13341941      _writer_bits::MapStorageBase<Node>* label = 0;
    13351942      for (typename NodeMaps::iterator it = _node_maps.begin();
     
    14142021      }
    14152022    }
    14162023
     2024     void writeEdgesBinary() {
     2025      _writer_bits::MapStorageBase<Edge>* label = 0;
     2026      _writer_bits::MapStorageBase<Node>* node_labels = 0;
     2027
     2028      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2029        it != _edge_maps.end(); ++it) {
     2030        if (it->first == "label") {
     2031          label = it->second;
     2032          break;
     2033        }
     2034      }
     2035
     2036      for (typename NodeMaps::iterator it = _node_maps.begin();
     2037        it != _node_maps.end(); ++it) {
     2038        if (it->first == "label") {
     2039          node_labels = it->second;
     2040          break;
     2041        }
     2042      }
     2043
     2044      std::vector<Edge> edges;
     2045      for (EdgeIt e(_graph); e != INVALID; ++e) {
     2046        edges.push_back(e);
     2047      }
     2048
     2049      if (edges.size() == 0)
     2050        return;
     2051
     2052      if (label == 0) {
     2053        IdMap<GR, Edge> id_map(_graph);
     2054        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
     2055        std::sort(edges.begin(), edges.end(), id_less);
     2056      } else {
     2057        label->sort(edges);
     2058      }
     2059
     2060      //BLOCK
     2061      //Type
     2062      {
     2063        _writer_bits::DefaultBinaryConverter<int> conv;
     2064        conv.setValue(_blgf_bits::ARCS,_blgf_bits::BLOCK_SPEC_TYPE);
     2065        _writer_bits::writeDataBinary(*_os,conv);
     2066      }
     2067      //Caption
     2068      {
     2069        _writer_bits::DefaultBinaryConverter<std::string> conv(_edges_caption);
     2070        _writer_bits::writeDataBinary(*_os,conv);
     2071      }
     2072      //Size
     2073      {
     2074        _writer_bits::DefaultBinaryConverter<int> conv;
     2075        conv.setValue(static_cast<int>(edges.size()),_blgf_bits::SIZE_SPEC_TYPE);
     2076        _writer_bits::writeDataBinary(*_os,conv);
     2077      }
     2078
     2079      //FROM_TO
     2080      //name
     2081      _os->put(0);
     2082      //type
     2083      {
     2084        _blgf_bits::BlgfType type;
     2085        if (node_labels == 0 || static_cast<int> (edges.size()) == 0)
     2086          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     2087        else{
     2088
     2089          _writer_bits::BinaryTokenBase const* conv = node_labels->getBinary(_graph.u(edges[0]));
     2090          type = conv->getType();
     2091        }
     2092       
     2093        if (type == _blgf_bits::DATA)
     2094          throw FormatError("Labels must be a fundemental type");
     2095
     2096        _writer_bits::DefaultBinaryConverter<int> conv;
     2097        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
     2098        _writer_bits::writeDataBinary(*_os,conv);
     2099      }
     2100      //data
     2101      for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
     2102        Edge e = edges[i];
     2103
     2104        if (node_labels != 0) {
     2105          _writer_bits::BinaryTokenBase const * u = node_labels->getBinary(_graph.u(e));
     2106          _writer_bits::writeDataBinary(*_os,*u);
     2107          _writer_bits::BinaryTokenBase const * v = node_labels->getBinary(_graph.v(e));
     2108          _writer_bits::writeDataBinary(*_os,*v);
     2109
     2110        } else {
     2111          int u = _graph.id(_graph.u(e));
     2112          int v = _graph.id(_graph.v(e));
     2113          _writer_bits::DefaultBinaryConverter<int> conv;
     2114
     2115          conv.setValue(u);
     2116          _writer_bits::writeDataBinary(*_os,conv);
     2117
     2118          conv.setValue(v);
     2119          _writer_bits::writeDataBinary(*_os,conv);
     2120        }
     2121      }
     2122
     2123      if (label != 0) {
     2124        //Label
     2125        //name
     2126        {
     2127          _writer_bits::DefaultBinaryConverter<std::string> conv("label");
     2128          _writer_bits::writeDataBinary(*_os,conv);
     2129        }
     2130        //type
     2131        {
     2132          _blgf_bits::BlgfType type;
     2133          if (static_cast<int> (edges.size()) == 0)
     2134            type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
     2135          else {
     2136            _writer_bits::BinaryTokenBase const * conv = label->getBinary(edges[0]);
     2137            type = conv->getType();
     2138          }
     2139
     2140          if (type == _blgf_bits::DATA)
     2141            throw FormatError("Labels must be a fundemental type");
     2142
     2143          _writer_bits::DefaultBinaryConverter<int> conv;
     2144          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     2145          _writer_bits::writeDataBinary(*_os, conv);
     2146        }
     2147        //data
     2148        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
     2149          Edge e = edges[i];
     2150            _writer_bits::BinaryTokenBase const *conv = label->getBinary(e) ;
     2151            _writer_bits::writeDataBinary(*_os, *conv);
     2152
     2153             std::string value = label->get(e);
     2154            _edge_index.insert(std::make_pair(e, value));
     2155          }
     2156      }else{
     2157        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
     2158          Edge e = edges[i];
     2159          std::ostringstream os;
     2160          int id = _graph.id(e);
     2161          os << id;
     2162
     2163          _edge_index.insert(std::make_pair(e, os.str()));
     2164        }
     2165      }
     2166
     2167
     2168      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2169        it != _edge_maps.end(); ++it) {
     2170        if (it->first == "label")
     2171          continue;
     2172
     2173        //Name
     2174        {
     2175          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
     2176          _writer_bits::writeDataBinary(*_os,conv);
     2177        }
     2178        //type
     2179        {
     2180          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
     2181          if (edges.size()>0)
     2182            type = it->second->getBinary(edges[0])->getType();
     2183
     2184          _writer_bits::DefaultBinaryConverter<int> conv;
     2185          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
     2186          _writer_bits::writeDataBinary(*_os, conv);
     2187        }
     2188        //Data
     2189        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
     2190          Edge n = edges[i];
     2191          //
     2192          _writer_bits::BinaryTokenBase const *c = it->second->getBinary(n);
     2193          if (c->getType() == _blgf_bits::DATA){
     2194            _writer_bits::DefaultBinaryConverter<int> conv;
     2195            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
     2196            _writer_bits::writeDataBinary(*_os,conv);
     2197          }
     2198          _writer_bits::writeDataBinary(*_os,*c);
     2199        }
     2200      }
     2201
     2202      _os->put(0);
     2203    }
     2204
    14172205    void writeEdges() {
    14182206      _writer_bits::MapStorageBase<Edge>* label = 0;
    14192207      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     
    15052293      }
    15062294    }
    15072295
     2296    void writeAttributesBinary() {
     2297      if (_attributes.size() == 0)
     2298        return;
     2299      //BLOCK
     2300      //Type
     2301      {
     2302        _writer_bits::DefaultBinaryConverter<int> conv;
     2303        conv.setValue(_blgf_bits::ATTRIBUTES,_blgf_bits::BLOCK_SPEC_TYPE);
     2304        _writer_bits::writeDataBinary(*_os,conv);
     2305      }
     2306
     2307      for (typename Attributes::iterator it = _attributes.begin();
     2308           it != _attributes.end(); ++it) {
     2309
     2310        _writer_bits::DefaultBinaryConverter<std::string> cstr(it->first);
     2311        _writer_bits::writeDataBinary(*_os,cstr);
     2312
     2313        cstr.setValue(it->second->get());
     2314        _writer_bits::writeDataBinary(*_os,cstr);
     2315      }
     2316
     2317      _os->put(0);
     2318    }
     2319
    15082320    void writeAttributes() {
    15092321      if (_attributes.empty()) return;
    15102322      *_os << "@attributes";
     
    15282340    /// \brief Start the batch processing
    15292341    ///
    15302342    /// This function starts the batch processing.
    1531     void run() {
     2343    void run(bool binary = false, bool append = false) {
     2344
     2345      if (binary && !append){
     2346        _os->write(_blgf_bits::BLGF_VERSION,6);
     2347      }
     2348
     2349
    15322350      if (!_skip_nodes) {
    1533         writeNodes();
     2351        if (!binary)
     2352          writeNodes();
     2353        else
     2354          writeNodesBinary();
    15342355      } else {
    15352356        createNodeIndex();
    15362357      }
    15372358      if (!_skip_edges) {
    1538         writeEdges();
     2359        if (!binary)
     2360          writeEdges();
     2361        else
     2362          writeEdgesBinary();
    15392363      } else {
    15402364        createEdgeIndex();
    15412365      }
    1542       writeAttributes();
     2366      if (!binary)
     2367        writeAttributes();
     2368      else
     2369        writeAttributesBinary();
     2370
    15432371    }
    15442372
    15452373    /// \brief Give back the stream of the writer
     
    15592387  /// This function just returns a \ref GraphWriter class.
    15602388  ///
    15612389  /// With this function a graph can be write to a file or output
    1562   /// stream in \ref lgf-format "LGF" format with several maps and
     2390  /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and
    15632391  /// attributes. For example, with the following code a weighted
    15642392  /// matching problem can be written to the standard output, i.e. a
    15652393  /// graph with a \e weight map on the edges:
     
    18332661}
    18342662
    18352663#endif
     2664