gravatar
deba@inf.elte.hu
deba@inf.elte.hu
LGF content reader class
0 1 0
default
1 file changed with 337 insertions and 0 deletions:
↑ Collapse diff ↑
Show white space 12 line context
... ...
@@ -2068,9 +2068,346 @@
2068 2068
  /// \relates GraphReader
2069 2069
  template <typename Graph>
2070 2070
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2071 2071
    GraphReader<Graph> tmp(fn, graph);
2072 2072
    return tmp;
2073 2073
  }
2074

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

	
2105
    std::istream* _is;
2106
    bool local_is;
2107

	
2108
    std::vector<std::string> _node_sections;
2109
    std::vector<std::string> _edge_sections;
2110
    std::vector<std::string> _attribute_sections;
2111
    std::vector<std::string> _extra_sections;
2112

	
2113
    std::vector<bool> _arc_sections;
2114

	
2115
    std::vector<std::vector<std::string> > _node_maps;
2116
    std::vector<std::vector<std::string> > _edge_maps;
2117

	
2118
    std::vector<std::vector<std::string> > _attributes;
2119

	
2120

	
2121
    int line_num;
2122
    std::istringstream line;
2123
    
2124
  public:
2125

	
2126
    /// \brief Constructor
2127
    ///
2128
    /// Construct an \e LGF content reader, which reads from the given
2129
    /// input stream.
2130
    LgfContent(std::istream& is) 
2131
      : _is(&is), local_is(false) {}
2132

	
2133
    /// \brief Constructor
2134
    ///
2135
    /// Construct an \e LGF content reader, which reads from the given
2136
    /// file.
2137
    LgfContent(const std::string& fn) 
2138
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2139

	
2140
    /// \brief Constructor
2141
    ///
2142
    /// Construct an \e LGF content reader, which reads from the given
2143
    /// file.
2144
    LgfContent(const char* fn)
2145
      : _is(new std::ifstream(fn)), local_is(true) {}
2146

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

	
2162
      _arc_sections.swap(other._arc_sections);
2163

	
2164
      _node_maps.swap(other._node_maps);
2165
      _edge_maps.swap(other._edge_maps);
2166
      _attributes.swap(other._attributes);
2167
    }
2168
    
2169
    /// \brief Destructor
2170
    ~LgfContent() {
2171
      if (local_is) delete _is;
2172
    }
2173

	
2174

	
2175
    /// \name Node sections
2176
    /// @{
2177

	
2178
    /// \brief Gives back the number of node sections in the file.
2179
    ///
2180
    /// Gives back the number of node sections in the file.
2181
    int nodeSectionNum() const {
2182
      return _node_sections.size();
2183
    }
2184

	
2185
    /// \brief Returns the section name at the given position. 
2186
    ///
2187
    /// Returns the section name at the given position. 
2188
    const std::string& nodeSection(int i) const {
2189
      return _node_sections[i];
2190
    }
2191

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

	
2199
    /// @}
2200

	
2201
    /// \name Arc sections 
2202
    /// @{
2203

	
2204
    /// \brief Gives back the number of arc sections in the file.
2205
    ///
2206
    /// Gives back the number of arc sections in the file.
2207
    /// \note It is synonim of \c edgeSectionNum().
2208
    int arcSectionNum() const {
2209
      return _edge_sections.size();
2210
    }
2211

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

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

	
2228
    /// \brief Returns true when the section type is \c "@arcs".
2229
    ///
2230
    /// Returns true when the section type is \c "@arcs", and not "@edges".
2231
    bool isArcSection(int i) const {
2232
      return _arc_sections[i];
2233
    }
2234

	
2235
    /// @}
2236

	
2237
    /// \name Edge sections   
2238
    /// @{
2239

	
2240
    /// \brief Gives back the number of edge sections in the file.
2241
    ///
2242
    /// Gives back the number of edge sections in the file.
2243
    int edgeSectionNum() const {
2244
      return _edge_sections.size();
2245
    }
2246

	
2247
    /// \brief Returns the section name at the given position. 
2248
    ///
2249
    /// Returns the section name at the given position. 
2250
    const std::string& edgeSection(int i) const {
2251
      return _edge_sections[i];
2252
    }
2253

	
2254
    /// \brief Gives back the edge maps for the given section.
2255
    ///
2256
    /// Gives back the edge maps for the given section.
2257
    const std::vector<std::string>& edgeMaps(int i) const {
2258
      return _edge_maps[i];
2259
    }
2260

	
2261
    /// \brief Returns true when the section type is \c "@edges".
2262
    ///
2263
    /// Returns true when the section type is \c "@edges", and not "@arcs".
