28 |
28 |
29 /// \todo fix exceptions |
29 /// \todo fix exceptions |
30 |
30 |
31 |
31 |
32 namespace lemon { |
32 namespace lemon { |
|
33 |
|
34 // Exceptions |
|
35 |
|
36 class IOException { |
|
37 public: |
|
38 virtual string what() const = 0; |
|
39 }; |
|
40 |
|
41 class DataFormatException : public IOException { |
|
42 std::string message; |
|
43 public: |
|
44 DataFormatException(const std::string& _message) |
|
45 : message(_message) {} |
|
46 std::string what() const { |
|
47 return "DataFormatException: " + message; |
|
48 } |
|
49 }; |
|
50 |
|
51 class StreamException : public IOException { |
|
52 public: |
|
53 virtual int line() = 0; |
|
54 private: |
|
55 IOException* exception; |
|
56 int line_num; |
|
57 }; |
|
58 |
|
59 |
|
60 // Readers and ReaderTraits |
33 |
61 |
34 struct DefaultReaderTraits { |
62 struct DefaultReaderTraits { |
35 |
63 |
36 template <typename _Value> |
64 template <typename _Value> |
37 struct Reader { |
65 struct Reader { |
38 typedef _Value Value; |
66 typedef _Value Value; |
39 void read(std::istream& is, Value& value) { |
67 void read(std::istream& is, Value& value) { |
40 is >> value; |
68 if (!(is >> value)) |
41 } |
69 throw DataFormatException("Default Reader format exception"); |
42 }; |
70 } |
43 |
71 }; |
44 template <typename _Value> |
72 |
45 struct Skipper { |
73 typedef Reader<std::string> DefaultReader; |
46 typedef _Value Value; |
74 |
47 void read(std::istream& is) { |
|
48 Value tmp; |
|
49 is >> tmp; |
|
50 } |
|
51 }; |
|
52 |
|
53 struct DefaultSkipper { |
|
54 void read(std::istream& is) { |
|
55 std::string tmp; |
|
56 is >> tmp; |
|
57 } |
|
58 }; |
|
59 }; |
75 }; |
60 |
76 |
61 class IOException { |
77 class QuotedStringReader { |
62 virtual string message() = 0; |
78 public: |
|
79 typedef std::string Value; |
|
80 |
|
81 QuotedStringReader(bool _escaped = true) : escaped(_escaped) {} |
|
82 |
|
83 void read(std::istream& is, std::string& value) { |
|
84 char c; |
|
85 value.clear(); |
|
86 is >> ws; |
|
87 if (!is.get(c) || c != '\"') throw DataFormatException("Quoted string format exception"); |
|
88 while (is.get(c) && c != '\"') { |
|
89 if (escaped && c == '\\') { |
|
90 value += readEscape(is); |
|
91 } else { |
|
92 value += c; |
|
93 } |
|
94 } |
|
95 if (!is) throw DataFormatException("Quoted string format exception"); |
|
96 } |
|
97 |
|
98 private: |
|
99 |
|
100 static char readEscape(std::istream& is) { |
|
101 char c; |
|
102 switch (is.get(c), c) { |
|
103 case '\\': |
|
104 return '\\'; |
|
105 case '\"': |
|
106 return '\"'; |
|
107 case '\'': |
|
108 return '\''; |
|
109 case '\?': |
|
110 return '\?'; |
|
111 case 'a': |
|
112 return '\a'; |
|
113 case 'b': |
|
114 return '\b'; |
|
115 case 'f': |
|
116 return '\f'; |
|
117 case 'n': |
|
118 return '\n'; |
|
119 case 'r': |
|
120 return '\r'; |
|
121 case 't': |
|
122 return '\t'; |
|
123 case 'v': |
|
124 return '\v'; |
|
125 case 'x': |
|
126 { |
|
127 int code; |
|
128 if (!is.get(c) || !isHex(c)) throw DataFormatException("Escape format exception"); |
|
129 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); |
|
130 else code = code * 16 + valueHex(c); |
|
131 return code; |
|
132 } |
|
133 default: |
|
134 { |
|
135 int code; |
|
136 if (!isOct(c)) throw DataFormatException("Escape format exception"); |
|
137 else if (code = valueOct(c), !is.get(c) || !isOct(c)) is.putback(c); |
|
138 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) is.putback(c); |
|
139 else code = code * 8 + valueOct(c); |
|
140 return code; |
|
141 } |
|
142 } |
|
143 } |
|
144 |
|
145 static bool isOct(char c) { |
|
146 return '0' <= c && c <='7'; |
|
147 } |
|
148 |
|
149 static int valueOct(char c) { |
|
150 return c - '0'; |
|
151 } |
|
152 |
|
153 static bool isHex(char c) { |
|
154 return ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); |
|
155 } |
|
156 |
|
157 static int valueHex(char c) { |
|
158 if ('0' <= c && c <= '9') return c - '0'; |
|
159 if ('a' <= c && c <= 'z') return c - 'a' + 10; |
|
160 return c - 'A' + 10; |
|
161 } |
|
162 |
|
163 bool escaped; |
63 }; |
164 }; |
64 |
165 |
65 class FileReaderException { |
166 |
66 virtual int getLine() = 0; |
167 |
67 }; |
168 |
68 |
169 |
69 |
170 // Graph reader |
70 |
171 |
71 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
172 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> |
72 class GraphReader { |
173 class GraphReader { |
73 |
174 |
74 public: |
175 public: |
76 typedef _Graph Graph; |
177 typedef _Graph Graph; |
77 typedef typename Graph::Node Node; |
178 typedef typename Graph::Node Node; |
78 typedef typename Graph::Edge Edge; |
179 typedef typename Graph::Edge Edge; |
79 |
180 |
80 typedef _ReaderTraits ReaderTraits; |
181 typedef _ReaderTraits ReaderTraits; |
81 |
182 typedef typename ReaderTraits::DefaultReader DefaultReader; |
82 |
183 |
83 GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {} |
184 GraphReader(istream& _is, Graph& _graph, const DefaultReader& _reader = DefaultReader()) |
|
185 : is(_is), graph(_graph), nodeSkipper(_reader), edgeSkipper(_reader) {} |
|
186 |
|
187 |
|
188 ~GraphReader() { |
|
189 |
|
190 for (typename NodeReaders::iterator it = node_readers.begin(); it != node_readers.end(); ++it) { |
|
191 delete it->second; |
|
192 } |
|
193 |
|
194 for (typename EdgeReaders::iterator it = edge_readers.begin(); it != edge_readers.end(); ++it) { |
|
195 delete it->second; |
|
196 } |
|
197 |
|
198 } |
84 |
199 |
85 template <typename Map> |
200 template <typename Map> |
86 GraphReader& readNodeMap(std::string name, Map& map, |
201 GraphReader& readNodeMap(std::string name, Map& map) { |
87 const typename ReaderTraits::template Reader<typename Map::Value>& reader = |
202 return readNodeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
88 typename ReaderTraits::template Reader<typename Map::Value>()) { |
203 } |
89 return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader); |
204 |
90 } |
205 template <typename Reader, typename Map> |
91 |
|
92 template <typename Map, typename Reader> |
|
93 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
206 GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
|
207 if (node_readers.find(name) != node_readers.end()) { |
|
208 Exception e; |
|
209 e << "Multiple read rule for node map: " << name; |
|
210 throw e; |
|
211 } |
94 node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
212 node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader))); |
95 return *this; |
213 return *this; |
96 } |
214 } |
97 |
215 |
|
216 template <typename Reader> |
|
217 GraphReader& skipNodeMap(std::string name, const Reader& reader = Reader()) { |
|
218 if (node_readers.find(name) != node_readers.end()) { |
|
219 Exception e; |
|
220 e << "Multiple read rule for node map: " << name; |
|
221 throw e; |
|
222 } |
|
223 node_readers.insert(make_pair(name, new SkipReader<Node, Reader>(reader))); |
|
224 return *this; |
|
225 } |
|
226 |
98 template <typename Map> |
227 template <typename Map> |
99 GraphReader& readEdgeMap(std::string name, Map& map, |
228 GraphReader& readEdgeMap(std::string name, Map& map) { |
100 const typename ReaderTraits::template Reader<typename Map::Value>& reader = |
229 return readEdgeMap<typename ReaderTraits::template Reader<typename Map::Value>, Map>(name, map); |
101 typename ReaderTraits::template Reader<typename Map::Value>()) { |
230 } |
102 return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader); |
231 |
103 } |
232 |
104 |
233 template <typename Reader, typename Map> |
105 template <typename Map, typename Reader> |
|
106 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
234 GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) { |
|
235 if (edge_readers.find(name) != edge_readers.end()) { |
|
236 Exception e; |
|
237 e << "Multiple read rule for edge map: " << name; |
|
238 throw e; |
|
239 } |
107 edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
240 edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader))); |
108 return *this; |
241 return *this; |
109 } |
242 } |
110 |
243 |
|
244 template <typename Reader> |
|
245 GraphReader& skipEdgeMap(std::string name, const Reader& reader = Reader()) { |
|
246 if (edge_readers.find(name) != edge_readers.end()) { |
|
247 Exception e; |
|
248 e << "Multiple read rule for edge map: " << name; |
|
249 throw e; |
|
250 } |
|
251 edge_readers.insert(make_pair(name, new SkipReader<Edge, Reader>(reader))); |
|
252 return *this; |
|
253 } |
|
254 |
111 void read() { |
255 void read() { |
112 int line_num = 0; |
256 int line_num = 0; |
113 readNodeSet(line_num); |
257 InverterBase<Node>* nodeInverter = 0; |
114 readEdgeSet(line_num); |
258 InverterBase<Edge>* edgeInverter = 0; |
115 { |
259 // \todo delete the inverters |
116 std::string line = readNotEmptyLine(is, line_num); |
260 // try { |
117 } |
261 { |
|
262 std::string line = readNotEmptyLine(is, line_num); |
|
263 } |
|
264 readNodeSet(line_num, nodeInverter); |
|
265 readEdgeSet(line_num, edgeInverter, nodeInverter); |
|
266 // } catch (...){ |
|
267 if (nodeInverter != 0) delete nodeInverter; |
|
268 if (edgeInverter != 0) delete edgeInverter; |
|
269 // } |
118 } |
270 } |
119 |
271 |
120 private: |
272 private: |
121 |
273 |
122 void readNodeSet(int& line_num) { |
274 template <typename Item> class InverterBase; |
|
275 // template <typename Item> class InverterBase; |
|
276 |
|
277 void readNodeSet(int& line_num, InverterBase<Node>* & nodeInverter) { |
123 int n = 0; |
278 int n = 0; |
124 { |
279 std::vector<ReaderBase<Node>*> index; |
125 std::string line = readNotEmptyLine(is, line_num); |
|
126 } |
|
127 std::vector<MapReaderBase<Node>*> index; |
|
128 { |
280 { |
129 std::string line = readNotEmptyLine(is, line_num); |
281 std::string line = readNotEmptyLine(is, line_num); |
130 std::string id; |
282 std::string id; |
131 std::istringstream ls(line); |
283 std::istringstream ls(line); |
132 while (ls >> id) { |
284 while (ls >> id) { |
133 typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id); |
285 if (id[0] == '#') break; |
|
286 typename NodeReaders::iterator it = node_readers.find(id); |
134 if (it != node_readers.end()) { |
287 if (it != node_readers.end()) { |
135 index.push_back(it->second); |
288 index.push_back(it->second); |
136 } else { |
289 } else { |
137 index.push_back(0); |
290 index.push_back(&nodeSkipper); |
138 } |
291 } |
139 ++n; |
292 ++n; |
140 } |
293 } |
141 } |
294 } |
|
295 |
|
296 nodeInverter = index[0]->getInverter(); |
142 std::string line; |
297 std::string line; |
143 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
298 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
144 Node node = graph.addNode(); |
299 Node node = graph.addNode(); |
145 std::istringstream ls(line); |
300 std::istringstream ls(line); |
146 for (int i = 0; i < n; ++i) { |
301 nodeInverter->read(ls, node); |
147 if (index[i] != 0) { |
302 for (int i = 1; i < n; ++i) { |
148 index[i]->read(ls, node); |
303 index[i]->read(ls, node); |
|
304 } |
|
305 } |
|
306 } |
|
307 |
|
308 void readEdgeSet(int& line_num, InverterBase<Edge>* & edgeInverter, InverterBase<Node>* & nodeInverter) { |
|
309 int n = 0; |
|
310 std::vector<ReaderBase<Edge>*> index; |
|
311 { |
|
312 std::string line = readNotEmptyLine(is, line_num); |
|
313 std::string id; |
|
314 std::istringstream ls(line); |
|
315 while (ls >> id) { |
|
316 if (id[0] == '#') break; |
|
317 typename EdgeReaders::iterator it = edge_readers.find(id); |
|
318 if (it != edge_readers.end()) { |
|
319 index.push_back(it->second); |
149 } else { |
320 } else { |
150 default_skipper.read(ls); |
321 index.push_back(&edgeSkipper); |
151 } |
322 } |
152 } |
323 ++n; |
153 } |
324 } |
154 } |
325 } |
155 |
326 edgeInverter = index[0]->getInverter(); |
156 void readEdgeSet(int& line_num) { |
327 std::string line; |
157 |
328 while (line = readNotEmptyLine(is, line_num), line[0] != '@') { |
|
329 std::istringstream ls(line); |
|
330 Node source = nodeInverter->read(ls); |
|
331 Node target = nodeInverter->read(ls); |
|
332 Edge edge = graph.addEdge(source, target); |
|
333 edgeInverter->read(ls, edge); |
|
334 for (int i = 1; i < n; ++i) { |
|
335 index[i]->read(ls, edge); |
|
336 } |
|
337 } |
158 } |
338 } |
159 |
339 |
160 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
340 std::string readNotEmptyLine(std::istream& is, int& line_num) { |
161 std::string line; |
341 std::string line; |
162 while (++line_num, getline(is, line)) { |
342 while (++line_num, getline(is, line)) { |
166 } |
346 } |
167 } |
347 } |
168 throw Exception(); |
348 throw Exception(); |
169 } |
349 } |
170 |
350 |
171 istream& is; |
351 template <typename _Item> |
172 Graph& graph; |
352 class InverterBase { |
173 |
353 public: |
174 typename ReaderTraits::DefaultSkipper default_skipper; |
354 typedef _Item Item; |
|
355 virtual void read(istream&, const Item&) = 0; |
|
356 virtual Item read(istream&) = 0; |
|
357 }; |
|
358 |
|
359 template <typename _Item, typename _Map, typename _Reader> |
|
360 class MapReaderInverter : public InverterBase<_Item> { |
|
361 public: |
|
362 typedef _Item Item; |
|
363 typedef _Reader Reader; |
|
364 typedef typename Reader::Value Value; |
|
365 typedef _Map Map; |
|
366 typedef std::map<Value, Item> Inverse; |
|
367 |
|
368 Map& map; |
|
369 Reader reader; |
|
370 Inverse inverse; |
|
371 |
|
372 MapReaderInverter(Map& _map, const Reader& _reader) |
|
373 : map(_map), reader(_reader) {} |
|
374 |
|
375 virtual void read(istream& is, const Item& item) { |
|
376 Value value; |
|
377 reader.read(is, value); |
|
378 map.set(item, value); |
|
379 typename Inverse::iterator it = inverse.find(value); |
|
380 if (it == inverse.end()) { |
|
381 inverse.insert(make_pair(value, item)); |
|
382 } else { |
|
383 throw DataFormatException("Multiple ID occurence"); |
|
384 } |
|
385 } |
|
386 |
|
387 virtual Item read(istream& is) { |
|
388 Value value; |
|
389 reader.read(is, value); |
|
390 typename Inverse::const_iterator it = inverse.find(value); |
|
391 if (it != inverse.end()) { |
|
392 return it->second; |
|
393 } else { |
|
394 throw DataFormatException("Invalid ID"); |
|
395 } |
|
396 } |
|
397 }; |
|
398 |
|
399 template <typename _Item, typename _Reader> |
|
400 class SkipReaderInverter : public InverterBase<_Item> { |
|
401 public: |
|
402 typedef _Item Item; |
|
403 typedef _Reader Reader; |
|
404 typedef typename Reader::Value Value; |
|
405 typedef std::map<Value, Item> Inverse; |
|
406 |
|
407 Reader reader; |
|
408 |
|
409 SkipReaderInverter(const Reader& _reader) |
|
410 : reader(_reader) {} |
|
411 |
|
412 virtual void read(istream& is, const Item& item) { |
|
413 Value value; |
|
414 reader.read(is, value); |
|
415 typename Inverse::iterator it = inverse.find(value); |
|
416 if (it == inverse.end()) { |
|
417 inverse.insert(make_pair(value, item)); |
|
418 } else { |
|
419 throw DataFormatException("Multiple ID occurence"); |
|
420 } |
|
421 } |
|
422 |
|
423 virtual Item read(istream& is) { |
|
424 Value value; |
|
425 reader.read(is, value); |
|
426 typename Inverse::const_iterator it = inverse.find(value); |
|
427 if (it != inverse.end()) { |
|
428 return it->second; |
|
429 } else { |
|
430 throw DataFormatException("Invalid ID"); |
|
431 } |
|
432 } |
|
433 private: |
|
434 Inverse inverse; |
|
435 }; |
|
436 |
175 |
437 |
176 template <typename _Item> |
438 template <typename _Item> |
177 class MapReaderBase { |
439 class ReaderBase { |
178 public: |
440 public: |
179 typedef _Item Item; |
441 typedef _Item Item; |
180 virtual void read(istream& is, const Item& item) = 0; |
442 virtual void read(istream& is, const Item& item) = 0; |
181 }; |
443 virtual InverterBase<_Item>* getInverter() = 0; |
182 |
444 }; |
|
445 |
183 template <typename _Item, typename _Map, typename _Reader> |
446 template <typename _Item, typename _Map, typename _Reader> |
184 class MapReader : public MapReaderBase<_Item> { |
447 class MapReader : public ReaderBase<_Item> { |
185 public: |
448 public: |
186 typedef _Map Map; |
449 typedef _Map Map; |
187 typedef _Reader Reader; |
450 typedef _Reader Reader; |
|
451 typedef typename Reader::Value Value; |
188 typedef _Item Item; |
452 typedef _Item Item; |
189 |
453 |
190 Map& map; |
454 Map& map; |
191 Reader reader; |
455 Reader reader; |
192 |
456 |
193 MapReader(Map& _map, const Reader& _reader) |
457 MapReader(Map& _map, const Reader& _reader) |
194 : map(_map), reader(_reader) {} |
458 : map(_map), reader(_reader) {} |
195 |
459 |
196 |
460 |
197 virtual void read(istream& is, const Item& item) { |
461 virtual void read(istream& is, const Item& item) { |
198 typename Reader::Value value; |
462 Value value; |
199 reader.read(is, value); |
463 reader.read(is, value); |
200 map.set(item, value); |
464 map.set(item, value); |
201 } |
465 } |
202 }; |
466 |
203 |
467 virtual InverterBase<_Item>* getInverter() { |
204 typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders; |
468 return new MapReaderInverter<Item, Map, Reader>(map, reader); |
|
469 } |
|
470 }; |
|
471 |
|
472 |
|
473 template <typename _Item, typename _Reader> |
|
474 class SkipReader : public ReaderBase<_Item> { |
|
475 public: |
|
476 typedef _Reader Reader; |
|
477 typedef typename Reader::Value Value; |
|
478 typedef _Item Item; |
|
479 |
|
480 Reader reader; |
|
481 SkipReader(const Reader& _reader) : reader(_reader) {} |
|
482 |
|
483 virtual void read(istream& is, const Item& item) { |
|
484 Value value; |
|
485 reader.read(is, value); |
|
486 } |
|
487 |
|
488 virtual InverterBase<Item>* getInverter() { |
|
489 return new SkipReaderInverter<Item, Reader>(reader); |
|
490 } |
|
491 }; |
|
492 |
|
493 |
|
494 typedef std::map<std::string, ReaderBase<Node>* > NodeReaders; |
205 NodeReaders node_readers; |
495 NodeReaders node_readers; |
206 |
496 |
207 typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders; |
497 typedef std::map<std::string, ReaderBase<Edge>* > EdgeReaders; |
208 EdgeReaders edge_readers; |
498 EdgeReaders edge_readers; |
209 |
499 |
|
500 std::istream& is; |
|
501 Graph& graph; |
|
502 |
|
503 SkipReader<Node, DefaultReader> nodeSkipper; |
|
504 SkipReader<Edge, DefaultReader> edgeSkipper; |
|
505 |
210 }; |
506 }; |
211 |
507 |
212 } |
508 } |