1.1 --- a/src/lemon/graph_reader.h Sat Apr 09 19:32:06 2005 +0000
1.2 +++ b/src/lemon/graph_reader.h Sat Apr 09 19:35:33 2005 +0000
1.3 @@ -34,16 +34,20 @@
1.4
1.5 namespace lemon {
1.6
1.7 + /// \addtogroup io_group
1.8 + /// @{
1.9
1.10 /// \brief Standard ReaderTraits for the GraphReader class.
1.11 ///
1.12 /// Standard ReaderTraits for the GraphReader class.
1.13 /// It defines standard reading method for all type of value.
1.14 + /// \author Balazs Dezso
1.15 struct DefaultReaderTraits {
1.16
1.17 - /// \brief Template class for reading an value.
1.18 + /// \brief Template class for reading an value.
1.19 ///
1.20 /// Template class for reading an value.
1.21 + /// \author Balazs Dezso
1.22 template <typename _Value>
1.23 struct Reader {
1.24 /// The value type.
1.25 @@ -57,6 +61,13 @@
1.26 }
1.27 };
1.28
1.29 + /// \brief Returns wheter this name is an ID map name.
1.30 + ///
1.31 + /// Returns wheter this name is an ID map name.
1.32 + static bool idMapName(const std::string& name) {
1.33 + return name == "id";
1.34 + }
1.35 +
1.36 /// The reader class for the not needed maps.
1.37 typedef Reader<std::string> DefaultReader;
1.38
1.39 @@ -66,6 +77,7 @@
1.40 ///
1.41 /// Reader class for quoted strings. It can process the escape
1.42 /// sequences in the string.
1.43 + /// \author Balazs Dezso
1.44 class QuotedStringReader {
1.45 public:
1.46 typedef std::string Value;
1.47 @@ -171,12 +183,69 @@
1.48
1.49 /// \brief The graph reader class.
1.50 ///
1.51 - /// \ingroup io_group
1.52 - /// The reader class for the graph input.
1.53 + ///
1.54 + /// The given file format may contain several maps and labeled nodes or
1.55 + /// edges.
1.56 + ///
1.57 + /// If you read a graph you need not read all the maps and items just those
1.58 + /// that you need. The interface of the \c GraphReader is very similar to
1.59 + /// the GraphWriter but the reading method does not depend on the order the
1.60 + /// given commands.
1.61 + ///
1.62 + /// The reader object suppose that each not readed value does not contain
1.63 + /// whitespaces, therefore it has some extra possibilities to control how
1.64 + /// it should skip the values when the string representation contains spaces.
1.65 + ///
1.66 + /// \code
1.67 + /// GraphReader<ListGraph> reader(std::cin, graph);
1.68 + /// \endcode
1.69 + ///
1.70 + /// The \c addNodeMap() function reads a map from the \c \@nodeset section.
1.71 + /// If there is a map that you do not want to read from the file and there is
1.72 + /// whitespace in the string represenation of the values then you should
1.73 + /// call the \c skipNodeMap() template member function with proper
1.74 + /// parameters.
1.75 + ///
1.76 + /// \code
1.77 + /// reader.addNodeMap("x-coord", xCoordMap);
1.78 + /// reader.addNodeMap("y-coord", yCoordMap);
1.79 + ///
1.80 + /// reader.addNodeMap<QuotedStringReader>("label", labelMap);
1.81 + /// reader.skipNodeMap<QuotedStringReader>("description");
1.82 + ///
1.83 + /// reader.addNodeMap("color", colorMap);
1.84 + /// \endcode
1.85 + ///
1.86 + /// With the \c addEdgeMap() member function you can give an edge map
1.87 + /// reading command similar to the NodeMaps.
1.88 + ///
1.89 + /// \code
1.90 + /// reader.addEdgeMap("weight", weightMap);
1.91 + /// reader.addEdgeMap("label", labelMap);
1.92 + /// \endcode
1.93 + ///
1.94 + /// With \c addNode() and \c addEdge() functions you can read labeled Nodes
1.95 + /// and Edges.
1.96 + ///
1.97 + /// \code
1.98 + /// reader.addNode("source", sourceNode);
1.99 + /// reader.addNode("target", targetNode);
1.100 + ///
1.101 + /// reader.addEdge("observed", edge);
1.102 + /// \endcode
1.103 + ///
1.104 + /// After you give all read commands you must call the \c run() member
1.105 + /// function, which execute all the commands.
1.106 + ///
1.107 + /// \code
1.108 + /// reader.run();
1.109 + /// \endcode
1.110 + ///
1.111 /// \see DefaultReaderTraits
1.112 /// \see QuotedStringReader
1.113 /// \see \ref GraphWriter
1.114 /// \see \ref graph-io-page
1.115 + /// \author Balazs Dezso
1.116 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
1.117 class GraphReader {
1.118 public:
1.119 @@ -200,7 +269,6 @@
1.120 ///
1.121 /// Destruct the graph reader.
1.122 ~GraphReader() {
1.123 -
1.124 for (typename NodeMapReaders::iterator it = node_map_readers.begin();
1.125 it != node_map_readers.end(); ++it) {
1.126 delete it->second;
1.127 @@ -364,7 +432,6 @@
1.128 std::string id;
1.129 std::istringstream ls(line);
1.130 while (ls >> id) {
1.131 - if (id[0] == '#') break;
1.132 typename NodeMapReaders::iterator it = node_map_readers.find(id);
1.133 if (it != node_map_readers.end()) {
1.134 index.push_back(it->second);
1.135 @@ -372,21 +439,24 @@
1.136 } else {
1.137 index.push_back(&nodeSkipper);
1.138 }
1.139 + if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
1.140 + nodeInverter.reset(index.back()->getInverter());
1.141 + index.back() = nodeInverter.get();
1.142 + }
1.143 }
1.144 }
1.145
1.146 - if (index.size() == 0) {
1.147 - throw DataFormatError("Cannot find node id map");
1.148 - }
1.149 +// if (index.size() == 0) {
1.150 +// throw DataFormatError("Cannot find node id map");
1.151 +// }
1.152
1.153 - nodeInverter =
1.154 - std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
1.155 +// nodeInverter =
1.156 +// std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
1.157 std::string line;
1.158 while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.159 Node node = graph.addNode();
1.160 std::istringstream ls(line);
1.161 - nodeInverter->read(ls, node);
1.162 - for (int i = 1; i < (int)index.size(); ++i) {
1.163 + for (int i = 0; i < (int)index.size(); ++i) {
1.164 index[i]->read(ls, node);
1.165 }
1.166 }
1.167 @@ -402,7 +472,6 @@
1.168 std::string id;
1.169 std::istringstream ls(line);
1.170 while (ls >> id) {
1.171 - if (id[0] == '#') break;
1.172 typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
1.173 if (it != edge_map_readers.end()) {
1.174 index.push_back(it->second);
1.175 @@ -410,23 +479,29 @@
1.176 } else {
1.177 index.push_back(&edgeSkipper);
1.178 }
1.179 + if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
1.180 + edgeInverter.reset(index.back()->getInverter());
1.181 + index.back() = edgeInverter.get();
1.182 + }
1.183 }
1.184 }
1.185 +
1.186 + if (nodeInverter.get() == 0) {
1.187 + throw DataFormatError("Cannot find node id map");
1.188 + }
1.189 +// if (index.size() == 0) {
1.190 +// throw DataFormatError("Cannot find edge id map");
1.191 +// }
1.192
1.193 - if (index.size() == 0) {
1.194 - throw DataFormatError("Cannot find edge id map");
1.195 - }
1.196 -
1.197 - edgeInverter =
1.198 - std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
1.199 +// edgeInverter =
1.200 +// std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
1.201 std::string line;
1.202 while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.203 std::istringstream ls(line);
1.204 Node source = nodeInverter->read(ls);
1.205 Node target = nodeInverter->read(ls);
1.206 Edge edge = graph.addEdge(source, target);
1.207 - edgeInverter->read(ls, edge);
1.208 - for (int i = 1; i < (int)index.size(); ++i) {
1.209 + for (int i = 0; i < (int)index.size(); ++i) {
1.210 index[i]->read(ls, edge);
1.211 }
1.212 }
1.213 @@ -436,6 +511,9 @@
1.214 std::string readNodes(int& line_num,
1.215 std::auto_ptr<InverterBase<Node> >& nodeInverter) {
1.216 std::string line;
1.217 + if (nodeInverter.get() == 0) {
1.218 + throw DataFormatError("Cannot find node id map");
1.219 + }
1.220 while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.221 std::istringstream ls(line);
1.222 std::string name;
1.223 @@ -451,6 +529,9 @@
1.224 std::string readEdges(int& line_num,
1.225 std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
1.226 std::string line;
1.227 + if (edgeInverter.get() == 0) {
1.228 + throw DataFormatError("Cannot find edge id map");
1.229 + }
1.230 while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
1.231 std::istringstream ls(line);
1.232 std::string name;
1.233 @@ -466,23 +547,32 @@
1.234 std::string readNotEmptyLine(std::istream& is, int& line_num) {
1.235 std::string line;
1.236 while (++line_num, getline(is, line)) {
1.237 - int vi = line.find_first_not_of(" \t");
1.238 - if (vi != (int)std::string::npos && line[vi] != '#') {
1.239 + int vi = line.find('#');
1.240 + if (vi != (int)::std::string::npos) {
1.241 + line = line.substr(0, vi);
1.242 + }
1.243 + vi = line.find_first_not_of(" \t");
1.244 + if (vi != (int)std::string::npos) {
1.245 + std::cerr << "Line: " << line.substr(vi) << std::endl;
1.246 return line.substr(vi);
1.247 }
1.248 }
1.249 throw DataFormatError("End of stream error");
1.250 }
1.251
1.252 - // Inverters store and give back the Item from the id,
1.253 - // and may put the ids into a map.
1.254 + template <typename _Item>
1.255 + class ReaderBase;
1.256
1.257 template <typename _Item>
1.258 - class InverterBase {
1.259 + class InverterBase : public ReaderBase<_Item> {
1.260 public:
1.261 typedef _Item Item;
1.262 virtual void read(std::istream&, const Item&) = 0;
1.263 virtual Item read(std::istream&) = 0;
1.264 +
1.265 + virtual InverterBase<_Item>* getInverter() {
1.266 + return this;
1.267 + }
1.268 };
1.269
1.270 template <typename _Item, typename _Map, typename _Reader>
1.271 @@ -651,7 +741,15 @@
1.272
1.273 };
1.274
1.275 - /// Ready to use reader function.
1.276 + /// \brief Read a graph from the input.
1.277 + ///
1.278 + /// Read a graph from the input.
1.279 + /// \param is The input stream.
1.280 + /// \param g The graph.
1.281 + /// \param capacity The capacity map.
1.282 + /// \param s The source node.
1.283 + /// \param t The target node.
1.284 + /// \param cost The cost map.
1.285 template<typename Graph, typename CapacityMap, typename CostMap>
1.286 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
1.287 typename Graph::Node &s, typename Graph::Node &t,
1.288 @@ -664,6 +762,14 @@
1.289 reader.run();
1.290 }
1.291
1.292 + /// \brief Read a graph from the input.
1.293 + ///
1.294 + /// Read a graph from the input.
1.295 + /// \param is The input stream.
1.296 + /// \param g The graph.
1.297 + /// \param capacity The capacity map.
1.298 + /// \param s The source node.
1.299 + /// \param t The target node.
1.300 template<typename Graph, typename CapacityMap>
1.301 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
1.302 typename Graph::Node &s, typename Graph::Node &t) {
1.303 @@ -674,6 +780,13 @@
1.304 reader.run();
1.305 }
1.306
1.307 + /// \brief Read a graph from the input.
1.308 + ///
1.309 + /// Read a graph from the input.
1.310 + /// \param is The input stream.
1.311 + /// \param g The graph.
1.312 + /// \param capacity The capacity map.
1.313 + /// \param s The source node.
1.314 template<typename Graph, typename CapacityMap>
1.315 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
1.316 typename Graph::Node &s) {
1.317 @@ -683,6 +796,12 @@
1.318 reader.run();
1.319 }
1.320
1.321 + /// \brief Read a graph from the input.
1.322 + ///
1.323 + /// Read a graph from the input.
1.324 + /// \param is The input stream.
1.325 + /// \param g The graph.
1.326 + /// \param capacity The capacity map.
1.327 template<typename Graph, typename CapacityMap>
1.328 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
1.329 GraphReader<Graph> reader(is, g);
1.330 @@ -690,12 +809,18 @@
1.331 reader.run();
1.332 }
1.333
1.334 + /// \brief Read a graph from the input.
1.335 + ///
1.336 + /// Read a graph from the input.
1.337 + /// \param is The input stream.
1.338 + /// \param g The graph.
1.339 template<typename Graph>
1.340 void readGraph(std::istream& is, Graph &g) {
1.341 GraphReader<Graph> reader(is, g);
1.342 reader.run();
1.343 }
1.344
1.345 + /// @}
1.346 }
1.347
1.348 #endif