| ... | ... |
@@ -2071,6 +2071,343 @@ |
| 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)