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. |
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> > {}; |