gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Doc improvements in LgfContents
0 1 0
default
1 file changed with 14 insertions and 11 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -2005,391 +2005,394 @@
2005 2005
	    }
2006 2006
	  } else if (section == "attributes" && !attributes_done) {
2007 2007
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
2008 2008
	      readAttributes();
2009 2009
	      attributes_done = true;
2010 2010
	    }
2011 2011
	  } else {
2012 2012
	    if (extra_sections.find(section) != extra_sections.end()) {
2013 2013
	      std::ostringstream msg;
2014 2014
	      msg << "Multiple occurence of section " << section;
2015 2015
	      throw DataFormatError(msg.str().c_str());
2016 2016
	    }
2017 2017
	    Sections::iterator it = _sections.find(section);
2018 2018
	    if (it != _sections.end()) {
2019 2019
	      extra_sections.insert(section);
2020 2020
	      it->second->process(*_is, line_num);
2021 2021
	    }
2022 2022
	    readLine();
2023 2023
	    skipSection();
2024 2024
	  }
2025 2025
	} catch (DataFormatError& error) {
2026 2026
	  error.line(line_num);
2027 2027
	  throw;
2028 2028
	}	
2029 2029
      }
2030 2030

	
2031 2031
      if (!nodes_done) {
2032 2032
	throw DataFormatError("Section @nodes not found");
2033 2033
      }
2034 2034

	
2035 2035
      if (!edges_done) {
2036 2036
	throw DataFormatError("Section @edges not found");
2037 2037
      }
2038 2038

	
2039 2039
      if (!attributes_done && !_attributes.empty()) {
2040 2040
	throw DataFormatError("Section @attributes not found");
2041 2041
      }
2042 2042

	
2043 2043
    }
2044 2044

	
2045 2045
    /// @}
2046 2046
    
2047 2047
  };
2048 2048

	
2049 2049
  /// \relates GraphReader
2050 2050
  template <typename Graph>
2051 2051
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2052 2052
    GraphReader<Graph> tmp(is, graph);
2053 2053
    return tmp;
2054 2054
  }
2055 2055

	
2056 2056
  /// \relates GraphReader
2057 2057
  template <typename Graph>
2058 2058
  GraphReader<Graph> graphReader(const std::string& fn, 
2059 2059
				       Graph& graph) {
2060 2060
    GraphReader<Graph> tmp(fn, graph);
2061 2061
    return tmp;
2062 2062
  }
2063 2063

	
2064 2064
  /// \relates GraphReader
2065 2065
  template <typename Graph>
2066 2066
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2067 2067
    GraphReader<Graph> tmp(fn, graph);
2068 2068
    return tmp;
2069 2069
  }
2070 2070

	
2071 2071
  /// \ingroup lemon_io
2072 2072
  ///
2073 2073
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file 
2074 2074
  ///
2075 2075
  /// This class can be used to read the sections, the map names and
2076 2076
  /// the attributes from a file. Usually, the Lemon programs know
2077 2077
  /// that, which type of graph, which maps and which attributes
2078 2078
  /// should be read from a file, but in general tools (like glemon)
2079 2079
  /// the contents of an LGF file should be guessed somehow. This class
2080 2080
  /// reads the graph and stores the appropriate information for
2081 2081
  /// reading the graph.
2082 2082
  ///
2083 2083
  ///\code LgfContents contents("graph.lgf"); 
2084 2084
  /// contents.run();
2085 2085
  ///
2086 2086
  /// // does it contain any node section and arc section
2087 2087
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2088 2088
  ///   std::cerr << "Failure, cannot find graph" << std::endl;
2089 2089
  ///   return -1;
2090 2090
  /// }
2091 2091
  /// std::cout << "The name of the default node section : " 
2092 2092
  ///           << contents.nodeSection(0) << std::endl;
2093 2093
  /// std::cout << "The number of the arc maps : " 
2094 2094
  ///           << contents.arcMaps(0).size() << std::endl;
2095 2095
  /// std::cout << "The name of second arc map : " 
2096 2096
  ///           << contents.arcMaps(0)[1] << std::endl;
2097 2097
  ///\endcode
