]>
Commit | Line | Data |
---|---|---|
46c4e5d6 | 1 | // -*- C++ -*- |
983de0da | 2 | // Testing streambuf/filebuf/stringbuf for the C++ library testsuite. |
46c4e5d6 | 3 | // |
8fc81078 | 4 | // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010 |
748086b7 | 5 | // Free Software Foundation, Inc. |
46c4e5d6 BK |
6 | // |
7 | // This file is part of the GNU ISO C++ Library. This library is free | |
8 | // software; you can redistribute it and/or modify it under the | |
9 | // terms of the GNU General Public License as published by the | |
748086b7 | 10 | // Free Software Foundation; either version 3, or (at your option) |
46c4e5d6 BK |
11 | // any later version. |
12 | // | |
13 | // This library is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License along | |
748086b7 JJ |
19 | // with this library; see the file COPYING3. If not see |
20 | // <http://www.gnu.org/licenses/>. | |
46c4e5d6 | 21 | // |
46c4e5d6 | 22 | |
3d7c150e BK |
23 | #ifndef _GLIBCXX_TESTSUITE_IO_H |
24 | #define _GLIBCXX_TESTSUITE_IO_H | |
46c4e5d6 | 25 | |
2fdff2be | 26 | #include <ios> |
46c4e5d6 | 27 | |
aecf642c | 28 | namespace __gnu_test |
46c4e5d6 BK |
29 | { |
30 | // Used to verify the constraints/requirements on get and put areas | |
31 | // as defined in | |
32 | // 27.5.1 - Stream buffer requirements: get and put areas | |
33 | // 27.8.1.1 - Template class basic_filebuf p 3 | |
34 | // If the file is not open (ios_base::in) -> input seq. cannot be read | |
35 | // If the file is not open (ios_base::out) -> output seq. cannot be written | |
36 | // Joint file position | |
37 | // 27.8.1.4 - Overridden virtual functions p9 | |
38 | // If unbuffered, pbase == pptr == NULL | |
983de0da PC |
39 | // 27.7.1.1 - Basic_stringbuf constructors p 1 |
40 | // 27.8.1.2 - Basic_filebuf constructors p 1 | |
41 | // ... , initializing the base class with basic_streambuf() 27.5.2.1 | |
42 | template<typename T> | |
43 | class constraint_buf | |
44 | : public T | |
45 | { | |
46 | public: | |
47 | bool | |
48 | write_position() | |
49 | { | |
8fc81078 | 50 | bool one = this->pptr() != 0; |
983de0da PC |
51 | bool two = this->pptr() < this->epptr(); |
52 | return one && two; | |
53 | } | |
54 | ||
55 | bool | |
56 | read_position() | |
57 | { | |
8fc81078 | 58 | bool one = this->gptr() != 0; |
983de0da PC |
59 | bool two = this->gptr() < this->egptr(); |
60 | return one && two; | |
61 | } | |
62 | ||
63 | bool | |
64 | unbuffered() | |
65 | { | |
8fc81078 PC |
66 | bool one = this->pbase() == 0; |
67 | bool two = this->pptr() == 0; | |
983de0da PC |
68 | return one && two; |
69 | } | |
70 | ||
71 | bool | |
72 | check_pointers() | |
73 | { | |
8fc81078 PC |
74 | bool one = this->eback() == 0; |
75 | bool two = this->gptr() == 0; | |
76 | bool three = this->egptr() == 0; | |
983de0da | 77 | |
8fc81078 PC |
78 | bool four = this->pbase() == 0; |
79 | bool five = this->pptr() == 0; | |
80 | bool six = this->epptr() == 0; | |
983de0da PC |
81 | return one && two && three && four && five && six; |
82 | } | |
83 | }; | |
46c4e5d6 | 84 | |
983de0da PC |
85 | typedef constraint_buf<std::streambuf> constraint_streambuf; |
86 | typedef constraint_buf<std::filebuf> constraint_filebuf; | |
87 | typedef constraint_buf<std::stringbuf> constraint_stringbuf; | |
88 | #ifdef _GLIBCXX_USE_WCHAR_T | |
89 | typedef constraint_buf<std::wstreambuf> constraint_wstreambuf; | |
90 | typedef constraint_buf<std::wfilebuf> constraint_wfilebuf; | |
91 | typedef constraint_buf<std::wstringbuf> constraint_wstringbuf; | |
92 | #endif | |
5681c890 PR |
93 | |
94 | // Used to check if basic_streambuf::pubsync() has been called. | |
95 | // This is useful for checking if a function creates [io]stream::sentry | |
96 | // objects, since the sentry constructors call tie()->flush(). | |
9b8d9ac3 PC |
97 | template<typename T> |
98 | class sync_buf | |
99 | : public T | |
100 | { | |
101 | private: | |
102 | bool m_sync_called; | |
5681c890 | 103 | |
9b8d9ac3 PC |
104 | public: |
105 | sync_buf() | |
106 | : m_sync_called(false) | |
107 | { } | |
108 | ||
109 | bool sync_called() const | |
110 | { return m_sync_called; } | |
5681c890 | 111 | |
9b8d9ac3 PC |
112 | protected: |
113 | int sync() | |
114 | { | |
115 | m_sync_called = true; | |
116 | return 0; | |
117 | } | |
118 | }; | |
5681c890 | 119 | |
9b8d9ac3 PC |
120 | typedef sync_buf<std::streambuf> sync_streambuf; |
121 | #ifdef _GLIBCXX_USE_WCHAR_T | |
122 | typedef sync_buf<std::wstreambuf> sync_wstreambuf; | |
123 | #endif | |
12841eb3 BK |
124 | |
125 | // Throws on all overflow and underflow calls. | |
126 | struct underflow_error: std::exception { }; | |
127 | struct overflow_error: std::exception { }; | |
128 | struct positioning_error: std::exception { }; | |
129 | ||
9b8d9ac3 PC |
130 | template<typename T> |
131 | struct fail_buf | |
132 | : public T | |
12841eb3 | 133 | { |
9b8d9ac3 PC |
134 | typedef typename T::char_type char_type; |
135 | typedef typename T::int_type int_type; | |
136 | typedef typename T::off_type off_type; | |
137 | typedef typename T::pos_type pos_type; | |
12841eb3 | 138 | |
9b8d9ac3 PC |
139 | private: |
140 | char_type p[2]; | |
12841eb3 | 141 | |
9b8d9ac3 PC |
142 | public: |
143 | fail_buf() | |
144 | { | |
145 | p[0] = char_type('s'); | |
146 | p[1] = char_type(); | |
94df301f | 147 | this->setg(p, p, p + 1); |
9b8d9ac3 | 148 | } |
12841eb3 | 149 | |
9b8d9ac3 PC |
150 | virtual int_type underflow() |
151 | { | |
152 | throw underflow_error(); | |
cfc45d90 | 153 | return int_type(); |
9b8d9ac3 PC |
154 | } |
155 | ||
156 | virtual int_type uflow() | |
157 | { | |
158 | throw underflow_error(); | |
cfc45d90 | 159 | return int_type(); |
9b8d9ac3 PC |
160 | } |
161 | ||
162 | virtual int_type | |
163 | overflow(int_type) | |
164 | { | |
165 | throw overflow_error(); | |
cfc45d90 | 166 | return int_type(); |
9b8d9ac3 PC |
167 | } |
168 | ||
169 | virtual pos_type | |
170 | seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode) | |
171 | { | |
172 | throw positioning_error(); | |
173 | return pos_type(off_type(-1)); | |
174 | } | |
175 | ||
176 | virtual pos_type | |
177 | seekpos(pos_type, std::ios_base::openmode) | |
178 | { | |
179 | throw positioning_error(); | |
180 | return pos_type(off_type(-1)); | |
181 | } | |
182 | ||
183 | virtual int | |
184 | sync() | |
185 | { | |
186 | throw positioning_error(); | |
187 | return 0; | |
188 | } | |
189 | }; | |
12841eb3 | 190 | |
9b8d9ac3 PC |
191 | typedef fail_buf<std::streambuf> fail_streambuf; |
192 | #ifdef _GLIBCXX_USE_WCHAR_T | |
193 | typedef fail_buf<std::wstreambuf> fail_wstreambuf; | |
194 | #endif | |
12841eb3 BK |
195 | |
196 | // Facets that throw an exception for every virtual function. | |
197 | struct facet_error: std::exception { }; | |
198 | ||
9b8d9ac3 PC |
199 | template<typename T> |
200 | class fail_num_get | |
201 | : public std::num_get<T> | |
202 | { | |
203 | typedef std::ios_base ios_base; | |
204 | typedef typename std::num_get<T>::iter_type iter_type; | |
12841eb3 | 205 | |
9b8d9ac3 PC |
206 | protected: |
207 | iter_type | |
8b5bc374 | 208 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const |
9b8d9ac3 | 209 | { throw facet_error(); return iter_type(); } |
12841eb3 | 210 | |
9b8d9ac3 PC |
211 | virtual iter_type |
212 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long&) const | |
213 | { throw facet_error(); return iter_type(); } | |
214 | ||
215 | virtual iter_type | |
8b5bc374 | 216 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
217 | unsigned short&) const |
218 | { throw facet_error(); return iter_type(); } | |
219 | ||
220 | virtual iter_type | |
8b5bc374 | 221 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
222 | unsigned int&) const |
223 | { throw facet_error(); return iter_type(); } | |
224 | ||
225 | virtual iter_type | |
8b5bc374 | 226 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
227 | unsigned long&) const |
228 | { throw facet_error(); return iter_type(); } | |
12841eb3 BK |
229 | |
230 | #ifdef _GLIBCXX_USE_LONG_LONG | |
9b8d9ac3 | 231 | virtual iter_type |
8b5bc374 | 232 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
233 | long long&) const |
234 | { throw facet_error(); return iter_type(); } | |
235 | ||
236 | virtual iter_type | |
8b5bc374 | 237 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
238 | unsigned long long&) const |
239 | { throw facet_error(); return iter_type(); } | |
12841eb3 BK |
240 | #endif |
241 | ||
9b8d9ac3 | 242 | virtual iter_type |
8b5bc374 | 243 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
244 | float&) const |
245 | { throw facet_error(); return iter_type(); } | |
246 | ||
247 | virtual iter_type | |
8b5bc374 | 248 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
249 | double&) const |
250 | { throw facet_error(); return iter_type(); } | |
251 | ||
252 | virtual iter_type | |
8b5bc374 | 253 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
254 | long double&) const |
255 | { throw facet_error(); return iter_type(); } | |
256 | ||
257 | virtual iter_type | |
8b5bc374 | 258 | do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, |
9b8d9ac3 PC |
259 | void*&) const |
260 | { throw facet_error(); return iter_type(); } | |
261 | }; | |
12841eb3 | 262 | |
9b8d9ac3 PC |
263 | typedef fail_num_get<char> fail_num_get_char; |
264 | #ifdef _GLIBCXX_USE_WCHAR_T | |
265 | typedef fail_num_get<wchar_t> fail_num_get_wchar_t; | |
266 | #endif | |
12841eb3 | 267 | |
9b8d9ac3 PC |
268 | template<typename T> |
269 | class fail_num_put | |
270 | : public std::num_put<T> | |
271 | { | |
272 | typedef std::ios_base ios_base; | |
273 | typedef typename std::num_put<T>::iter_type iter_type; | |
274 | typedef typename std::num_put<T>::char_type char_type; | |
275 | ||
276 | protected: | |
277 | iter_type | |
8b5bc374 | 278 | do_put(iter_type, ios_base&, char_type, bool) const |
8fc81078 | 279 | { throw facet_error(); return iter_type(0); } |
9b8d9ac3 PC |
280 | |
281 | virtual iter_type | |
8b5bc374 | 282 | do_put(iter_type, ios_base&, char_type, long) const |
8fc81078 | 283 | { throw facet_error(); return iter_type(0); } |
12841eb3 | 284 | |
9b8d9ac3 | 285 | virtual iter_type |
8b5bc374 | 286 | do_put(iter_type, ios_base&, char_type, unsigned long) const |
8fc81078 | 287 | { throw facet_error(); return iter_type(0); } |
12841eb3 BK |
288 | |
289 | #ifdef _GLIBCXX_USE_LONG_LONG | |
9b8d9ac3 | 290 | virtual iter_type |
8b5bc374 | 291 | do_put(iter_type, ios_base&, char_type, long long) const |
8fc81078 | 292 | { throw facet_error(); return iter_type(0); } |
12841eb3 | 293 | |
9b8d9ac3 | 294 | virtual iter_type |
8b5bc374 | 295 | do_put(iter_type, ios_base&, char_type, unsigned long long) const |
8fc81078 | 296 | { throw facet_error(); return iter_type(0); } |
12841eb3 | 297 | #endif |
9b8d9ac3 PC |
298 | |
299 | virtual iter_type | |
8b5bc374 | 300 | do_put(iter_type, ios_base&, char_type, double) const |
8fc81078 | 301 | { throw facet_error(); return iter_type(0); } |
12841eb3 | 302 | |
9b8d9ac3 | 303 | virtual iter_type |
8b5bc374 | 304 | do_put(iter_type, ios_base&, char_type, long double) const |
8fc81078 | 305 | { throw facet_error(); return iter_type(0); } |
9b8d9ac3 PC |
306 | |
307 | virtual iter_type | |
8b5bc374 | 308 | do_put(iter_type, ios_base&, char_type, const void*) const |
8fc81078 | 309 | { throw facet_error(); return iter_type(0); } |
9b8d9ac3 | 310 | }; |
12841eb3 | 311 | |
9b8d9ac3 PC |
312 | typedef fail_num_put<char> fail_num_put_char; |
313 | #ifdef _GLIBCXX_USE_WCHAR_T | |
314 | typedef fail_num_put<wchar_t> fail_num_put_wchar_t; | |
315 | #endif | |
799a6e36 | 316 | } // namespace __gnu_test |
46c4e5d6 | 317 | |
3d7c150e | 318 | #endif // _GLIBCXX_TESTSUITE_IO_H |
46c4e5d6 | 319 |