# HG changeset patch # User deba # Date 1161183912 0 # Node ID 50cb2b90daa9572b900fa5e6c858d14f867599c7 # Parent 1645f6cc9667897f639bad613e9be8d8c02713e9 Some improvements on item readers and writers 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. diff -r 1645f6cc9667 -r 50cb2b90daa9 lemon/bits/item_writer.h --- a/lemon/bits/item_writer.h Tue Oct 17 11:05:23 2006 +0000 +++ b/lemon/bits/item_writer.h Wed Oct 18 15:05:12 2006 +0000 @@ -24,6 +24,7 @@ #define LEMON_BITS_ITEM_WRITER_H #include +#include #include #include @@ -39,10 +40,101 @@ /// \ingroup item_io /// \brief Writer class for quoted strings. /// + /// Writer class for unformatted strings. + /// \author Balazs Dezso + class UnformattedWriter { + public: + typedef std::string Value; + + /// \brief Constructor for the writer. + /// + /// Constructor for the writer. + UnformattedWriter() {} + + /// \brief Writes an unformatted string to the given stream. + /// + /// Writes an unformatted string to the given stream. + void write(std::ostream& os, const std::string& value) const { + os << value; + } + + bool readable(const std::string& value) const { + std::istringstream is(value); + char c; + while (is.get(c) && !whiteSpace(c)) { + if (!processChar(c, is)) return false; + } + if (is) return false; + return true; + } + + private: + + bool processChar(char c, std::istream& is) const { + switch (c) { + case '(': + is.putback(c); + if (!readableParsed('(', ')', is)) return false; + break; + case '[': + is.putback(c); + if (!readableParsed('[', ']', is)) return false; + break; + case '{': + is.putback(c); + if (!readableParsed('{', '}', is)) return false; + break; + case '\"': + is.putback(c); + if (!readableQuoted('\"', is)) return false; + break; + case '\'': + is.putback(c); + if (!readableQuoted('\'', is)) return false; + break; + default: + break; + } + return true; + } + + bool readableParsed(char open, char close, std::istream& is) const { + char c; + if (!is.get(c) || c != open) return false; + while (is.get(c) && c != close) { + if (!processChar(c, is)) return false; + } + if (!is) return false; + return true; + } + + bool readableQuoted(char quote, std::istream& is) const { + char c; + bool esc = false; + if (!is.get(c) || c != quote) return false; + while (is.get(c) && c != quote && !esc) { + if (c == '\\') esc = !esc; + else esc = false; + } + if (!is) return false; + return true; + } + + static bool whiteSpace(char c) { + return c == ' ' || c == '\t' || c == '\v' || + c == '\n' || c == '\r' || c == '\f'; + } + + }; + + /// \ingroup item_io + /// \brief Writer class for quoted strings. + /// /// Writer class for quoted strings. It can process the escape /// sequences in the string. /// \author Balazs Dezso class QuotedStringWriter { + friend class QuotedCharWriter; public: typedef std::string Value; @@ -120,6 +212,41 @@ }; /// \ingroup item_io + /// \brief Writer class for quoted chars. + /// + /// Writer class for quoted char. It can process the escape + /// sequences in the string. + /// \author Balazs Dezso + class QuotedCharWriter { + public: + typedef char Value; + + /// \brief Constructor for the writer. + /// + /// Constructor for the writer. If the given parameter is true + /// the writer creates escape sequences from special characters. + QuotedCharWriter(bool _escaped = true) : escaped(_escaped) {} + + /// \brief Writes a quoted char to the given stream. + /// + /// Writes a quoted char to the given stream. + void write(std::ostream& os, const char& value) const { + os << "\'"; + if (escaped) { + std::ostringstream ls; + QuotedStringWriter::writeEscape(ls, value); + os << ls.str(); + } else { + os << value; + } + os << "\'"; + } + + private: + bool escaped; + }; + + /// \ingroup item_io /// \brief Writer class for quoted char array. /// /// Writer class for quoted char array. It can process the escape @@ -258,8 +385,34 @@ }; template <> - class DefaultWriter - : public QuotedStringWriter {}; + class DefaultWriter { + public: + typedef std::string Value; + + void write(std::ostream& os, const Value& value) const { + if (UnformattedWriter().readable(value)) { + UnformattedWriter().write(os, value); + } else { + QuotedStringWriter().write(os, value); + } + } + + }; + + template <> + class DefaultWriter + : public QuotedCharWriter {}; + + template <> + class DefaultWriter { + public: + typedef bool Value; + + void write(std::ostream& os, const Value& value) const { + os << (value ? "1" : "0"); + } + + }; template class DefaultWriter