lemon/lgf_reader.h
changeset 173 b026e9779b28
parent 165 b4c336c27a03
child 174 2ec3c1bbc687
equal deleted inserted replaced
7:2dbf9764175b 9:b043958089d3
  2069   template <typename Graph>
  2069   template <typename Graph>
  2070   GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
  2070   GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
  2071     GraphReader<Graph> tmp(fn, graph);
  2071     GraphReader<Graph> tmp(fn, graph);
  2072     return tmp;
  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 #endif
  2413 #endif