Changes in / [172:c94a80f38d7f:174:2ec3c1bbc687] in lemon-main
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_reader.h
r172 r174 2068 2068 return tmp; 2069 2069 } 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 }; 2070 2407 } 2071 2408
Note: See TracChangeset
for help on using the changeset viewer.