COIN-OR::LEMON - Graph Library

Ticket #35: b026e9779b28.patch

File b026e9779b28.patch, 9.8 KB (added by Balazs Dezso, 16 years ago)
  • lemon/lgf_reader.h

    # HG changeset patch
    # User Balazs Dezso <deba@inf.elte.hu>
    # Date 1213633391 -7200
    # Node ID b026e9779b282cd092e9b45e3bb9cf0671135fc5
    # Parent  02f4d5d9bfd743e5737320a9f40fa964332bf953
    LGF content reader class
    
    diff -r 02f4d5d9bfd7 -r b026e9779b28 lemon/lgf_reader.h
    a b  
    20712071    GraphReader<Graph> tmp(fn, graph);
    20722072    return tmp;
    20732073  }
     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  };
    20742411}
    20752412
    20762413#endif