1.1 --- a/lemon/bits/item_reader.h Tue Oct 17 11:05:23 2006 +0000
1.2 +++ b/lemon/bits/item_reader.h Wed Oct 18 15:05:12 2006 +0000
1.3 @@ -38,6 +38,112 @@
1.4
1.5 /// \ingroup item_io
1.6 ///
1.7 + /// \brief Reader class for unformatted strings.
1.8 + ///
1.9 + /// Reader class for unformatted strings. This class want to be
1.10 + /// a general reader type which can read the most
1.11 + ///
1.12 + /// \author Balazs Dezso
1.13 + class UnformattedReader {
1.14 + public:
1.15 + /// \brief The value type of reader.
1.16 + ///
1.17 + /// The value type of reader.
1.18 + typedef std::string Value;
1.19 +
1.20 + /// \brief Constructor for the reader.
1.21 + ///
1.22 + /// Constructor for the reader.
1.23 + UnformattedReader() {}
1.24 +
1.25 + /// \brief Reads an unformatted string from the given stream.
1.26 + ///
1.27 + /// Reads an unformatted string from the given stream.
1.28 + void read(std::istream& is, std::string& value) const {
1.29 + char c;
1.30 + value.clear();
1.31 + is >> std::ws;
1.32 + while (is.get(c) && !whiteSpace(c)) {
1.33 + processChar(c, is, value);
1.34 + }
1.35 + }
1.36 +
1.37 + private:
1.38 +
1.39 + void processChar(char c, std::istream& is, Value& value) const {
1.40 + switch (c) {
1.41 + case '(':
1.42 + is.putback(c);
1.43 + readParsed('(', ')', is, value);
1.44 + break;
1.45 + case '[':
1.46 + is.putback(c);
1.47 + readParsed('[', ']', is, value);
1.48 + break;
1.49 + case '{':
1.50 + is.putback(c);
1.51 + readParsed('{', '}', is, value);
1.52 + break;
1.53 + case '/':
1.54 + is.putback(c);
1.55 + readParsed('/', '/', is, value);
1.56 + break;
1.57 + case '\"':
1.58 + is.putback(c);
1.59 + readQuoted('\"', is, value);
1.60 + break;
1.61 + case '\'':
1.62 + is.putback(c);
1.63 + readQuoted('\'', is, value);
1.64 + break;
1.65 + default:
1.66 + value += c;
1.67 + break;
1.68 + }
1.69 + }
1.70 +
1.71 + void readParsed(char open, char close,
1.72 + std::istream& is, Value& value) const {
1.73 + char c;
1.74 + if (!is.get(c) || c != open)
1.75 + throw DataFormatError("Unformatted string format error");
1.76 + value += c;
1.77 + while (is.get(c) && c != close) {
1.78 + processChar(c, is, value);
1.79 + }
1.80 + if (!is)
1.81 + throw DataFormatError("Unformatted string format error");
1.82 + value += c;
1.83 + }
1.84 +
1.85 + void readQuoted(char quote, std::istream& is, Value& value) const {
1.86 + char c;
1.87 + bool esc = false;
1.88 + if (!is.get(c) || c != quote)
1.89 + throw DataFormatError("Unformatted string format error");
1.90 + value += c;
1.91 + while (is.get(c) && (c != quote || esc)) {
1.92 + if (c == '\\') esc = !esc;
1.93 + else esc = false;
1.94 + value += c;
1.95 + }
1.96 + if (!is)
1.97 + throw DataFormatError("Unformatted string format error");
1.98 + value += c;
1.99 + }
1.100 +
1.101 +
1.102 +
1.103 + static bool whiteSpace(char c) {
1.104 + return c == ' ' || c == '\t' || c == '\v' ||
1.105 + c == '\n' || c == '\r' || c == '\f';
1.106 + }
1.107 +
1.108 +
1.109 + };
1.110 +
1.111 + /// \ingroup item_io
1.112 + ///
1.113 /// \brief Reader class for quoted strings.
1.114 ///
1.115 /// Reader class for quoted strings. It can process the escape
1.116 @@ -45,6 +151,7 @@
1.117 ///
1.118 /// \author Balazs Dezso
1.119 class QuotedStringReader {
1.120 + friend class QuotedCharReader;
1.121 public:
1.122 /// \brief The value type of reader.
1.123 ///
1.124 @@ -66,7 +173,7 @@
1.125 value.clear();
1.126 is >> std::ws;
1.127 if (!is.get(c) || c != '\"')
1.128 - throw DataFormatError("Quoted string format error");
1.129 + throw DataFormatError("Quoted format error");
1.130 while (is.get(c) && c != '\"') {
1.131 if (escaped && c == '\\') {
1.132 value += readEscape(is);
1.133 @@ -74,7 +181,7 @@
1.134 value += c;
1.135 }
1.136 }
1.137 - if (!is) throw DataFormatError("Quoted string format error");
1.138 + if (!is) throw DataFormatError("Quoted format error");
1.139 }
1.140
1.141 private:
1.142 @@ -152,6 +259,51 @@
1.143 };
1.144
1.145 /// \ingroup item_io
1.146 + ///
1.147 + /// \brief Reader class for quoted strings.
1.148 + ///
1.149 + /// Reader class for quoted strings. It can process the escape
1.150 + /// sequences in the string.
1.151 + ///
1.152 + /// \author Balazs Dezso
1.153 + class QuotedCharReader {
1.154 + public:
1.155 + /// \brief The value type of reader.
1.156 + ///
1.157 + /// The value type of reader.
1.158 + typedef char Value;
1.159 +
1.160 + /// \brief Constructor for the reader.
1.161 + ///
1.162 + /// Constructor for the reader. If the given parameter is true
1.163 + /// the reader processes the escape sequences.
1.164 + QuotedCharReader(bool _escaped = true)
1.165 + : escaped(_escaped) {}
1.166 +
1.167 + /// \brief Reads a quoted string from the given stream.
1.168 + ///
1.169 + /// Reads a quoted string from the given stream.
1.170 + void read(std::istream& is, char& value) const {
1.171 + char c;
1.172 + is >> std::ws;
1.173 + if (!is.get(c) || c != '\'')
1.174 + throw DataFormatError("Quoted format error");
1.175 + if (!is.get(c))
1.176 + throw DataFormatError("Quoted format error");
1.177 + if (escaped && c == '\\') {
1.178 + value = QuotedStringReader::readEscape(is);
1.179 + } else {
1.180 + value = c;
1.181 + }
1.182 + if (!is.get(c) || c != '\'')
1.183 + throw DataFormatError("Quoted format error");
1.184 + }
1.185 +
1.186 + private:
1.187 + bool escaped;
1.188 + };
1.189 +
1.190 + /// \ingroup item_io
1.191 /// \brief Reader for standard containers.
1.192 ///
1.193 /// Reader for back insertable standard containers. The representation
1.194 @@ -271,6 +423,7 @@
1.195 /// Reads the parsed string from the given stream.
1.196 void read(std::istream& is, Value& value) const {
1.197 char c;
1.198 + value.clear();
1.199 if (!(is >> c) || c != open) {
1.200 throw DataFormatError("ParsedStringReader format error");
1.201 }
1.202 @@ -407,30 +560,64 @@
1.203
1.204 void read(std::istream& is, Value& value) const {
1.205 char c;
1.206 - if (!(is >> std::ws >> c)) return;
1.207 + if (!(is >> std::ws >> c))
1.208 + throw DataFormatError("DefaultReader<string> format error");
1.209 is.putback(c);
1.210 switch (c) {
1.211 case '\"':
1.212 QuotedStringReader().read(is, value);
1.213 break;
1.214 - case '(':
1.215 - ParsedStringReader().read(is, value);
1.216 - break;
1.217 - case '[':
1.218 - ParsedStringReader('[', ']').read(is, value);
1.219 - break;
1.220 - case '/':
1.221 - ParsedStringReader('/', '/').read(is, value);
1.222 - break;
1.223 default:
1.224 - if (!(is >> value))
1.225 - throw DataFormatError("DefaultReader format error");
1.226 + UnformattedReader().read(is, value);
1.227 break;
1.228 }
1.229 }
1.230
1.231 };
1.232
1.233 + template <>
1.234 + class DefaultReader<char> {
1.235 + public:
1.236 + typedef char Value;
1.237 +
1.238 + void read(std::istream& is, Value& value) const {
1.239 + char c;
1.240 + if (!(is >> std::ws >> c))
1.241 + throw DataFormatError("DefaultReader<char> format error");
1.242 + is.putback(c);
1.243 + switch (c) {
1.244 + case '\'':
1.245 + QuotedCharReader().read(is, value);
1.246 + break;
1.247 + default:
1.248 + {
1.249 + int temp;
1.250 + if (!(is >> temp))
1.251 + throw DataFormatError("DefaultReader<char> format error");
1.252 + value = (char)temp;
1.253 + break;
1.254 + }
1.255 + }
1.256 + }
1.257 + };
1.258 +
1.259 + template <>
1.260 + class DefaultReader<bool> {
1.261 + public:
1.262 + typedef bool Value;
1.263 +
1.264 + void read(std::istream& is, Value& value) const {
1.265 + std::string rep;
1.266 + if (!(is >> rep))
1.267 + throw DataFormatError("DefaultReader<bool> format error");
1.268 + if (rep == "true" || rep == "t" || rep == "1") {
1.269 + value = true;
1.270 + } else if (rep == "false" || rep == "f" || rep == "0") {
1.271 + value = false;
1.272 + } else throw DataFormatError("DefaultReader<bool> format error");
1.273 + }
1.274 + };
1.275 +
1.276 template <typename Item>
1.277 class DefaultReader<std::vector<Item> >
1.278 : public PushBackReader<std::vector<Item> > {};
1.279 @@ -472,7 +659,7 @@
1.280 /// The default item reader for skipping a value in the stream.
1.281 ///
1.282 /// \author Balazs Dezso
1.283 - class DefaultSkipper : public DefaultReader<std::string> {};
1.284 + class DefaultSkipper : public UnformattedReader {};
1.285
1.286 /// \ingroup item_io
1.287 /// \brief Standard ReaderTraits for the GraphReader class.
2.1 --- a/lemon/bits/item_writer.h Tue Oct 17 11:05:23 2006 +0000
2.2 +++ b/lemon/bits/item_writer.h Wed Oct 18 15:05:12 2006 +0000
2.3 @@ -24,6 +24,7 @@
2.4 #define LEMON_BITS_ITEM_WRITER_H
2.5
2.6 #include <iostream>
2.7 +#include <sstream>
2.8 #include <string>
2.9
2.10 #include <vector>
2.11 @@ -39,10 +40,101 @@
2.12 /// \ingroup item_io
2.13 /// \brief Writer class for quoted strings.
2.14 ///
2.15 + /// Writer class for unformatted strings.
2.16 + /// \author Balazs Dezso
2.17 + class UnformattedWriter {
2.18 + public:
2.19 + typedef std::string Value;
2.20 +
2.21 + /// \brief Constructor for the writer.
2.22 + ///
2.23 + /// Constructor for the writer.
2.24 + UnformattedWriter() {}
2.25 +
2.26 + /// \brief Writes an unformatted string to the given stream.
2.27 + ///
2.28 + /// Writes an unformatted string to the given stream.
2.29 + void write(std::ostream& os, const std::string& value) const {
2.30 + os << value;
2.31 + }
2.32 +
2.33 + bool readable(const std::string& value) const {
2.34 + std::istringstream is(value);
2.35 + char c;
2.36 + while (is.get(c) && !whiteSpace(c)) {
2.37 + if (!processChar(c, is)) return false;
2.38 + }
2.39 + if (is) return false;
2.40 + return true;
2.41 + }
2.42 +
2.43 + private:
2.44 +
2.45 + bool processChar(char c, std::istream& is) const {
2.46 + switch (c) {
2.47 + case '(':
2.48 + is.putback(c);
2.49 + if (!readableParsed('(', ')', is)) return false;
2.50 + break;
2.51 + case '[':
2.52 + is.putback(c);
2.53 + if (!readableParsed('[', ']', is)) return false;
2.54 + break;
2.55 + case '{':
2.56 + is.putback(c);
2.57 + if (!readableParsed('{', '}', is)) return false;
2.58 + break;
2.59 + case '\"':
2.60 + is.putback(c);
2.61 + if (!readableQuoted('\"', is)) return false;
2.62 + break;
2.63 + case '\'':
2.64 + is.putback(c);
2.65 + if (!readableQuoted('\'', is)) return false;
2.66 + break;
2.67 + default:
2.68 + break;
2.69 + }
2.70 + return true;
2.71 + }
2.72 +
2.73 + bool readableParsed(char open, char close, std::istream& is) const {
2.74 + char c;
2.75 + if (!is.get(c) || c != open) return false;
2.76 + while (is.get(c) && c != close) {
2.77 + if (!processChar(c, is)) return false;
2.78 + }
2.79 + if (!is) return false;
2.80 + return true;
2.81 + }
2.82 +
2.83 + bool readableQuoted(char quote, std::istream& is) const {
2.84 + char c;
2.85 + bool esc = false;
2.86 + if (!is.get(c) || c != quote) return false;
2.87 + while (is.get(c) && c != quote && !esc) {
2.88 + if (c == '\\') esc = !esc;
2.89 + else esc = false;
2.90 + }
2.91 + if (!is) return false;
2.92 + return true;
2.93 + }
2.94 +
2.95 + static bool whiteSpace(char c) {
2.96 + return c == ' ' || c == '\t' || c == '\v' ||
2.97 + c == '\n' || c == '\r' || c == '\f';
2.98 + }
2.99 +
2.100 + };
2.101 +
2.102 + /// \ingroup item_io
2.103 + /// \brief Writer class for quoted strings.
2.104 + ///
2.105 /// Writer class for quoted strings. It can process the escape
2.106 /// sequences in the string.
2.107 /// \author Balazs Dezso
2.108 class QuotedStringWriter {
2.109 + friend class QuotedCharWriter;
2.110 public:
2.111 typedef std::string Value;
2.112
2.113 @@ -120,6 +212,41 @@
2.114 };
2.115
2.116 /// \ingroup item_io
2.117 + /// \brief Writer class for quoted chars.
2.118 + ///
2.119 + /// Writer class for quoted char. It can process the escape
2.120 + /// sequences in the string.
2.121 + /// \author Balazs Dezso
2.122 + class QuotedCharWriter {
2.123 + public:
2.124 + typedef char Value;
2.125 +
2.126 + /// \brief Constructor for the writer.
2.127 + ///
2.128 + /// Constructor for the writer. If the given parameter is true
2.129 + /// the writer creates escape sequences from special characters.
2.130 + QuotedCharWriter(bool _escaped = true) : escaped(_escaped) {}
2.131 +
2.132 + /// \brief Writes a quoted char to the given stream.
2.133 + ///
2.134 + /// Writes a quoted char to the given stream.
2.135 + void write(std::ostream& os, const char& value) const {
2.136 + os << "\'";
2.137 + if (escaped) {
2.138 + std::ostringstream ls;
2.139 + QuotedStringWriter::writeEscape(ls, value);
2.140 + os << ls.str();
2.141 + } else {
2.142 + os << value;
2.143 + }
2.144 + os << "\'";
2.145 + }
2.146 +
2.147 + private:
2.148 + bool escaped;
2.149 + };
2.150 +
2.151 + /// \ingroup item_io
2.152 /// \brief Writer class for quoted char array.
2.153 ///
2.154 /// Writer class for quoted char array. It can process the escape
2.155 @@ -258,8 +385,34 @@
2.156 };
2.157
2.158 template <>
2.159 - class DefaultWriter<std::string>
2.160 - : public QuotedStringWriter {};
2.161 + class DefaultWriter<std::string> {
2.162 + public:
2.163 + typedef std::string Value;
2.164 +
2.165 + void write(std::ostream& os, const Value& value) const {
2.166 + if (UnformattedWriter().readable(value)) {
2.167 + UnformattedWriter().write(os, value);
2.168 + } else {
2.169 + QuotedStringWriter().write(os, value);
2.170 + }
2.171 + }
2.172 +
2.173 + };
2.174 +
2.175 + template <>
2.176 + class DefaultWriter<char>
2.177 + : public QuotedCharWriter {};
2.178 +
2.179 + template <>
2.180 + class DefaultWriter<bool> {
2.181 + public:
2.182 + typedef bool Value;
2.183 +
2.184 + void write(std::ostream& os, const Value& value) const {
2.185 + os << (value ? "1" : "0");
2.186 + }
2.187 +
2.188 + };
2.189
2.190 template <int length>
2.191 class DefaultWriter<char[length]>