2098 2098
  class LgfContents {    
2099 2099
  private:
2100 2100

	
2101 2101
    std::istream* _is;
2102 2102
    bool local_is;
2103 2103

	
2104 2104
    std::vector<std::string> _node_sections;
2105 2105
    std::vector<std::string> _edge_sections;
2106 2106
    std::vector<std::string> _attribute_sections;
2107 2107
    std::vector<std::string> _extra_sections;
2108 2108

	
2109 2109
    std::vector<bool> _arc_sections;
2110 2110

	
2111 2111
    std::vector<std::vector<std::string> > _node_maps;
2112 2112
    std::vector<std::vector<std::string> > _edge_maps;
2113 2113

	
2114 2114
    std::vector<std::vector<std::string> > _attributes;
2115 2115

	
2116 2116

	
2117 2117
    int line_num;
2118 2118
    std::istringstream line;
2119 2119
    
2120 2120
  public:
2121 2121

	
2122 2122
    /// \brief Constructor
2123 2123
    ///
2124 2124
    /// Construct an \e LGF contents reader, which reads from the given
2125 2125
    /// input stream.
2126 2126
    LgfContents(std::istream& is) 
2127 2127
      : _is(&is), local_is(false) {}
2128 2128

	
2129 2129
    /// \brief Constructor
2130 2130
    ///
2131 2131
    /// Construct an \e LGF contents reader, which reads from the given
2132 2132
    /// file.
2133 2133
    LgfContents(const std::string& fn) 
2134 2134
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2135 2135

	
2136 2136
    /// \brief Constructor
2137 2137
    ///
2138 2138
    /// Construct an \e LGF contents reader, which reads from the given
2139 2139
    /// file.
2140 2140
    LgfContents(const char* fn)
2141 2141
      : _is(new std::ifstream(fn)), local_is(true) {}
2142 2142

	
2143 2143
    /// \brief Copy constructor
2144 2144
    ///
2145 2145
    /// The copy constructor transfers all data from the other reader,
2146 2146
    /// therefore the copied reader will not be usable more. 
2147 2147
    LgfContents(LgfContents& other)
2148 2148
      : _is(other._is), local_is(other.local_is) {
2149 2149
      
2150 2150
      other._is = 0;
2151 2151
      other.local_is = false;
2152 2152
      
2153 2153
      _node_sections.swap(other._node_sections);
2154 2154
      _edge_sections.swap(other._edge_sections);
2155 2155
      _attribute_sections.swap(other._attribute_sections);
2156 2156
      _extra_sections.swap(other._extra_sections);
2157 2157

	
2158 2158
      _arc_sections.swap(other._arc_sections);
2159 2159

	
2160 2160
      _node_maps.swap(other._node_maps);
2161 2161
      _edge_maps.swap(other._edge_maps);
2162 2162
      _attributes.swap(other._attributes);
2163 2163
    }
2164 2164
    
2165 2165
    /// \brief Destructor
2166 2166
    ~LgfContents() {
2167 2167
      if (local_is) delete _is;
2168 2168
    }
2169 2169

	
2170 2170

	
2171 2171
    /// \name Node sections
2172 2172
    /// @{
2173 2173

	
2174 2174
    /// \brief Gives back the number of node sections in the file.
2175 2175
    ///
2176 2176
    /// Gives back the number of node sections in the file.
2177 2177
    int nodeSectionNum() const {
2178 2178
      return _node_sections.size();
2179 2179
    }
2180 2180

	
2181 2181
    /// \brief Returns the section name at the given position. 
2182 2182
    ///
2183 2183
    /// Returns the section name at the given position. 
2184 2184
    const std::string& nodeSection(int i) const {
2185 2185
      return _node_sections[i];
2186 2186
    }
2187 2187

	
2188 2188
    /// \brief Gives back the node maps for the given section.
2189 2189
    ///
2190 2190
    /// Gives back the node maps for the given section.
2191 2191
    const std::vector<std::string>& nodeMaps(int i) const {
2192 2192
      return _node_maps[i];
2193 2193
    }
2194 2194

	
2195 2195
    /// @}
2196 2196

	
2197
    /// \name Arc sections 
2197
    /// \name Arc/Edge sections 
2198 2198
    /// @{
2199 2199

	
2200
    /// \brief Gives back the number of arc sections in the file.
2200
    /// \brief Gives back the number of arc/edge sections in the file.
2201 2201
    ///
2202
    /// Gives back the number of arc sections in the file.
2203
    /// \note It is synonim of \c edgeSectionNum().
2202
    /// Gives back the number of arc/edge sections in the file.
2203
    /// \note It is synonym of \c edgeSectionNum().
2204 2204
    int arcSectionNum() const {
2205 2205
      return _edge_sections.size();
2206 2206
    }
2207 2207

	
2208 2208
    /// \brief Returns the section name at the given position. 
2209 2209
    ///
2210 2210
    /// Returns the section name at the given position. 
2211
    /// \note It is synonim of \c edgeSection().
2211
    /// \note It is synonym of \c edgeSection().
2212 2212
    const std::string& arcSection(int i) const {
2213 2213
      return _edge_sections[i];
2214 2214
    }
2215 2215

	
2216
    /// \brief Gives back the arc maps for the given section.
2216
    /// \brief Gives back the arc/edge maps for the given section.
2217 2217
    ///
2218
    /// Gives back the arc maps for the given section.
2219
    /// \note It is synonim of \c edgeMaps().
2218
    /// Gives back the arc/edge maps for the given section.
2219
    /// \note It is synonym of \c edgeMaps().
2220 2220
    const std::vector<std::string>& arcMaps(int i) const {
2221 2221
      return _edge_maps[i];
2222 2222
    }
2223 2223

	
2224 2224
    /// @}
2225 2225

	
2226
    /// \name Edge sections   
2226
    /// \name Synonyms
2227 2227
    /// @{
2228 2228

	
2229
    /// \brief Gives back the number of edge sections in the file.
2229
    /// \brief Gives back the number of arc/edge sections in the file.
2230 2230
    ///
2231
    /// Gives back the number of edge sections in the file.
2231
    /// Gives back the number of arc/edge sections in the file.
2232
    /// \note It is synonym of \c arcSectionNum().
2232 2233
    int edgeSectionNum() const {
2233 2234
      return _edge_sections.size();
2234 2235
    }
2235 2236

	
2236 2237
    /// \brief Returns the section name at the given position. 
2237 2238
    ///
2238 2239
    /// Returns the section name at the given position. 
2240
    /// \note It is synonym of \c arcSection().
2239 2241
    const std::string& edgeSection(int i) const {
2240 2242
      return _edge_sections[i];
2241 2243
    }
2242 2244

	
2243 2245
    /// \brief Gives back the edge maps for the given section.
2244 2246
    ///
2245 2247
    /// Gives back the edge maps for the given section.
2248
    /// \note It is synonym of \c arcMaps().
2246 2249
    const std::vector<std::string>& edgeMaps(int i) const {
2247 2250
      return _edge_maps[i];
2248 2251
    }
2249 2252

	
2250 2253
    /// @}
2251 2254

	
2252 2255
    /// \name Attribute sections   
2253 2256
    /// @{
2254 2257

	
2255 2258
    /// \brief Gives back the number of attribute sections in the file.
2256 2259
    ///
2257 2260
    /// Gives back the number of attribute sections in the file.
2258 2261
    int attributeSectionNum() const {
2259 2262
      return _attribute_sections.size();
2260 2263
    }
2261 2264

	
2262 2265
    /// \brief Returns the section name at the given position. 
2263 2266
    ///
2264 2267
    /// Returns the section name at the given position. 
2265 2268
    const std::string& attributeSection(int i) const {
2266 2269
      return _attribute_sections[i];
2267 2270
    }
2268 2271

	
2269 2272
    /// \brief Gives back the attributes for the given section.
2270 2273
    ///
2271 2274
    /// Gives back the attributes for the given section.
2272 2275
    const std::vector<std::string>& attributes(int i) const {
2273 2276
      return _attributes[i];
2274 2277
    }
2275 2278

	
2276 2279
    /// @}
2277 2280

	
2278 2281
    /// \name Extra sections   
2279 2282
    /// @{
2280 2283

	
2281 2284
    /// \brief Gives back the number of extra sections in the file.
2282 2285
    ///
2283 2286
    /// Gives back the number of extra sections in the file.
2284 2287
    int extraSectionNum() const {
2285 2288
      return _extra_sections.size();
2286 2289
    }
2287 2290

	
2288 2291
    /// \brief Returns the extra section type at the given position. 
2289 2292
    ///
2290 2293
    /// Returns the section type at the given position. 
2291 2294
    const std::string& extraSection(int i) const {
2292 2295
      return _extra_sections[i];
2293 2296
    }
2294 2297

	
2295 2298
    /// @}
2296 2299

	
2297 2300
  private:
2298 2301

	
2299 2302
    bool readLine() {
2300 2303
      std::string str;
2301 2304
      while(++line_num, std::getline(*_is, str)) {
2302 2305
	line.clear(); line.str(str);
2303 2306
	char c;
2304 2307
	if (line >> std::ws >> c && c != '#') {
2305 2308
	  line.putback(c);
2306 2309
	  return true;
2307 2310
	}
2308 2311
      }
2309 2312
      return false;
2310 2313
    }
2311 2314

	
2312 2315
    bool readSuccess() {
2313 2316
      return static_cast<bool>(*_is);
2314 2317
    }
2315 2318

	
2316 2319
    void skipSection() {
2317 2320
      char c;
2318 2321
      while (readSuccess() && line >> c && c != '@') {
2319 2322
	readLine();
2320 2323
      }
2321 2324
      line.putback(c);
2322 2325
    }
2323 2326

	
2324 2327
    void readMaps(std::vector<std::string>& maps) {
2325 2328
      if (!readLine()) 
2326 2329
	throw DataFormatError("Cannot find map captions");
2327 2330
      std::string map;
2328 2331
      while (_reader_bits::readToken(line, map)) {
2329 2332
	maps.push_back(map);
2330 2333
      }
2331 2334
    }
2332 2335

	
2333 2336
    void readAttributes(std::vector<std::string>& attrs) {
2334 2337
      readLine();
2335 2338
      char c;
2336 2339
      while (readSuccess() && line >> c && c != '@') {
2337 2340
	line.putback(c);
2338 2341
	std::string attr;
2339 2342
	_reader_bits::readToken(line, attr);
2340 2343
	attrs.push_back(attr);
2341 2344
	readLine();
2342 2345
      }
2343 2346
      line.putback(c);
2344 2347
    }
2345 2348

	
2346 2349
  public:
2347 2350

	
2348 2351
    /// \name Execution of the contents reader    
2349 2352
    /// @{
2350 2353

	
2351 2354
    /// \brief Start the reading
2352 2355
    ///
2353 2356
    /// This function starts the reading
2354 2357
    void run() {
2355 2358

	
2356 2359
      readLine();
2357 2360
      skipSection();
2358 2361

	
2359 2362
      while (readSuccess()) {
2360 2363

	
2361 2364
	char c;
2362 2365
	line >> c;
2363 2366

	
2364 2367
	std::string section, caption;
2365 2368
	_reader_bits::readToken(line, section);
2366 2369
	_reader_bits::readToken(line, caption);
2367 2370

	
2368 2371
	if (section == "nodes") {
2369 2372
	  _node_sections.push_back(caption);
2370 2373
	  _node_maps.push_back(std::vector<std::string>());
2371 2374
	  readMaps(_node_maps.back());
2372 2375
	  readLine(); skipSection();
2373 2376
	} else if (section == "arcs" || section == "edges") {
2374 2377
	  _edge_sections.push_back(caption);
2375 2378
	  _arc_sections.push_back(section == "arcs");
2376 2379
	  _edge_maps.push_back(std::vector<std::string>());
2377 2380
	  readMaps(_edge_maps.back());
2378 2381
	  readLine(); skipSection();
2379 2382
	} else if (section == "attributes") {
2380 2383
	  _attribute_sections.push_back(caption);
2381 2384
	  _attributes.push_back(std::vector<std::string>());
2382 2385
	  readAttributes(_attributes.back());
2383 2386
	} else {
2384 2387
	  _extra_sections.push_back(section);
2385 2388
	  readLine(); skipSection();
2386 2389
	}
2387 2390
      }
2388 2391
    }
2389 2392

	
2390 2393
    /// @}
2391 2394
    
2392 2395
  };
2393 2396
}
2394 2397

	
2395 2398
#endif
0 comments (0 inline)