lemon/bits/item_reader.h
changeset 2254 50cb2b90daa9
parent 2016 ecb067198349
child 2386 81b47fc5c444
equal deleted inserted replaced
7:4b71511bc194 8:f7d078cd8771
    36   template <typename Value>
    36   template <typename Value>
    37   class DefaultReader;
    37   class DefaultReader;
    38 
    38 
    39   /// \ingroup item_io
    39   /// \ingroup item_io
    40   ///
    40   ///
       
    41   /// \brief Reader class for unformatted strings.
       
    42   ///
       
    43   /// Reader class for unformatted strings. This class want to be
       
    44   /// a general reader type which can read the most 
       
    45   ///
       
    46   /// \author Balazs Dezso
       
    47   class UnformattedReader {
       
    48   public:
       
    49     /// \brief The value type of reader.
       
    50     ///
       
    51     /// The value type of reader.
       
    52     typedef std::string Value;
       
    53     
       
    54     /// \brief Constructor for the reader.
       
    55     ///
       
    56     /// Constructor for the reader.
       
    57     UnformattedReader() {} 
       
    58     
       
    59     /// \brief Reads an unformatted string from the given stream.
       
    60     ///
       
    61     /// Reads an unformatted string from the given stream.
       
    62     void read(std::istream& is, std::string& value) const {
       
    63       char c;
       
    64       value.clear();
       
    65       is >> std::ws;
       
    66       while (is.get(c) && !whiteSpace(c)) {
       
    67         processChar(c, is, value);
       
    68       }
       
    69     }
       
    70 
       
    71   private:
       
    72 
       
    73     void processChar(char c, std::istream& is, Value& value) const {
       
    74       switch (c) {
       
    75       case '(':
       
    76         is.putback(c);
       
    77         readParsed('(', ')', is, value);
       
    78         break;
       
    79       case '[':
       
    80         is.putback(c);
       
    81         readParsed('[', ']', is, value);
       
    82         break;
       
    83       case '{':
       
    84         is.putback(c);
       
    85         readParsed('{', '}', is, value);
       
    86         break;
       
    87       case '/':
       
    88         is.putback(c);
       
    89         readParsed('/', '/', is, value);
       
    90         break;
       
    91       case '\"':
       
    92         is.putback(c);
       
    93         readQuoted('\"', is, value);
       
    94         break;
       
    95       case '\'':
       
    96         is.putback(c);
       
    97         readQuoted('\'', is, value);
       
    98         break;
       
    99       default:
       
   100         value += c;
       
   101         break;
       
   102       }
       
   103     }
       
   104 
       
   105     void readParsed(char open, char close, 
       
   106                     std::istream& is, Value& value) const {
       
   107       char c;
       
   108       if (!is.get(c) || c != open)
       
   109 	throw DataFormatError("Unformatted string format error");
       
   110       value += c;
       
   111       while (is.get(c) && c != close) {
       
   112         processChar(c, is, value);
       
   113       }
       
   114       if (!is) 
       
   115         throw DataFormatError("Unformatted string format error");
       
   116       value += c;      
       
   117     }
       
   118 
       
   119     void readQuoted(char quote, std::istream& is, Value& value) const {
       
   120       char c;
       
   121       bool esc = false;
       
   122       if (!is.get(c) || c != quote)
       
   123 	throw DataFormatError("Unformatted string format error");
       
   124       value += c;
       
   125       while (is.get(c) && (c != quote || esc)) {
       
   126         if (c == '\\') esc = !esc;
       
   127         else esc = false;
       
   128         value += c;
       
   129       }
       
   130       if (!is) 
       
   131         throw DataFormatError("Unformatted string format error");
       
   132       value += c;
       
   133     }
       
   134 
       
   135 
       
   136 
       
   137     static bool whiteSpace(char c) {
       
   138       return c == ' ' || c == '\t' || c == '\v' || 
       
   139         c == '\n' || c == '\r' || c == '\f'; 
       
   140     }
       
   141 
       
   142     
       
   143   };
       
   144 
       
   145   /// \ingroup item_io
       
   146   ///
    41   /// \brief Reader class for quoted strings.
   147   /// \brief Reader class for quoted strings.
    42   ///
   148   ///
    43   /// Reader class for quoted strings. It can process the escape
   149   /// Reader class for quoted strings. It can process the escape
    44   /// sequences in the string.
   150   /// sequences in the string.
    45   ///
   151   ///
    46   /// \author Balazs Dezso
   152   /// \author Balazs Dezso
    47   class QuotedStringReader {
   153   class QuotedStringReader {
       
   154     friend class QuotedCharReader;
    48   public:
   155   public:
    49     /// \brief The value type of reader.
   156     /// \brief The value type of reader.
    50     ///
   157     ///
    51     /// The value type of reader.
   158     /// The value type of reader.
    52     typedef std::string Value;
   159     typedef std::string Value;
    64     void read(std::istream& is, std::string& value) const {
   171     void read(std::istream& is, std::string& value) const {
    65       char c;
   172       char c;
    66       value.clear();
   173       value.clear();
    67       is >> std::ws;
   174       is >> std::ws;
    68       if (!is.get(c) || c != '\"') 
   175       if (!is.get(c) || c != '\"') 
    69 	throw DataFormatError("Quoted string format error");
   176 	throw DataFormatError("Quoted format error");
    70       while (is.get(c) && c != '\"') {
   177       while (is.get(c) && c != '\"') {
    71 	if (escaped && c == '\\') {
   178 	if (escaped && c == '\\') {
    72 	  value += readEscape(is);
   179 	  value += readEscape(is);
    73 	} else {
   180 	} else {
    74 	  value += c;
   181 	  value += c;
    75 	}
   182 	}
    76       }
   183       }
    77       if (!is) throw DataFormatError("Quoted string format error");
   184       if (!is) throw DataFormatError("Quoted format error");
    78     }
   185     }
    79 
   186 
    80   private:
   187   private:
    81     
   188     
    82     static char readEscape(std::istream& is) {
   189     static char readEscape(std::istream& is) {
   150 
   257 
   151     bool escaped;
   258     bool escaped;
   152   };
   259   };
   153 
   260 
   154   /// \ingroup item_io
   261   /// \ingroup item_io
       
   262   ///
       
   263   /// \brief Reader class for quoted strings.
       
   264   ///
       
   265   /// Reader class for quoted strings. It can process the escape
       
   266   /// sequences in the string.
       
   267   ///
       
   268   /// \author Balazs Dezso
       
   269   class QuotedCharReader {
       
   270   public:
       
   271     /// \brief The value type of reader.
       
   272     ///
       
   273     /// The value type of reader.
       
   274     typedef char Value;
       
   275     
       
   276     /// \brief Constructor for the reader.
       
   277     ///
       
   278     /// Constructor for the reader. If the given parameter is true
       
   279     /// the reader processes the escape sequences.
       
   280     QuotedCharReader(bool _escaped = true) 
       
   281       : escaped(_escaped) {}
       
   282     
       
   283     /// \brief Reads a quoted string from the given stream.
       
   284     ///
       
   285     /// Reads a quoted string from the given stream.
       
   286     void read(std::istream& is, char& value) const {
       
   287       char c;
       
   288       is >> std::ws;
       
   289       if (!is.get(c) || c != '\'') 
       
   290 	throw DataFormatError("Quoted format error");
       
   291       if (!is.get(c)) 
       
   292         throw DataFormatError("Quoted format error");
       
   293       if (escaped && c == '\\') {
       
   294         value = QuotedStringReader::readEscape(is);
       
   295       } else {
       
   296         value = c;
       
   297       }
       
   298       if (!is.get(c) || c != '\'') 
       
   299 	throw DataFormatError("Quoted format error");
       
   300     }
       
   301 
       
   302   private:
       
   303     bool escaped;
       
   304   };
       
   305 
       
   306   /// \ingroup item_io
   155   /// \brief Reader for standard containers.
   307   /// \brief Reader for standard containers.
   156   ///
   308   ///
   157   /// Reader for back insertable standard containers. The representation
   309   /// Reader for back insertable standard containers. The representation
   158   /// of the container is the values enumerated between an open and a
   310   /// of the container is the values enumerated between an open and a
   159   /// close parse. 
   311   /// close parse. 
   269     /// \brief Reads the parsed string from the given stream.
   421     /// \brief Reads the parsed string from the given stream.
   270     ///
   422     ///
   271     /// Reads the parsed string from the given stream.
   423     /// Reads the parsed string from the given stream.
   272     void read(std::istream& is, Value& value) const {
   424     void read(std::istream& is, Value& value) const {
   273       char c;
   425       char c;
       
   426       value.clear();
   274       if (!(is >> c) || c != open) {
   427       if (!(is >> c) || c != open) {
   275 	throw DataFormatError("ParsedStringReader format error");
   428 	throw DataFormatError("ParsedStringReader format error");
   276       }
   429       }
   277       value += c;
   430       value += c;
   278       int counter = 1;
   431       int counter = 1;
   405   public:
   558   public:
   406     typedef std::string Value;
   559     typedef std::string Value;
   407     
   560     
   408     void read(std::istream& is, Value& value) const {
   561     void read(std::istream& is, Value& value) const {
   409       char c;
   562       char c;
   410       if (!(is >> std::ws >> c)) return;
   563       if (!(is >> std::ws >> c)) 
       
   564         throw DataFormatError("DefaultReader<string> format error");
   411       is.putback(c);
   565       is.putback(c);
   412       switch (c) {
   566       switch (c) {
   413       case '\"':
   567       case '\"':
   414 	QuotedStringReader().read(is, value);
   568 	QuotedStringReader().read(is, value);
   415 	break;
   569 	break;
   416       case '(':
   570       default:
   417 	ParsedStringReader().read(is, value);
   571         UnformattedReader().read(is, value);
   418 	break;
   572 	break;
   419       case '[':
   573       }
   420 	ParsedStringReader('[', ']').read(is, value);
   574     }
   421 	break;
   575     
   422       case '/':
   576   };
   423 	ParsedStringReader('/', '/').read(is, value);
   577 
       
   578   template <>
       
   579   class DefaultReader<char> {
       
   580   public:
       
   581     typedef char Value;
       
   582     
       
   583     void read(std::istream& is, Value& value) const {
       
   584       char c;
       
   585       if (!(is >> std::ws >> c))
       
   586         throw DataFormatError("DefaultReader<char> format error");
       
   587       is.putback(c);
       
   588       switch (c) {
       
   589       case '\'':
       
   590 	QuotedCharReader().read(is, value);
   424 	break;
   591 	break;
   425       default:
   592       default:
   426 	if (!(is >> value)) 
   593         { 
   427 	  throw DataFormatError("DefaultReader format error");
   594           int temp;          
   428 	break;
   595           if (!(is >> temp)) 
   429       }
   596             throw DataFormatError("DefaultReader<char> format error");
   430     }
   597           value = (char)temp;
   431     
   598           break;
       
   599         }
       
   600       }
       
   601     }    
       
   602   };
       
   603 
       
   604   template <>
       
   605   class DefaultReader<bool> {
       
   606   public:
       
   607     typedef bool Value;
       
   608     
       
   609     void read(std::istream& is, Value& value) const {
       
   610       std::string rep;
       
   611       if (!(is >> rep))
       
   612         throw DataFormatError("DefaultReader<bool> format error");
       
   613       if (rep == "true" || rep == "t" || rep == "1") {
       
   614         value = true;
       
   615       } else if (rep == "false" || rep == "f" || rep == "0") {
       
   616         value = false;
       
   617       } else throw DataFormatError("DefaultReader<bool> format error");
       
   618     }    
   432   };
   619   };
   433 
   620 
   434   template <typename Item>
   621   template <typename Item>
   435   class DefaultReader<std::vector<Item> > 
   622   class DefaultReader<std::vector<Item> > 
   436     : public PushBackReader<std::vector<Item> > {};
   623     : public PushBackReader<std::vector<Item> > {};
   470   /// \brief The default item reader for skipping a value in the stream.
   657   /// \brief The default item reader for skipping a value in the stream.
   471   ///
   658   ///
   472   /// The default item reader for skipping a value in the stream.
   659   /// The default item reader for skipping a value in the stream.
   473   ///
   660   ///
   474   /// \author Balazs Dezso
   661   /// \author Balazs Dezso
   475   class DefaultSkipper : public DefaultReader<std::string> {};
   662   class DefaultSkipper : public UnformattedReader {};
   476 
   663 
   477   /// \ingroup item_io  
   664   /// \ingroup item_io  
   478   /// \brief Standard ReaderTraits for the GraphReader class.
   665   /// \brief Standard ReaderTraits for the GraphReader class.
   479   ///
   666   ///
   480   /// Standard ReaderTraits for the GraphReader class.
   667   /// Standard ReaderTraits for the GraphReader class.