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