diff -r 1645f6cc9667 -r 50cb2b90daa9 lemon/bits/item_reader.h --- a/lemon/bits/item_reader.h Tue Oct 17 11:05:23 2006 +0000 +++ b/lemon/bits/item_reader.h Wed Oct 18 15:05:12 2006 +0000 @@ -38,6 +38,112 @@ /// \ingroup item_io /// + /// \brief Reader class for unformatted strings. + /// + /// Reader class for unformatted strings. This class want to be + /// a general reader type which can read the most + /// + /// \author Balazs Dezso + class UnformattedReader { + public: + /// \brief The value type of reader. + /// + /// The value type of reader. + typedef std::string Value; + + /// \brief Constructor for the reader. + /// + /// Constructor for the reader. + UnformattedReader() {} + + /// \brief Reads an unformatted string from the given stream. + /// + /// Reads an unformatted string from the given stream. + void read(std::istream& is, std::string& value) const { + char c; + value.clear(); + is >> std::ws; + while (is.get(c) && !whiteSpace(c)) { + processChar(c, is, value); + } + } + + private: + + void processChar(char c, std::istream& is, Value& value) const { + switch (c) { + case '(': + is.putback(c); + readParsed('(', ')', is, value); + break; + case '[': + is.putback(c); + readParsed('[', ']', is, value); + break; + case '{': + is.putback(c); + readParsed('{', '}', is, value); + break; + case '/': + is.putback(c); + readParsed('/', '/', is, value); + break; + case '\"': + is.putback(c); + readQuoted('\"', is, value); + break; + case '\'': + is.putback(c); + readQuoted('\'', is, value); + break; + default: + value += c; + break; + } + } + + void readParsed(char open, char close, + std::istream& is, Value& value) const { + char c; + if (!is.get(c) || c != open) + throw DataFormatError("Unformatted string format error"); + value += c; + while (is.get(c) && c != close) { + processChar(c, is, value); + } + if (!is) + throw DataFormatError("Unformatted string format error"); + value += c; + } + + void readQuoted(char quote, std::istream& is, Value& value) const { + char c; + bool esc = false; + if (!is.get(c) || c != quote) + throw DataFormatError("Unformatted string format error"); + value += c; + while (is.get(c) && (c != quote || esc)) { + if (c == '\\') esc = !esc; + else esc = false; + value += c; + } + if (!is) + throw DataFormatError("Unformatted string format error"); + value += c; + } + + + + static bool whiteSpace(char c) { + return c == ' ' || c == '\t' || c == '\v' || + c == '\n' || c == '\r' || c == '\f'; + } + + + }; + + /// \ingroup item_io + /// /// \brief Reader class for quoted strings. /// /// Reader class for quoted strings. It can process the escape @@ -45,6 +151,7 @@ /// /// \author Balazs Dezso class QuotedStringReader { + friend class QuotedCharReader; public: /// \brief The value type of reader. /// @@ -66,7 +173,7 @@ value.clear(); is >> std::ws; if (!is.get(c) || c != '\"') - throw DataFormatError("Quoted string format error"); + throw DataFormatError("Quoted format error"); while (is.get(c) && c != '\"') { if (escaped && c == '\\') { value += readEscape(is); @@ -74,7 +181,7 @@ value += c; } } - if (!is) throw DataFormatError("Quoted string format error"); + if (!is) throw DataFormatError("Quoted format error"); } private: @@ -152,6 +259,51 @@ }; /// \ingroup item_io + /// + /// \brief Reader class for quoted strings. + /// + /// Reader class for quoted strings. It can process the escape + /// sequences in the string. + /// + /// \author Balazs Dezso + class QuotedCharReader { + public: + /// \brief The value type of reader. + /// + /// The value type of reader. + typedef char Value; + + /// \brief Constructor for the reader. + /// + /// Constructor for the reader. If the given parameter is true + /// the reader processes the escape sequences. + QuotedCharReader(bool _escaped = true) + : escaped(_escaped) {} + + /// \brief Reads a quoted string from the given stream. + /// + /// Reads a quoted string from the given stream. + void read(std::istream& is, char& value) const { + char c; + is >> std::ws; + if (!is.get(c) || c != '\'') + throw DataFormatError("Quoted format error"); + if (!is.get(c)) + throw DataFormatError("Quoted format error"); + if (escaped && c == '\\') { + value = QuotedStringReader::readEscape(is); + } else { + value = c; + } + if (!is.get(c) || c != '\'') + throw DataFormatError("Quoted format error"); + } + + private: + bool escaped; + }; + + /// \ingroup item_io /// \brief Reader for standard containers. /// /// Reader for back insertable standard containers. The representation @@ -271,6 +423,7 @@ /// Reads the parsed string from the given stream. void read(std::istream& is, Value& value) const { char c; + value.clear(); if (!(is >> c) || c != open) { throw DataFormatError("ParsedStringReader format error"); } @@ -407,30 +560,64 @@ void read(std::istream& is, Value& value) const { char c; - if (!(is >> std::ws >> c)) return; + if (!(is >> std::ws >> c)) + throw DataFormatError("DefaultReader format error"); is.putback(c); switch (c) { case '\"': QuotedStringReader().read(is, value); break; - case '(': - ParsedStringReader().read(is, value); - break; - case '[': - ParsedStringReader('[', ']').read(is, value); - break; - case '/': - ParsedStringReader('/', '/').read(is, value); - break; default: - if (!(is >> value)) - throw DataFormatError("DefaultReader format error"); + UnformattedReader().read(is, value); break; } } }; + template <> + class DefaultReader { + public: + typedef char Value; + + void read(std::istream& is, Value& value) const { + char c; + if (!(is >> std::ws >> c)) + throw DataFormatError("DefaultReader format error"); + is.putback(c); + switch (c) { + case '\'': + QuotedCharReader().read(is, value); + break; + default: + { + int temp; + if (!(is >> temp)) + throw DataFormatError("DefaultReader format error"); + value = (char)temp; + break; + } + } + } + }; + + template <> + class DefaultReader { + public: + typedef bool Value; + + void read(std::istream& is, Value& value) const { + std::string rep; + if (!(is >> rep)) + throw DataFormatError("DefaultReader format error"); + if (rep == "true" || rep == "t" || rep == "1") { + value = true; + } else if (rep == "false" || rep == "f" || rep == "0") { + value = false; + } else throw DataFormatError("DefaultReader format error"); + } + }; + template class DefaultReader > : public PushBackReader > {}; @@ -472,7 +659,7 @@ /// The default item reader for skipping a value in the stream. /// /// \author Balazs Dezso - class DefaultSkipper : public DefaultReader {}; + class DefaultSkipper : public UnformattedReader {}; /// \ingroup item_io /// \brief Standard ReaderTraits for the GraphReader class.