Ticket #225: blgf.patch
File blgf.patch, 117.6 KB (added by , 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 19 namespace lemon { 20 /*! 21 22 23 24 \page blgf-format Binary LEMON Graph Format (BLGF) 25 26 The \e BLGF is a <em>binary</em> 27 file format for storing graphs and associated data like 28 node and edge maps. 29 30 Each BLGF file starts with a signature, which are the "BLGF" letters followed by the two digit 31 version number. 32 After that, the file consists of several blocks. 33 Each block is preceded by its type, which is a 2 byte unsigned integer value (UINT16). 34 Currently, there are three types of blocks: 35 36 - Nodes block 37 - Arcs block 38 - Attributes block 39 40 Note: There may be several Nodes and Arcs blocks but only one Attributes block. 41 42 \section Nodes Nodes block 43 44 This type of block describes a set of nodes and associated maps. 45 It consists of two parts, the header and the data terminated by a null byte. 46 The header contains the name of the block and 47 the number of nodes described (i.e. the item count in each map) stored as a 4 byte unsigned integer (UINT32). 48 The data part contains the maps stored one after the other. The ï¬rst map in the Nodes 49 block is a special one, called \c Label, which contains unique id (label) for each node. 50 When describing end points of an arc, these ids are used to refer to the target and 51 the source node. \c Label map has an empty name (i.e. only NULL byte) and it must 52 not be absent! The order of nodes in each map must be the same (e.g. the i. item 53 in each map describes the node labeled by the i. item in the \c Label map)! 54 55 56 \section Arcs Arcs block 57 58 This type of block is very similar to the Nodes block. It again starts with a 59 header containing the name of the block and the number of items described (i.e. the 60 number of arcs or edges). The diï¬erence between these two types of blocks is the following: the 61 \c Label map is optional here and the ï¬rst map in this block must be the \c From-To map, 62 which contains node pairs describing the source and the destination for each arc. 63 The \c From-To map has also an empty name. If there is a \c Label map in Arcs block, 64 it must be on the second place right after the \c From-To map. 65 66 As in the Nodes block, the order of the arcs in the maps must be the same! 67 68 \section Attributes Attributes block 69 70 As it was mentioned before, only one Attributes block can take place in the 71 BLGF ï¬le. This block contains a null-terminated sequence of key-value pairs. The 72 Attributes block contains no header, since the name is not necessary, and the type 73 of the values is ï¬xed (STRING). 74 75 76 \section Limitations Limitations 77 78 Compared to LGF, the implementation of BLGF has some limitations: 79 - Using real types with their default value converters, the BLGF becomes portable 80 only on machines with the same memory endianness (i.e. big-endian or little- 81 endian). 82 - Long double type is not supported yet. 83 - The values of the label maps must be fundamental types (integer, real or 84 string). 85 86 */ 87 } 88 89 // LocalWords: whitespace whitespaces -
doc/groups.dox
diff -r a93f1a27d831 -r 454f0c2a380c doc/groups.dox
a b 659 659 postscript (EPS) format. 660 660 */ 661 661 662 662 663 /** 663 @defgroup lemon_io LEMON Graph Format 664 @defgroup lemon_io LEMON Graph Formats 664 665 @ingroup io_group 665 \brief Reading and writing LEMON Graph Format .666 \brief Reading and writing LEMON Graph Format and its binary version. 666 667 667 668 This 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". 669 670 */ 670 671 671 672 /** -
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;"> 6 Ravindra K. Ahuja, Thomas L. Magnanti, and James B. Orlin. 7 <em>Network Flows: Theory, Algorithms, and Applications</em>. 8 Prentice-Hall, Inc., 9 February 1993. 10 </div> 11 12 \section boost [Boost] 13 <div style="margin-top: -4ex; margin-left: 8em;"> 14 Boost 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;"> 20 Ursula Bünnagel, Bernhard Korte, and Jens Vygen. 21 Efficient implementation of the Goldberg-Tarjan minimum-cost flow algorithm. 22 <em>Optimization Methods and Software</em>, 23 10:157-174, 24 1998. 25 </div> 26 27 \section cmake [CMake] 28 <div style="margin-top: -4ex; margin-left: 8em;"> 29 CMake -- 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;"> 35 COIN-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;"> 41 ILOG 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;"> 47 Cbc -- 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;"> 53 Clp -- 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;"> 59 Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. 60 <em>Introduction to Algorithms</em>. 61 The MIT Press, 62 2nd edition, 63 2001. 64 </div> 65 66 \section dantzig63linearprog [Dan63] 67 <div style="margin-top: -4ex; margin-left: 8em;"> 68 George B. Dantzig. 69 <em>Linear Programming and Extensions</em>. 70 Princeton University Press, 71 1963. 72 </div> 73 74 \section dasdan98minmeancycle [DG98] 75 <div style="margin-top: -4ex; margin-left: 8em;"> 76 Ali Dasdan and Rajesh K. Gupta. 77 Faster maximum and minimum mean cycle alogrithms for system performance analysis. 78 <em>IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems</em>, 79 17(10):889-899, 80 1998. 81 </div> 82 83 \section dinic70algorithm [Din70] 84 <div style="margin-top: -4ex; margin-left: 8em;"> 85 E. A. Dinic. 86 Algorithm for solution of a problem of maximum flow in a network with power estimation. 87 <em>Soviet Math. Doklady</em>, 88 11:1277-1280, 89 1970. 90 </div> 91 92 \section doxygen [Doxygen] 93 <div style="margin-top: -4ex; margin-left: 8em;"> 94 Doxygen -- 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;"> 100 EGRES -- Egervá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;"> 106 Jack Edmonds and Richard M. Karp. 107 Theoretical improvements in algorithmic efficiency for network flow problems. 108 <em>Journal of the ACM</em>, 109 19(2):248-264, 110 1972. 111 </div> 112 113 \section glpk [GLPK] 114 <div style="margin-top: -4ex; margin-left: 8em;"> 115 GLPK -- 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;"> 121 Andrew V. Goldberg. 122 An efficient implementation of a scaling minimum-cost flow algorithm. 123 <em>Journal of Algorithms</em>, 124 22(1):1-29, 125 1997. 126 </div> 127 128 \section goldberg08partial [Gol08] 129 <div style="margin-top: -4ex; margin-left: 8em;"> 130 Andrew V. Goldberg. 131 The partial augment-relabel algorithm for the maximum flow problem. 132 <em>16th Annual European Symposium on Algorithms</em>, 133 pages 466-477, 134 2008. 135 </div> 136 137 \section goldberg88newapproach [GT88] 138 <div style="margin-top: -4ex; margin-left: 8em;"> 139 Andrew V. Goldberg and Robert E. Tarjan. 140 A new approach to the maximum flow problem. 141 <em>Journal of the ACM</em>, 142 35(4):921-940, 143 1988. 144 </div> 145 146 \section goldberg89cyclecanceling [GT89] 147 <div style="margin-top: -4ex; margin-left: 8em;"> 148 Andrew V. Goldberg and Robert E. Tarjan. 149 Finding minimum-cost circulations by canceling negative cycles. 150 <em>Journal of the ACM</em>, 151 36(4):873-886, 152 1989. 153 </div> 154 155 \section goldberg90approximation [GT90] 156 <div style="margin-top: -4ex; margin-left: 8em;"> 157 Andrew V. Goldberg and Robert E. Tarjan. 158 Finding minimum-cost circulations by successive approximation. 159 <em>Mathematics of Operations Research</em>, 160 15(3):430-466, 161 1990. 162 </div> 163 164 \section karp78characterization [Kar78] 165 <div style="margin-top: -4ex; margin-left: 8em;"> 166 Richard M. Karp. 167 A characterization of the minimum cycle mean in a digraph. 168 <em>Discrete Math.</em>, 169 23:309-311, 170 1978. 171 </div> 172 173 \section kellyoneill91netsimplex [KO91] 174 <div style="margin-top: -4ex; margin-left: 8em;"> 175 Damian J. Kelly and Garrett M. O'Neill. 176 The minimum cost flow problem and the network simplex method. 177 Master's thesis, 178 University College, 179 Dublin, Ireland, 180 September 1991. 181 </div> 182 183 \section klein67primal [Kle67] 184 <div style="margin-top: -4ex; margin-left: 8em;"> 185 Morton Klein. 186 A primal method for minimal cost flows with applications to the assignment and transportation problems. 187 <em>Management Science</em>, 188 14:205-220, 189 1967. 190 </div> 191 192 \section leda [LEDA] 193 <div style="margin-top: -4ex; margin-left: 8em;"> 194 LEDA -- 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;"> 200 LEMON -- Library for Efficient Modeling and Optimization in Networks. 201 <a href="http://lemon.cs.elte.hu/">http://lemon.cs.elte.hu/</a>, 202 2009. 203 </div> 204 205 \section ledabook [MN99] 206 <div style="margin-top: -4ex; margin-left: 8em;"> 207 Kurt Mehlhorn and Stefan Näher. 208 <em>LEDA: A platform for combinatorial and geometric computing</em>. 209 Cambridge University Press, 210 New York, NY, USA, 211 1999. 212 </div> 213 214 \section schrijver03combinatorial [Sch03] 215 <div style="margin-top: -4ex; margin-left: 8em;"> 216 Alexander Schrijver. 217 <em>Combinatorial Optimization: Polyhedra and Efficiency</em>. 218 Springer-Verlag, 219 2003. 220 </div> 221 222 \section bglbook [SLL02] 223 <div style="margin-top: -4ex; margin-left: 8em;"> 224 Jeremy G. Siek, Lee-Quan Lee, and Andrew Lumsdaine. 225 <em>The Boost Graph Library: User Guide and Reference Manual</em>. 226 Addison-Wesley, 227 2002. 228 </div> 229 230 \section sleator83dynamic [ST83] 231 <div style="margin-top: -4ex; margin-left: 8em;"> 232 Daniel D. Sleator and Robert E. Tarjan. 233 A data structure for dynamic trees. 234 <em>Journal of Computer and System Sciences</em>, 235 26(3):362-391, 236 1983. 237 </div> 238 239 \section soplex [SoPlex] 240 <div style="margin-top: -4ex; margin-left: 8em;"> 241 SoPlex -- 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;"> 247 Bjarne Stroustrup. 248 <em>The C++ Programming Language</em>. 249 Addison-Wesley Professional, 250 3rd edition, 251 February 2000. 252 </div> 253 254 */ -
lemon/Makefile.am
diff -r a93f1a27d831 -r 454f0c2a380c lemon/Makefile.am
a b 95 95 lemon/karp.h \ 96 96 lemon/kruskal.h \ 97 97 lemon/hao_orlin.h \ 98 lemon/blgf.h \ 98 99 lemon/lgf_reader.h \ 99 100 lemon/lgf_writer.h \ 100 101 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 34 namespace 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 18 18 19 19 ///\ingroup lemon_io 20 20 ///\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. 22 23 23 24 24 25 #ifndef LEMON_LGF_READER_H 25 26 #define LEMON_LGF_READER_H 26 27 28 #include <string> 29 27 30 #include <iostream> 28 31 #include <fstream> 29 32 #include <sstream> … … 33 36 34 37 #include <lemon/core.h> 35 38 39 #include <lemon/blgf.h> 36 40 #include <lemon/lgf_writer.h> 37 41 38 42 #include <lemon/concept_check.h> 39 43 #include <lemon/concepts/maps.h> 40 44 45 46 //#include <limits> 47 41 48 namespace lemon { 42 49 43 50 namespace _reader_bits { 44 51 45 52 template <typename Value> … … 76 83 virtual ~MapStorageBase() {} 77 84 78 85 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; 79 87 80 88 }; 81 89 82 90 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> > 84 93 class MapStorage : public MapStorageBase<_Item> { 85 94 public: 86 95 typedef _Map Map; 87 96 typedef _Converter Converter; 97 typedef _BinaryConverter BinaryConverter; 88 98 typedef _Item Item; 89 99 90 100 private: 91 101 Map& _map; 92 102 Converter _converter; 103 BinaryConverter _binaryConverter; 93 104 94 105 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) {} 97 109 virtual ~MapStorage() {} 98 110 99 111 virtual void set(const Item& item ,const std::string& value) { 100 112 _map.set(item, _converter(value)); 101 113 } 114 115 virtual void setBinary(const Item& item ,const char* data, const _blgf_bits::BlgfType blgfType) { 116 _map.set(item, _binaryConverter(blgfType,data)); 117 } 102 118 }; 103 119 104 120 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> > 106 123 class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> { 107 124 public: 108 125 typedef _Map Map; 109 126 typedef _Converter Converter; 127 typedef _BinaryConverter BinaryConverter; 110 128 typedef _GR GR; 111 129 typedef typename GR::Edge Item; 112 130 static const bool dir = _dir; … … 115 133 const GR& _graph; 116 134 Map& _map; 117 135 Converter _converter; 136 BinaryConverter _binaryConverter; 118 137 119 138 public: 120 139 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) {} 123 143 virtual ~GraphArcMapStorage() {} 124 144 125 145 virtual void set(const Item& item ,const std::string& value) { 126 146 _map.set(_graph.direct(item, dir), _converter(value)); 127 147 } 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 } 128 152 }; 129 153 130 154 class ValueStorageBase { … … 147 171 148 172 public: 149 173 ValueStorage(Value& value, const Converter& converter = Converter()) 150 : _value(value), _converter(converter) {} 174 : _value(value), _converter(converter) 175 {} 151 176 152 177 virtual void set(const std::string& value) { 153 178 _value = _converter(value); … … 285 310 } 286 311 } 287 312 313 314 315 288 316 inline std::istream& readToken(std::istream& is, std::string& str) { 289 317 std::ostringstream os; 290 318 … … 399 427 400 428 /// \ingroup lemon_io 401 429 /// 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. 403 432 /// 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. 405 436 /// 406 437 /// The reading method does a batch processing. The user creates a 407 438 /// reader object, then various reading rules can be added to the 408 439 /// reader, and eventually the reading is executed with the \c run() 409 440 /// member function. A map reading rule can be added to the reader 410 441 /// with the \c nodeMap() or \c arcMap() members. An optional 411 /// converter parameter can also be added as a standard functor412 /// converting from \c std::string to the value type of the map. If it413 /// is set, it will determine how the tokens in the file should be414 /// converted to the value type of the map. If the functor is not set,415 /// the n a default conversion will be used. One map can be read into416 /// multiple map objects at the same time. The \c attribute(), \c417 /// node() and \c arc() functions are used to add attribute reading418 /// 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. 419 450 /// 420 451 ///\code 421 452 /// DigraphReader<DGR>(digraph, std::cin). … … 427 458 /// run(); 428 459 ///\endcode 429 460 /// 430 /// By default, the reader uses the first section in the file of the431 /// proper type. If a section has an optional name, then it can be461 /// 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 432 463 /// selected for reading by giving an optional name parameter to the 433 464 /// \c nodes(), \c arcs() or \c attributes() functions. 434 465 /// … … 437 468 /// graph) during the reading, but instead the label map of the items 438 469 /// are given as a parameter of these functions. An 439 470 /// application of these functions is multipass reading, which is 440 /// important if two \c \@arcs sections must be read from the471 /// important if two \c \@arcs sections/blocks must be read from the 441 472 /// file. In this case the first phase would read the node set and one 442 473 /// of the arc sets, while the second phase would read the second arc 443 474 /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet). … … 609 640 610 641 /// \brief Node map reading rule 611 642 /// 612 /// Add a node map reading rule with specialized converter to the643 /// Add a node map reading rule with specialized text converter to the 613 644 /// reader. 614 645 template <typename Map, typename Converter> 615 646 DigraphReader& nodeMap(const std::string& caption, Map& map, … … 621 652 return *this; 622 653 } 623 654 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 624 672 /// \brief Arc map reading rule 625 673 /// 626 674 /// Add an arc map reading rule to the reader. … … 635 683 636 684 /// \brief Arc map reading rule 637 685 /// 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 639 702 /// reader. 640 703 template <typename Map, typename Converter> 641 704 DigraphReader& arcMap(const std::string& caption, Map& map, … … 851 914 } 852 915 } 853 916 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 854 1059 void readNodes() { 855 1060 856 1061 std::vector<int> map_index(_node_maps.size()); … … 944 1149 } 945 1150 } 946 1151 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 947 1272 void readArcs() { 948 1273 949 1274 std::vector<int> map_index(_arc_maps.size()); … … 1065 1390 } 1066 1391 } 1067 1392 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 1068 1434 void readAttributes() { 1069 1435 1070 1436 std::set<std::string> read_attr; … … 1113 1479 } 1114 1480 } 1115 1481 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() { 1126 1557 1127 1558 bool nodes_done = _skip_nodes; 1128 1559 bool arcs_done = _skip_arcs; … … 1174 1605 throw FormatError("Section @nodes not found"); 1175 1606 } 1176 1607 1177 if (!arcs_done) { 1608 if (!arcs_done) { 1178 1609 throw FormatError("Section @arcs not found"); 1179 1610 } 1180 1611 … … 1183 1614 } 1184 1615 1185 1616 } 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 } 1186 1642 1187 1643 /// @} 1188 1644 … … 1195 1651 /// This function just returns a \ref DigraphReader class. 1196 1652 /// 1197 1653 /// 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 1200 1657 /// digraph, i.e. a digraph with a \e capacity map on the arcs and 1201 1658 /// \e source and \e target nodes. This digraph can be read with the 1202 1659 /// following code: … … 1247 1704 return tmp; 1248 1705 } 1249 1706 1250 template <typename GR> 1707 template <typename GR> 1251 1708 class GraphReader; 1252 1709 1253 1710 template <typename TGR> … … 1259 1716 1260 1717 /// \ingroup lemon_io 1261 1718 /// 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 1263 1721 /// 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. 1265 1725 /// 1266 1726 /// It can be used almost the same way as \c DigraphReader. 1267 1727 /// The only difference is that this class can handle edges and … … 1432 1892 1433 1893 /// \brief Node map reading rule 1434 1894 /// 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 /// 1435 1910 /// Add a node map reading rule with specialized converter to the 1436 1911 /// reader. 1437 1912 template <typename Map, typename Converter> … … 1456 1931 return *this; 1457 1932 } 1458 1933 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 } 1459 1948 /// \brief Edge map reading rule 1460 1949 /// 1461 1950 /// Add an edge map reading rule with specialized converter to the … … 1487 1976 1488 1977 /// \brief Arc map reading rule 1489 1978 /// 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 /// 1490 1999 /// Add an arc map reading rule with specialized converter to the 1491 2000 /// reader. 1492 2001 template <typename Map, typename Converter> … … 1515 2024 return *this; 1516 2025 } 1517 2026 2027 1518 2028 /// \brief Attribute reading rule 1519 2029 /// 1520 2030 /// Add an attribute reading rule with specialized converter to the … … 1721 2231 } 1722 2232 } 1723 2233 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 1724 2377 void readNodes() { 1725 2378 1726 2379 std::vector<int> map_index(_node_maps.size()); … … 1814 2467 } 1815 2468 } 1816 2469 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 1817 2591 void readEdges() { 1818 2592 1819 2593 std::vector<int> map_index(_edge_maps.size()); … … 1935 2709 } 1936 2710 } 1937 2711 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 1938 2753 void readAttributes() { 1939 2754 1940 2755 std::set<std::string> read_attr; … … 1983 2798 } 1984 2799 } 1985 2800 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() { 1998 2802 bool nodes_done = _skip_nodes; 1999 2803 bool edges_done = _skip_edges; 2000 2804 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 2002 2881 line_num = 0; 2003 2882 readLine(); 2004 2883 skipSection(); … … 2052 2931 if (!attributes_done && !_attributes.empty()) { 2053 2932 throw FormatError("Section @attributes not found"); 2054 2933 } 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 2055 2963 2056 2964 } 2057 2965 … … 2066 2974 /// This function just returns a \ref GraphReader class. 2067 2975 /// 2068 2976 /// With this function a graph can be read from an 2069 /// \ref lgf-format "LGF" file or input stream with several maps and2977 /// \ref lgf-format "LGF" or an \ref blgf-format "BLGF" file or input stream with several maps and 2070 2978 /// attributes. For example, there is weighted matching problem on a 2071 2979 /// graph, i.e. a graph with a \e weight map on the edges. This 2072 2980 /// graph can be read with the following code: -
lemon/lgf_writer.h
diff -r a93f1a27d831 -r 454f0c2a380c lemon/lgf_writer.h
a b 39 39 #include <lemon/concept_check.h> 40 40 #include <lemon/concepts/maps.h> 41 41 42 #include <lemon/blgf.h> 43 42 44 namespace lemon { 43 45 44 namespace _writer_bits { 46 namespace _writer_bits { 45 47 46 48 template <typename Value> 47 49 struct DefaultConverter { … … 105 107 virtual ~MapStorageBase() {} 106 108 107 109 virtual std::string get(const Item& item) = 0; 110 111 virtual BinaryTokenBase const* getBinary(const Item& item) = 0; 112 108 113 virtual void sort(std::vector<Item>&) = 0; 109 114 }; 110 115 116 111 117 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> > 113 120 class MapStorage : public MapStorageBase<_Item> { 114 121 public: 115 122 typedef _Map Map; 116 123 typedef _Converter Converter; 124 typedef _BinaryConverter BinaryConverter; 117 125 typedef _Item Item; 118 126 119 127 private: 120 128 const Map& _map; 121 129 Converter _converter; 130 BinaryConverter _binaryConverter; 122 131 123 132 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) {} 126 136 virtual ~MapStorage() {} 127 137 128 138 virtual std::string get(const Item& item) { 129 139 return _converter(_map[item]); 130 140 } 141 142 virtual BinaryTokenBase* getBinary(const Item& item) { 143 _binaryConverter.setValue(_map[item]); 144 return &_binaryConverter; 145 //return _converter(_map[item]); 146 } 147 131 148 virtual void sort(std::vector<Item>& items) { 132 149 MapLess<Map> less(_map); 133 150 std::sort(items.begin(), items.end(), less); 134 151 } 135 152 }; 136 153 154 137 155 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> > 139 158 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { 140 159 public: 141 160 typedef _Map Map; 142 161 typedef _Converter Converter; 162 typedef _BinaryConverter BinaryConverter; 143 163 typedef _Graph Graph; 144 164 typedef typename Graph::Edge Item; 145 165 static const bool dir = _dir; … … 148 168 const Graph& _graph; 149 169 const Map& _map; 150 170 Converter _converter; 171 BinaryConverter _binaryConverter; 151 172 152 173 public: 153 174 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) {} 156 178 virtual ~GraphArcMapStorage() {} 157 179 158 180 virtual std::string get(const Item& item) { 159 181 return _converter(_map[_graph.direct(item, dir)]); 160 182 } 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 161 190 virtual void sort(std::vector<Item>& items) { 162 191 GraphArcMapLess<Graph, dir, Map> less(_graph, _map); 163 192 std::sort(items.begin(), items.end(), less); … … 172 201 virtual std::string get() = 0; 173 202 }; 174 203 204 175 205 template <typename _Value, typename _Converter = DefaultConverter<_Value> > 176 206 class ValueStorage : public ValueStorageBase { 177 207 public: … … 184 214 185 215 public: 186 216 ValueStorage(const Value& value, const Converter& converter = Converter()) 187 : _value(value), _converter(converter) {} 217 : _value(value), _converter(converter) 218 {} 188 219 189 220 virtual std::string get() { 190 221 return _converter(_value); 191 222 } 223 192 224 }; 193 225 194 226 template <typename Value> … … 206 238 } 207 239 return it->second; 208 240 } 241 242 209 243 }; 210 244 211 245 template <typename Graph> … … 362 396 363 397 /// \ingroup lemon_io 364 398 /// 365 /// \brief \ref lgf-format "LGF" writer for directed graphs399 /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for directed graphs 366 400 /// 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. 368 402 /// 369 403 /// The writing method does a batch processing. The user creates a 370 404 /// 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 373 410 /// with the \c nodeMap() or \c arcMap() members. An optional 374 411 /// converter parameter can also be added as a standard functor 375 412 /// converting from the value type of the map to \c std::string. If it … … 392 429 /// 393 430 /// 394 431 /// By default, the writer does not write additional captions to the 395 /// sections , but they can be give as an optional parameterof432 /// sections/blocks, but they can be given as an optional parameters of 396 433 /// the \c nodes(), \c arcs() or \c 397 434 /// attributes() functions. 398 435 /// 399 436 /// The \c skipNodes() and \c skipArcs() functions forbid the 400 /// writing of the sections . If two arc sections should be written437 /// writing of the sections/blocks. If two arc sections/blocks should be written 401 438 /// to the output, it can be done in two passes, the first pass 402 /// writes the node section and the first arc section, then the403 /// second pass skips the node section and writes just the arc404 /// section to the stream. The output stream can be retrieved with439 /// 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 405 442 /// 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. 407 445 template <typename DGR> 408 446 class DigraphWriter { 409 447 public: … … 565 603 return *this; 566 604 } 567 605 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 568 621 /// \brief Arc map writing rule 569 622 /// 570 623 /// Add an arc map writing rule to the writer. … … 591 644 return *this; 592 645 } 593 646 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 594 662 /// \brief Attribute writing rule 595 663 /// 596 664 /// Add an attribute writing rule to the writer. … … 615 683 return *this; 616 684 } 617 685 686 618 687 /// \brief Node writing rule 619 688 /// 620 689 /// Add a node writing rule to the writer. 621 690 DigraphWriter& node(const std::string& caption, const Node& node) { 622 691 typedef _writer_bits::MapLookUpConverter<Node> Converter; 692 623 693 Converter converter(_node_index); 694 624 695 _writer_bits::ValueStorageBase* storage = 625 696 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 626 697 _attributes.push_back(std::make_pair(caption, storage)); … … 691 762 692 763 private: 693 764 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 694 892 void writeNodes() { 695 893 _writer_bits::MapStorageBase<Node>* label = 0; 696 894 for (typename NodeMaps::iterator it = _node_maps.begin(); … … 775 973 } 776 974 } 777 975 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 778 1158 void writeArcs() { 779 1159 _writer_bits::MapStorageBase<Arc>* label = 0; 780 1160 for (typename ArcMaps::iterator it = _arc_maps.begin(); … … 866 1246 } 867 1247 } 868 1248 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 869 1275 void writeAttributes() { 870 1276 if (_attributes.empty()) return; 871 1277 *_os << "@attributes"; … … 889 1295 /// \brief Start the batch processing 890 1296 /// 891 1297 /// 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 893 1305 if (!_skip_nodes) { 894 writeNodes(); 1306 if (!binary) 1307 writeNodes(); 1308 else 1309 writeNodesBinary(); 895 1310 } else { 896 1311 createNodeIndex(); 897 1312 } 898 1313 if (!_skip_arcs) { 899 writeArcs(); 1314 if (!binary) 1315 writeArcs(); 1316 else 1317 writeArcsBinary(); 900 1318 } else { 901 1319 createArcIndex(); 902 1320 } 903 writeAttributes(); 1321 if (!binary) 1322 writeAttributes(); 1323 else 1324 writeAttributesBinary(); 1325 1326 //if (binary) 1327 // _os->put(0); 904 1328 } 905 1329 906 1330 /// \brief Give back the stream of the writer … … 920 1344 /// This function just returns a \ref DigraphWriter class. 921 1345 /// 922 1346 /// With this function a digraph can be write to a file or output 923 /// stream in \ref lgf-format "LGF" format with several maps and1347 /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and 924 1348 /// attributes. For example, with the following code a network flow 925 1349 /// problem can be written to the standard output, i.e. a digraph 926 1350 /// with a \e capacity map on the arcs and \e source and \e target … … 986 1410 987 1411 /// \ingroup lemon_io 988 1412 /// 989 /// \brief \ref lgf-format "LGF" writer fordirected graphs1413 /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for undirected graphs 990 1414 /// 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. 992 1416 /// 993 1417 /// It can be used almost the same way as \c DigraphWriter. 994 1418 /// The only difference is that this class can handle edges and … … 997 1421 /// The arc maps are written into the file as two columns, the 998 1422 /// caption of the columns are the name of the map prefixed with \c 999 1423 /// '+' and \c '-'. The arcs are written into the \c \@attributes 1000 /// section as a \c '+' or a \c '-' prefix (depends on the direction1424 /// section/block as a \c '+' or a \c '-' prefix (depends on the direction 1001 1425 /// of the arc) and the label of corresponding edge. 1002 1426 template <typename GR> 1003 1427 class GraphWriter { … … 1144 1568 return *this; 1145 1569 } 1146 1570 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 1147 1587 /// \brief Node map writing rule 1148 1588 /// 1149 1589 /// Add a node map writing rule with specialized converter to the … … 1172 1612 1173 1613 /// \brief Edge map writing rule 1174 1614 /// 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 /// 1175 1630 /// Add an edge map writing rule with specialized converter to the 1176 1631 /// writer. 1177 1632 template <typename Map, typename Converter> … … 1201 1656 1202 1657 /// \brief Arc map writing rule 1203 1658 /// 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 /// 1204 1682 /// Add an arc map writing rule with specialized converter to the 1205 1683 /// writer. 1206 1684 template <typename Map, typename Converter> … … 1218 1696 return *this; 1219 1697 } 1220 1698 1699 1700 1701 1221 1702 /// \brief Attribute writing rule 1222 1703 /// 1223 1704 /// Add an attribute writing rule to the writer. … … 1330 1811 1331 1812 private: 1332 1813 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 1333 1940 void writeNodes() { 1334 1941 _writer_bits::MapStorageBase<Node>* label = 0; 1335 1942 for (typename NodeMaps::iterator it = _node_maps.begin(); … … 1414 2021 } 1415 2022 } 1416 2023 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 1417 2205 void writeEdges() { 1418 2206 _writer_bits::MapStorageBase<Edge>* label = 0; 1419 2207 for (typename EdgeMaps::iterator it = _edge_maps.begin(); … … 1505 2293 } 1506 2294 } 1507 2295 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 1508 2320 void writeAttributes() { 1509 2321 if (_attributes.empty()) return; 1510 2322 *_os << "@attributes"; … … 1528 2340 /// \brief Start the batch processing 1529 2341 /// 1530 2342 /// 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 1532 2350 if (!_skip_nodes) { 1533 writeNodes(); 2351 if (!binary) 2352 writeNodes(); 2353 else 2354 writeNodesBinary(); 1534 2355 } else { 1535 2356 createNodeIndex(); 1536 2357 } 1537 2358 if (!_skip_edges) { 1538 writeEdges(); 2359 if (!binary) 2360 writeEdges(); 2361 else 2362 writeEdgesBinary(); 1539 2363 } else { 1540 2364 createEdgeIndex(); 1541 2365 } 1542 writeAttributes(); 2366 if (!binary) 2367 writeAttributes(); 2368 else 2369 writeAttributesBinary(); 2370 1543 2371 } 1544 2372 1545 2373 /// \brief Give back the stream of the writer … … 1559 2387 /// This function just returns a \ref GraphWriter class. 1560 2388 /// 1561 2389 /// With this function a graph can be write to a file or output 1562 /// stream in \ref lgf-format "LGF" format with several maps and2390 /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and 1563 2391 /// attributes. For example, with the following code a weighted 1564 2392 /// matching problem can be written to the standard output, i.e. a 1565 2393 /// graph with a \e weight map on the edges: … … 1833 2661 } 1834 2662 1835 2663 #endif 2664