2264
    bool isEdgeSection(int i) const {
2265
      return !_arc_sections[i];
2266
    }
2267

	
2268
    /// @}
2269

	
2270
    /// \name Attribute sections   
2271
    /// @{
2272

	
2273
    /// \brief Gives back the number of attribute sections in the file.
2274
    ///
2275
    /// Gives back the number of attribute sections in the file.
2276
    int attributeSectionNum() const {
2277
      return _attribute_sections.size();
2278
    }
2279

	
2280
    /// \brief Returns the section name at the given position. 
2281
    ///
2282
    /// Returns the section name at the given position. 
2283
    const std::string& attributeSection(int i) const {
2284
      return _attribute_sections[i];
2285
    }
2286

	
2287
    /// \brief Gives back the attributes for the given section.
2288
    ///
2289
    /// Gives back the attributes for the given section.
2290
    const std::vector<std::string>& attributes(int i) const {
2291
      return _attributes[i];
2292
    }
2293

	
2294
    /// @}
2295

	
2296
    /// \name Extra sections   
2297
    /// @{
2298

	
2299
    /// \brief Gives back the number of extra sections in the file.
2300
    ///
2301
    /// Gives back the number of extra sections in the file.
2302
    int extraSectionNum() const {
2303
      return _extra_sections.size();
2304
    }
2305

	
2306
    /// \brief Returns the extra section type at the given position. 
2307
    ///
2308
    /// Returns the section type at the given position. 
2309
    const std::string& extraSection(int i) const {
2310
      return _extra_sections[i];
2311
    }
2312

	
2313
    /// @}
2314

	
2315
  private:
2316

	
2317
    bool readLine() {
2318
      std::string str;
2319
      while(++line_num, std::getline(*_is, str)) {
2320
	line.clear(); line.str(str);
2321
	char c;
2322
	if (line >> std::ws >> c && c != '#') {
2323
	  line.putback(c);
2324
	  return true;
2325
	}
2326
      }
2327
      return false;
2328
    }
2329

	
2330
    bool readSuccess() {
2331
      return static_cast<bool>(*_is);
2332
    }
2333

	
2334
    void skipSection() {
2335
      char c;
2336
      while (readSuccess() && line >> c && c != '@') {
2337
	readLine();
2338
      }
2339
      line.putback(c);
2340
    }
2341

	
2342
    void readMaps(std::vector<std::string>& maps) {
2343
      if (!readLine()) 
2344
	throw DataFormatError("Cannot find map captions");
2345
      std::string map;
2346
      while (_reader_bits::readToken(line, map)) {
2347
	maps.push_back(map);
2348
      }
2349
    }
2350

	
2351
    void readAttributes(std::vector<std::string>& attrs) {
2352
      readLine();
2353
      char c;
2354
      while (readSuccess() && line >> c && c != '@') {
2355
	line.putback(c);
2356
	std::string attr;
2357
	_reader_bits::readToken(line, attr);
2358
	attrs.push_back(attr);
2359
	readLine();
2360
      }
2361
      line.putback(c);
2362
    }
2363

	
2364
  public:
2365

	
2366
    /// \name Execution of the content reader    
2367
    /// @{
2368

	
2369
    /// \brief Start the reading
2370
    ///
2371
    /// This function starts the reading
2372
    void run() {
2373

	
2374
      readLine();
2375
      skipSection();
2376

	
2377
      while (readSuccess()) {
2378

	
2379
	char c;
2380
	line >> c;
2381

	
2382
	std::string section, caption;
2383
	_reader_bits::readToken(line, section);
2384
	_reader_bits::readToken(line, caption);
2385

	
2386
	if (section == "nodes") {
2387
	  _node_sections.push_back(caption);
2388
	  _node_maps.push_back(std::vector<std::string>());
2389
	  readMaps(_node_maps.back());
2390
	  readLine(); skipSection();
2391
	} else if (section == "arcs" || section == "edges") {
2392
	  _edge_sections.push_back(caption);
2393
	  _arc_sections.push_back(section == "arcs");
2394
	  _edge_maps.push_back(std::vector<std::string>());
2395
	  readMaps(_edge_maps.back());
2396
	  readLine(); skipSection();
2397
	} else if (section == "attributes") {
2398
	  _attribute_sections.push_back(caption);
2399
	  _attributes.push_back(std::vector<std::string>());
2400
	  readAttributes(_attributes.back());
2401
	} else {
2402
	  _extra_sections.push_back(section);
2403
	  readLine(); skipSection();
2404
	}
2405
      }
2406
    }
2407

	
2408
    /// @}
2409
    
2410
  };
2074 2411
}
2075 2412

	
2076 2413
#endif
0 comments (0 inline)