item_reader.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
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

Generated on Fri Feb 3 18:35:48 2006 for LEMON by  doxygen 1.4.6