00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026
00030
00031 #ifndef LEMON_BITS_ITEM_READER_H
00032 #define LEMON_BITS_ITEM_READER_H
00033
00034 #include <iostream>
00035 #include <string>
00036
00037 #include <vector>
00038 #include <deque>
00039 #include <list>
00040 #include <set>
00041
00042 namespace lemon {
00043
00044 template <typename Value>
00045 class DefaultReader;
00046
00055 class QuotedStringReader {
00056 public:
00060 typedef std::string Value;
00061
00066 QuotedStringReader(bool _escaped = true)
00067 : escaped(_escaped) {}
00068
00072 void read(std::istream& is, std::string& value) const {
00073 char c;
00074 value.clear();
00075 is >> std::ws;
00076 if (!is.get(c) || c != '\"')
00077 throw DataFormatError("Quoted string format error");
00078 while (is.get(c) && c != '\"') {
00079 if (escaped && c == '\\') {
00080 value += readEscape(is);
00081 } else {
00082 value += c;
00083 }
00084 }
00085 if (!is) throw DataFormatError("Quoted string format error");
00086 }
00087
00088 private:
00089
00090 static char readEscape(std::istream& is) {
00091 char c;
00092 switch (is.get(c), c) {
00093 case '\\':
00094 return '\\';
00095 case '\"':
00096 return '\"';
00097 case '\'':
00098 return '\'';
00099 case '\?':
00100 return '\?';
00101 case 'a':
00102 return '\a';
00103 case 'b':
00104 return '\b';
00105 case 'f':
00106 return '\f';
00107 case 'n':
00108 return '\n';
00109 case 'r':
00110 return '\r';
00111 case 't':
00112 return '\t';
00113 case 'v':
00114 return '\v';
00115 case 'x':
00116 {
00117 int code;
00118 if (!is.get(c) || !isHex(c))
00119 throw DataFormatError("Escape format error");
00120 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
00121 else code = code * 16 + valueHex(c);
00122 return code;
00123 }
00124 default:
00125 {
00126 int code;
00127 if (!isOct(c))
00128 throw DataFormatError("Escape format error");
00129 else if (code = valueOct(c), !is.get(c) || !isOct(c))
00130 is.putback(c);
00131 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
00132 is.putback(c);
00133 else code = code * 8 + valueOct(c);
00134 return code;
00135 }
00136 }
00137 }
00138
00139 static bool isOct(char c) {
00140 return '0' <= c && c <='7';
00141 }
00142
00143 static int valueOct(char c) {
00144 return c - '0';
00145 }
00146
00147 static bool isHex(char c) {
00148 return ('0' <= c && c <= '9') ||
00149 ('a' <= c && c <= 'z') ||
00150 ('A' <= c && c <= 'Z');
00151 }
00152
00153 static int valueHex(char c) {
00154 if ('0' <= c && c <= '9') return c - '0';
00155 if ('a' <= c && c <= 'z') return c - 'a' + 10;
00156 return c - 'A' + 10;
00157 }
00158
00159 bool escaped;
00160 };
00161
00170 template <
00171 typename _Container,
00172 typename _ItemReader = DefaultReader<typename _Container::value_type>
00173 >
00174 class PushBackReader {
00175 public:
00176 typedef _Container Value;
00177 typedef _ItemReader ItemReader;
00178
00179 private:
00180
00181 ItemReader item_reader;
00182
00183 public:
00184
00188 PushBackReader(const ItemReader& _item_reader = ItemReader())
00189 : item_reader(_item_reader) {}
00190
00194 void read(std::istream& is, Value& value) const {
00195 char c;
00196 if (!(is >> c) || c != '(')
00197 throw DataFormatError("PushBackReader format error");
00198 while (is >> c && c != ')') {
00199 is.putback(c);
00200 typename ItemReader::Value item;
00201 item_reader.read(is, item);
00202 value.push_back(item);
00203 }
00204 if (!is) throw DataFormatError("PushBackReader format error");
00205 }
00206
00207 };
00208
00218 template <
00219 typename _Container,
00220 typename _ItemReader = DefaultReader<typename _Container::value_type>
00221 >
00222 class InsertReader {
00223 public:
00224 typedef _Container Value;
00225 typedef _ItemReader ItemReader;
00226
00227 private:
00228
00229 ItemReader item_reader;
00230
00231 public:
00232
00236 InsertReader(const ItemReader& _item_reader = ItemReader())
00237 : item_reader(_item_reader) {}
00238
00242 void read(std::istream& is, Value& value) const {
00243 char c;
00244 if (!(is >> c) || c != '(')
00245 throw DataFormatError("InsertReader format error");
00246 while (is >> c && c != ')') {
00247 is.putback(c);
00248 typename ItemReader::Value item;
00249 item_reader.read(is, item);
00250 value.insert(item);
00251 }
00252 if (!is) throw DataFormatError("PushBackReader format error");
00253 }
00254
00255 };
00256
00265 class ParsedStringReader {
00266 public:
00267 typedef std::string Value;
00268
00273 ParsedStringReader(char _open = '(', char _close = ')')
00274 : open(_open), close(_close) {}
00275
00276
00280 void read(std::istream& is, Value& value) const {
00281 char c;
00282 if (!(is >> c) || c != open) {
00283 throw DataFormatError("ParsedStringReader format error");
00284 }
00285 value += c;
00286 int counter = 1;
00287 while (counter > 0 && is >> c) {
00288 if (c == close) {
00289 --counter;
00290 } else if (c == open) {
00291 ++counter;
00292 }
00293 value += c;
00294 }
00295 if (!is) {
00296 throw DataFormatError("ParsedStrinReader format error");
00297 }
00298 }
00299
00300 private:
00301 char open, close;
00302
00303 };
00304
00311 class LineReader {
00312 public:
00313 typedef std::string Value;
00314
00320 LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
00321
00325 void read(std::istream& is, Value& value) const {
00326 if (skipSpaces) is >> std::ws;
00327 if (!getline(is, value)) {
00328 throw DataFormatError("LineReader format error");
00329 }
00330 }
00331 private:
00332 bool skipSpaces;
00333 };
00334
00341 template <typename _Pair,
00342 typename _FirstReader =
00343 DefaultReader<typename _Pair::first_type>,
00344 typename _SecondReader =
00345 DefaultReader<typename _Pair::second_type> >
00346 class PairReader {
00347 public:
00348 typedef _Pair Value;
00349
00350 typedef _FirstReader FirstReader;
00351 typedef _SecondReader SecondReader;
00352
00353 private:
00354
00355 FirstReader first_reader;
00356 SecondReader second_reader;
00357
00358 public:
00359
00363 PairReader(const FirstReader& _first_reader = FirstReader(),
00364 const SecondReader& _second_reader = SecondReader())
00365 : first_reader(_first_reader), second_reader(_second_reader) {}
00366
00370 void read(std::istream& is, Value& value) const {
00371 char c;
00372 if (!(is >> c) || c != '(') {
00373 throw DataFormatError("PairReader format error");
00374 }
00375 first_reader.read(is, value.first);
00376 if (!(is >> c) || c != '=') {
00377 throw DataFormatError("PairReader format error");
00378 }
00379 if (!(is >> c) || c != '>') {
00380 throw DataFormatError("PairReader format error");
00381 }
00382 second_reader.read(is, value.second);
00383 if (!(is >> c) || c != ')') {
00384 throw DataFormatError("PairReader format error");
00385 }
00386 }
00387 };
00388
00397 template <typename _Value>
00398 class DefaultReader {
00399 public:
00401 typedef _Value Value;
00405 void read(std::istream& is, Value& value) const {
00406 if (!(is >> value))
00407 throw DataFormatError("DefaultReader format error");
00408 }
00409 };
00410
00411 template <>
00412 class DefaultReader<std::string> {
00413 public:
00414 typedef std::string Value;
00415
00416 void read(std::istream& is, Value& value) const {
00417 char c;
00418 if (!(is >> std::ws >> c)) return;
00419 is.putback(c);
00420 switch (c) {
00421 case '\"':
00422 QuotedStringReader().read(is, value);
00423 break;
00424 case '(':
00425 ParsedStringReader().read(is, value);
00426 break;
00427 case '[':
00428 ParsedStringReader('[', ']').read(is, value);
00429 break;
00430 case '/':
00431 ParsedStringReader('/', '/').read(is, value);
00432 break;
00433 default:
00434 if (!(is >> value))
00435 throw DataFormatError("DefaultReader format error");
00436 break;
00437 }
00438 }
00439
00440 };
00441
00442 template <typename Item>
00443 class DefaultReader<std::vector<Item> >
00444 : public PushBackReader<std::vector<Item> > {};
00445
00446 template <typename Item>
00447 class DefaultReader<std::deque<Item> >
00448 : public PushBackReader<std::deque<Item> > {};
00449
00450 template <typename Item>
00451 class DefaultReader<std::list<Item> >
00452 : public PushBackReader<std::list<Item> > {};
00453
00454 template <typename Item>
00455 class DefaultReader<std::set<Item> >
00456 : public InsertReader<std::set<Item> > {};
00457
00458 template <typename Key, typename Value>
00459 class DefaultReader<std::map<Key, Value> >
00460 : public InsertReader<std::map<Key, Value>,
00461 DefaultReader<std::pair<Key, Value> > > {};
00462
00463 template <typename Item>
00464 class DefaultReader<std::multiset<Item> >
00465 : public InsertReader<std::multiset<Item> > {};
00466
00467 template <typename Key, typename Value>
00468 class DefaultReader<std::multimap<Key, Value> >
00469 : public InsertReader<std::multimap<Key, Value>,
00470 DefaultReader<std::pair<Key, Value> > > {};
00471
00472 template <typename First, typename Second>
00473 class DefaultReader<std::pair<First, Second> >
00474 : public PairReader<std::pair<First, Second> > {};
00475
00483 class DefaultSkipper : public DefaultReader<std::string> {};
00484
00491 struct DefaultReaderTraits {
00492
00493 template <typename _Value>
00494 struct Reader : DefaultReader<_Value> {};
00495
00496 typedef DefaultSkipper Skipper;
00497
00498 };
00499
00500 }
00501
00502 #endif