COIN-OR::LEMON - Graph Library

Changes in / [175:4eb8900a865c:176:47b69d4b0759] in lemon-main


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lgf_reader.h

    r165 r174  
    11401140      line_num = 0;     
    11411141      readLine();
     1142      skipSection();
    11421143
    11431144      while (readSuccess()) {
    1144         skipSection();
    11451145        try {
    11461146          char c;
     
    11791179              extra_sections.insert(section);
    11801180              it->second->process(*_is, line_num);
    1181               readLine();
    1182             } else {
    1183               readLine();
    1184               skipSection();
    11851181            }
     1182            readLine();
     1183            skipSection();
    11861184          }
    11871185        } catch (DataFormatError& error) {
     
    19821980      line_num = 0;     
    19831981      readLine();
     1982      skipSection();
    19841983
    19851984      while (readSuccess()) {
    1986         skipSection();
    19871985        try {
    19881986          char c;
     
    20212019              extra_sections.insert(section);
    20222020              it->second->process(*_is, line_num);
    2023               readLine();
    2024             } else {
    2025               readLine();
    2026               skipSection();
    20272021            }
     2022            readLine();
     2023            skipSection();
    20282024          }
    20292025        } catch (DataFormatError& error) {
     
    20722068    return tmp;
    20732069  }
     2070
     2071  /// \ingroup lemon_io
     2072  ///
     2073  /// \brief Reader for the content of the \ref lgf-format "LGF" file
     2074  ///
     2075  /// This class can be used to read the sections, the map names and
     2076  /// the attributes from a file. Usually, the Lemon programs know
     2077  /// that, which type of graph, which maps and which attributes
     2078  /// should be read from a file, but in general tools (like glemon)
     2079  /// the content of an LGF file should be guessed somehow. This class
     2080  /// reads the graph and stores the appropriate information for
     2081  /// reading the graph.
     2082  ///
     2083  ///\code LgfContent content("graph.lgf");
     2084  /// content.run();
     2085  ///
     2086  /// // does it contain any node section and arc section
     2087  /// if (content.nodeSectionNum() == 0 || content.arcSectionNum()) {
     2088  ///   std::cerr << "Failure, cannot find graph" << std::endl;
     2089  ///   return -1;
     2090  /// }
     2091  /// std::cout << "The name of the default node section : "
     2092  ///           << content.nodeSection(0) << std::endl;
     2093  /// std::cout << "The number of the arc maps : "
     2094  ///           << content.arcMaps(0).size() << std::endl;
     2095  /// std::cout << "The name of second arc map : "
     2096  ///           << content.arcMaps(0)[1] << std::endl;
     2097  ///\endcode
     2098  class LgfContent {   
     2099  private:
     2100
     2101    std::istream* _is;
     2102    bool local_is;
     2103
     2104    std::vector<std::string> _node_sections;
     2105    std::vector<std::string> _edge_sections;
     2106    std::vector<std::string> _attribute_sections;
     2107    std::vector<std::string> _extra_sections;
     2108
     2109    std::vector<bool> _arc_sections;
     2110
     2111    std::vector<std::vector<std::string> > _node_maps;
     2112    std::vector<std::vector<std::string> > _edge_maps;
     2113
     2114    std::vector<std::vector<std::string> > _attributes;
     2115
     2116
     2117    int line_num;
     2118    std::istringstream line;
     2119   
     2120  public:
     2121
     2122    /// \brief Constructor
     2123    ///
     2124    /// Construct an \e LGF content reader, which reads from the given
     2125    /// input stream.
     2126    LgfContent(std::istream& is)
     2127      : _is(&is), local_is(false) {}
     2128
     2129    /// \brief Constructor
     2130    ///
     2131    /// Construct an \e LGF content reader, which reads from the given
     2132    /// file.
     2133    LgfContent(const std::string& fn)
     2134      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
     2135
     2136    /// \brief Constructor
     2137    ///
     2138    /// Construct an \e LGF content reader, which reads from the given
     2139    /// file.
     2140    LgfContent(const char* fn)
     2141      : _is(new std::ifstream(fn)), local_is(true) {}
     2142
     2143    /// \brief Copy constructor
     2144    ///
     2145    /// The copy constructor transfers all data from the other reader,
     2146    /// therefore the copied reader will not be usable more.
     2147    LgfContent(LgfContent& other)
     2148      : _is(other._is), local_is(other.local_is) {
     2149     
     2150      other._is = 0;
     2151      other.local_is = false;
     2152     
     2153      _node_sections.swap(other._node_sections);
     2154      _edge_sections.swap(other._edge_sections);
     2155      _attribute_sections.swap(other._attribute_sections);
     2156      _extra_sections.swap(other._extra_sections);
     2157
     2158      _arc_sections.swap(other._arc_sections);
     2159
     2160      _node_maps.swap(other._node_maps);
     2161      _edge_maps.swap(other._edge_maps);
     2162      _attributes.swap(other._attributes);
     2163    }
     2164   
     2165    /// \brief Destructor
     2166    ~LgfContent() {
     2167      if (local_is) delete _is;
     2168    }
     2169
     2170
     2171    /// \name Node sections
     2172    /// @{
     2173
     2174    /// \brief Gives back the number of node sections in the file.
     2175    ///
     2176    /// Gives back the number of node sections in the file.
     2177    int nodeSectionNum() const {
     2178      return _node_sections.size();
     2179    }
     2180
     2181    /// \brief Returns the section name at the given position.
     2182    ///
     2183    /// Returns the section name at the given position.
     2184    const std::string& nodeSection(int i) const {
     2185      return _node_sections[i];
     2186    }
     2187
     2188    /// \brief Gives back the node maps for the given section.
     2189    ///
     2190    /// Gives back the node maps for the given section.
     2191    const std::vector<std::string>& nodeMaps(int i) const {
     2192      return _node_maps[i];
     2193    }
     2194
     2195    /// @}
     2196
     2197    /// \name Arc sections
     2198    /// @{
     2199
     2200    /// \brief Gives back the number of arc sections in the file.
     2201    ///
     2202    /// Gives back the number of arc sections in the file.
     2203    /// \note It is synonim of \c edgeSectionNum().
     2204    int arcSectionNum() const {
     2205      return _edge_sections.size();
     2206    }
     2207
     2208    /// \brief Returns the section name at the given position.
     2209    ///
     2210    /// Returns the section name at the given position.
     2211    /// \note It is synonim of \c edgeSection().
     2212    const std::string& arcSection(int i) const {
     2213      return _edge_sections[i];
     2214    }
     2215
     2216    /// \brief Gives back the arc maps for the given section.
     2217    ///
     2218    /// Gives back the arc maps for the given section.
     2219    /// \note It is synonim of \c edgeMaps().
     2220    const std::vector<std::string>& arcMaps(int i) const {
     2221      return _edge_maps[i];
     2222    }
     2223
     2224    /// \brief Returns true when the section type is \c "@arcs".
     2225    ///
     2226    /// Returns true when the section type is \c "@arcs", and not "@edges".
     2227    bool isArcSection(int i) const {
     2228      return _arc_sections[i];
     2229    }
     2230
     2231    /// @}
     2232
     2233    /// \name Edge sections   
     2234    /// @{
     2235
     2236    /// \brief Gives back the number of edge sections in the file.
     2237    ///
     2238    /// Gives back the number of edge sections in the file.
     2239    int edgeSectionNum() const {
     2240      return _edge_sections.size();
     2241    }
     2242
     2243    /// \brief Returns the section name at the given position.
     2244    ///
     2245    /// Returns the section name at the given position.
     2246    const std::string& edgeSection(int i) const {
     2247      return _edge_sections[i];
     2248    }
     2249
     2250    /// \brief Gives back the edge maps for the given section.
     2251    ///
     2252    /// Gives back the edge maps for the given section.
     2253    const std::vector<std::string>& edgeMaps(int i) const {
     2254      return _edge_maps[i];
     2255    }
     2256
     2257    /// \brief Returns true when the section type is \c "@edges".
     2258    ///
     2259    /// Returns true when the section type is \c "@edges", and not "@arcs".
     2260    bool isEdgeSection(int i) const {
     2261      return !_arc_sections[i];
     2262    }
     2263
     2264    /// @}
     2265
     2266    /// \name Attribute sections   
     2267    /// @{
     2268
     2269    /// \brief Gives back the number of attribute sections in the file.
     2270    ///
     2271    /// Gives back the number of attribute sections in the file.
     2272    int attributeSectionNum() const {
     2273      return _attribute_sections.size();
     2274    }
     2275
     2276    /// \brief Returns the section name at the given position.
     2277    ///
     2278    /// Returns the section name at the given position.
     2279    const std::string& attributeSection(int i) const {
     2280      return _attribute_sections[i];
     2281    }
     2282
     2283    /// \brief Gives back the attributes for the given section.
     2284    ///
     2285    /// Gives back the attributes for the given section.
     2286    const std::vector<std::string>& attributes(int i) const {
     2287      return _attributes[i];
     2288    }
     2289
     2290    /// @}
     2291
     2292    /// \name Extra sections   
     2293    /// @{
     2294
     2295    /// \brief Gives back the number of extra sections in the file.
     2296    ///
     2297    /// Gives back the number of extra sections in the file.
     2298    int extraSectionNum() const {
     2299      return _extra_sections.size();
     2300    }
     2301
     2302    /// \brief Returns the extra section type at the given position.
     2303    ///
     2304    /// Returns the section type at the given position.
     2305    const std::string& extraSection(int i) const {
     2306      return _extra_sections[i];
     2307    }
     2308
     2309    /// @}
     2310
     2311  private:
     2312
     2313    bool readLine() {
     2314      std::string str;
     2315      while(++line_num, std::getline(*_is, str)) {
     2316        line.clear(); line.str(str);
     2317        char c;
     2318        if (line >> std::ws >> c && c != '#') {
     2319          line.putback(c);
     2320          return true;
     2321        }
     2322      }
     2323      return false;
     2324    }
     2325
     2326    bool readSuccess() {
     2327      return static_cast<bool>(*_is);
     2328    }
     2329
     2330    void skipSection() {
     2331      char c;
     2332      while (readSuccess() && line >> c && c != '@') {
     2333        readLine();
     2334      }
     2335      line.putback(c);
     2336    }
     2337
     2338    void readMaps(std::vector<std::string>& maps) {
     2339      if (!readLine())
     2340        throw DataFormatError("Cannot find map captions");
     2341      std::string map;
     2342      while (_reader_bits::readToken(line, map)) {
     2343        maps.push_back(map);
     2344      }
     2345    }
     2346
     2347    void readAttributes(std::vector<std::string>& attrs) {
     2348      readLine();
     2349      char c;
     2350      while (readSuccess() && line >> c && c != '@') {
     2351        line.putback(c);
     2352        std::string attr;
     2353        _reader_bits::readToken(line, attr);
     2354        attrs.push_back(attr);
     2355        readLine();
     2356      }
     2357      line.putback(c);
     2358    }
     2359
     2360  public:
     2361
     2362    /// \name Execution of the content reader   
     2363    /// @{
     2364
     2365    /// \brief Start the reading
     2366    ///
     2367    /// This function starts the reading
     2368    void run() {
     2369
     2370      readLine();
     2371      skipSection();
     2372
     2373      while (readSuccess()) {
     2374
     2375        char c;
     2376        line >> c;
     2377
     2378        std::string section, caption;
     2379        _reader_bits::readToken(line, section);
     2380        _reader_bits::readToken(line, caption);
     2381
     2382        if (section == "nodes") {
     2383          _node_sections.push_back(caption);
     2384          _node_maps.push_back(std::vector<std::string>());
     2385          readMaps(_node_maps.back());
     2386          readLine(); skipSection();
     2387        } else if (section == "arcs" || section == "edges") {
     2388          _edge_sections.push_back(caption);
     2389          _arc_sections.push_back(section == "arcs");
     2390          _edge_maps.push_back(std::vector<std::string>());
     2391          readMaps(_edge_maps.back());
     2392          readLine(); skipSection();
     2393        } else if (section == "attributes") {
     2394          _attribute_sections.push_back(caption);
     2395          _attributes.push_back(std::vector<std::string>());
     2396          readAttributes(_attributes.back());
     2397        } else {
     2398          _extra_sections.push_back(section);
     2399          readLine(); skipSection();
     2400        }
     2401      }
     2402    }
     2403
     2404    /// @}
     2405   
     2406  };
    20742407}
    20752408
Note: See TracChangeset for help on using the changeset viewer.