00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00020
00021 #ifndef LEMON_BITS_ITEM_WRITER_H
00022 #define LEMON_BITS_ITEM_WRITER_H
00023
00024 #include <iostream>
00025 #include <string>
00026
00027 #include <vector>
00028 #include <deque>
00029 #include <list>
00030 #include <set>
00031
00032 namespace lemon {
00033
00034 template <typename Value>
00035 class DefaultWriter;
00036
00043 class QuotedStringWriter {
00044 public:
00045 typedef std::string Value;
00046
00051 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
00052
00056 void write(std::ostream& os, const std::string& value) {
00057 os << "\"";
00058 if (escaped) {
00059 std::ostringstream ls;
00060 for (int i = 0; i < (int)value.size(); ++i) {
00061 writeEscape(ls, value[i]);
00062 }
00063 os << ls.str();
00064 } else {
00065 os << value;
00066 }
00067 os << "\"";
00068 }
00069
00070 private:
00071
00072 static void writeEscape(std::ostream& os, char c) {
00073 switch (c) {
00074 case '\\':
00075 os << "\\\\";
00076 return;
00077 case '\"':
00078 os << "\\\"";
00079 return;
00080 case '\'':
00081 os << "\\\'";
00082 return;
00083 case '\?':
00084 os << "\\\?";
00085 return;
00086 case '\a':
00087 os << "\\a";
00088 return;
00089 case '\b':
00090 os << "\\b";
00091 return;
00092 case '\f':
00093 os << "\\f";
00094 return;
00095 case '\r':
00096 os << "\\r";
00097 return;
00098 case '\n':
00099 os << "\\n";
00100 return;
00101 case '\t':
00102 os << "\\t";
00103 return;
00104 case '\v':
00105 os << "\\v";
00106 return;
00107 default:
00108 if (c < 0x20) {
00109 os << '\\' << std::oct << (int)c;
00110 } else {
00111 os << c;
00112 }
00113 return;
00114 }
00115 }
00116 private:
00117 bool escaped;
00118 };
00119
00126 class QuotedCharArrayWriter {
00127 public:
00128 typedef const char* Value;
00129
00134 QuotedCharArrayWriter(bool _escaped = true) : escaped(_escaped) {}
00135
00139 void write(std::ostream& os, const char* value) {
00140 QuotedStringWriter(escaped).write(os, std::string(value));
00141 }
00142
00143 private:
00144 bool escaped;
00145 };
00146
00147
00157 template <
00158 typename _Container,
00159 typename _ItemWriter = DefaultWriter<typename _Container::value_type>
00160 >
00161 class IterableWriter {
00162 public:
00163 typedef _Container Value;
00164 typedef _ItemWriter ItemWriter;
00165
00166 private:
00167
00168 ItemWriter item_writer;
00169
00170 public:
00171
00175 void write(std::ostream& os, const Value& value) const {
00176 typename Value::const_iterator it;
00177 os << '(';
00178 for (it = value.begin(); it != value.end(); ++it) {
00179 item_writer.write(os, *it);
00180 os << ' ';
00181 }
00182 os << ')';
00183 }
00184
00185 };
00186
00195 template <typename _Value>
00196 class DefaultWriter {
00197 public:
00199 typedef _Value Value;
00203 void write(std::ostream& os, const Value& value) const {
00204 os << value;
00205 }
00206 };
00207
00208 template <>
00209 class DefaultWriter<std::string>
00210 : public QuotedStringWriter {};
00211
00212 template <int length>
00213 class DefaultWriter<char[length]>
00214 : public QuotedCharArrayWriter {};
00215
00216 template <int length>
00217 class DefaultWriter<const char[length]>
00218 : public QuotedCharArrayWriter {};
00219
00220 template <typename Item>
00221 class DefaultWriter<std::vector<Item> >
00222 : public IterableWriter<std::vector<Item> > {};
00223
00224 template <typename Item>
00225 class DefaultWriter<std::deque<Item> >
00226 : public IterableWriter<std::deque<Item> > {};
00227
00228 template <typename Item>
00229 class DefaultWriter<std::list<Item> >
00230 : public IterableWriter<std::list<Item> > {};
00231
00232 template <typename Item>
00233 class DefaultWriter<std::set<Item> >
00234 : public IterableWriter<std::set<Item> > {};
00235
00236 template <typename Item>
00237 class DefaultWriter<std::multiset<Item> >
00238 : public IterableWriter<std::multiset<Item> > {};
00239
00246 struct DefaultWriterTraits {
00247
00248 template <typename _Value>
00249 struct Writer : DefaultWriter<_Value> {
00250 typedef DefaultWriter<_Value> Parent;
00251 };
00252
00253 };
00254
00255 }
00256
00257 #endif