Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

item_reader.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00024 
00028 
00029 #ifndef LEMON_BITS_ITEM_READER_H
00030 #define LEMON_BITS_ITEM_READER_H
00031 
00032 #include <iostream>
00033 #include <string>
00034 
00035 #include <vector>
00036 #include <deque>
00037 #include <list>
00038 #include <set>
00039 
00040 namespace lemon {
00041   
00042   template <typename Value>
00043   class DefaultReader;
00044 
00053   class QuotedStringReader {
00054   public:
00058     typedef std::string Value;
00059     
00064     QuotedStringReader(bool _escaped = true) 
00065       : escaped(_escaped) {}
00066     
00070     void read(std::istream& is, std::string& value) const {
00071       char c;
00072       value.clear();
00073       is >> std::ws;
00074       if (!is.get(c) || c != '\"') 
00075         throw DataFormatError("Quoted string format error");
00076       while (is.get(c) && c != '\"') {
00077         if (escaped && c == '\\') {
00078           value += readEscape(is);
00079         } else {
00080           value += c;
00081         }
00082       }
00083       if (!is) throw DataFormatError("Quoted string format error");
00084     }
00085 
00086   private:
00087     
00088     static char readEscape(std::istream& is) {
00089       char c;
00090       switch (is.get(c), c) {
00091       case '\\':
00092         return '\\';
00093       case '\"':
00094         return '\"';
00095       case '\'':
00096         return '\'';
00097       case '\?':
00098         return '\?';
00099       case 'a':
00100         return '\a';
00101       case 'b':
00102         return '\b';
00103       case 'f':
00104         return '\f';
00105       case 'n':
00106         return '\n';
00107       case 'r':
00108         return '\r';
00109       case 't':
00110         return '\t';
00111       case 'v':
00112         return '\v';
00113       case 'x':
00114         {
00115           int code;
00116           if (!is.get(c) || !isHex(c)) 
00117             throw DataFormatError("Escape format error");
00118           else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
00119           else code = code * 16 + valueHex(c);
00120           return code;
00121         }
00122       default:
00123         {
00124           int code;
00125           if (!isOct(c)) 
00126             throw DataFormatError("Escape format error");
00127           else if (code = valueOct(c), !is.get(c) || !isOct(c)) 
00128             is.putback(c);
00129           else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) 
00130             is.putback(c);
00131           else code = code * 8 + valueOct(c);
00132           return code;
00133         }             
00134       } 
00135     }
00136 
00137     static bool isOct(char c) {
00138       return '0' <= c && c <='7'; 
00139     }
00140     
00141     static int valueOct(char c) {
00142       return c - '0';
00143     }
00144 
00145    static bool isHex(char c) {
00146       return ('0' <= c && c <= '9') || 
00147         ('a' <= c && c <= 'z') || 
00148         ('A' <= c && c <= 'Z'); 
00149     }
00150     
00151     static int valueHex(char c) {
00152       if ('0' <= c && c <= '9') return c - '0';
00153       if ('a' <= c && c <= 'z') return c - 'a' + 10;
00154       return c - 'A' + 10;
00155     }
00156 
00157     bool escaped;
00158   };
00159 
00168   template <
00169     typename _Container, 
00170     typename _ItemReader = DefaultReader<typename _Container::value_type> 
00171   >
00172   class PushBackReader {
00173   public:
00174     typedef _Container Value;
00175     typedef _ItemReader ItemReader;
00176 
00177   private:
00178 
00179     ItemReader item_reader;
00180 
00181   public:
00182 
00186     void read(std::istream& is, Value& value) const {
00187       char c;
00188       if (!(is >> c) || c != '(') 
00189         throw DataFormatError("PushBackReader format error");
00190       while (is >> c && c != ')') {
00191         is.putback(c);
00192         typename ItemReader::Value item;
00193         item_reader.read(is, item);
00194         value.push_back(item);
00195       }
00196       if (!is) throw DataFormatError("PushBackReader format error");
00197       is.putback(c);
00198     }
00199 
00200   };
00201 
00211   template <
00212     typename _Container, 
00213     typename _ItemReader = DefaultReader<typename _Container::value_type> 
00214   >
00215   class InsertReader {
00216   public:
00217     typedef _Container Value;
00218     typedef _ItemReader ItemReader;
00219 
00220   private:
00221 
00222     ItemReader item_reader;
00223 
00224   public:
00225 
00229     void read(std::istream& is, Value& value) const {
00230       char c;
00231       if (!(is >> c) || c != '(') 
00232         throw DataFormatError("InsertReader format error");
00233       while (is >> c && c != ')') {
00234         is.putback(c);
00235         typename ItemReader::Value item;
00236         item_reader.read(is, item);
00237         value.insert(item);
00238       }
00239       if (!is) throw DataFormatError("PushBackReader format error");
00240       is.putback(c);
00241     }
00242 
00243   };
00244 
00252   class ParsedStringReader {
00253   public:
00254     typedef std::string Value;
00255 
00260     ParsedStringReader(char _open = '(', char _close = ')')
00261       : open(_open), close(_close) {}
00262     
00263     
00267     void read(std::istream& is, Value& value) const {
00268       char c;
00269       if (!(is >> c) || c != open) {
00270         throw DataFormatError("ParsedStringReader format error");
00271       }
00272       value += c;
00273       int counter = 1;
00274       while (counter > 0 && is >> c) {
00275         if (c == close) {
00276           --counter;
00277         } else if (c == open) {
00278           ++counter;
00279         }
00280         value += c;
00281       }
00282       if (!is) {
00283         throw DataFormatError("ParsedStrinReader format error");
00284       }
00285     }
00286 
00287   private:
00288     char open, close;
00289 
00290   };
00291 
00298   class LineReader {
00299   public:
00300     typedef std::string Value;
00301 
00307     LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
00308     
00312     void read(std::istream& is, Value& value) {
00313       if (skipSpaces) is >> std::ws;
00314       if (!getline(is, value)) {
00315         throw DataFormatError("LineReader forma error");
00316       }
00317     }
00318   private:
00319     bool skipSpaces;
00320   };
00321 
00330   template <typename _Value>
00331   class DefaultReader {
00332   public:
00334     typedef _Value Value;
00338     void read(std::istream& is, Value& value) const {
00339       if (!(is >> value)) 
00340         throw DataFormatError("DefaultReader format error");
00341     }
00342   };
00343 
00344   template <>
00345   class DefaultReader<std::string> {
00346   public:
00347     typedef std::string Value;
00348     
00349     void read(std::istream& is, Value& value) const {
00350       char c;
00351       if (!(is >> std::ws >> c)) return;
00352       is.putback(c);
00353       switch (c) {
00354       case '\"':
00355         QuotedStringReader().read(is, value);
00356         break;
00357       case '(':
00358         ParsedStringReader().read(is, value);
00359         break;
00360       default:
00361         is >> value; 
00362         break;
00363       }
00364     }
00365     
00366   };
00367 
00368   template <typename Item>
00369   class DefaultReader<std::vector<Item> > 
00370     : public PushBackReader<std::vector<Item> > {};
00371 
00372   template <typename Item>
00373   class DefaultReader<std::deque<Item> > 
00374     : public PushBackReader<std::deque<Item> > {};
00375 
00376   template <typename Item>
00377   class DefaultReader<std::list<Item> > 
00378     : public PushBackReader<std::list<Item> > {};
00379 
00380   template <typename Item>
00381   class DefaultReader<std::set<Item> > 
00382     : public InsertReader<std::set<Item> > {};
00383 
00384   template <typename Item>
00385   class DefaultReader<std::multiset<Item> > 
00386     : public InsertReader<std::multiset<Item> > {};
00387 
00395   class DefaultSkipper : public DefaultReader<std::string> {};
00396 
00403   struct DefaultReaderTraits {
00404 
00405     template <typename _Value>
00406     struct Reader : DefaultReader<_Value> {};
00407 
00408     typedef DefaultSkipper Skipper;
00409 
00410   };
00411 
00412 }
00413 
00414 #endif

Generated on Sat Aug 27 14:14:50 2005 for LEMON by  doxygen 1.4.4