Commit b3329ad5c94b14b696de9f80b400b8c29f9e8bb2
- Diff rendering mode:
- inline
- side by side
src/fstream.cpp
(5 / 5)
|   | |||
| 39 | 39 | typedef char_traits<char> traits_type; | |
| 40 | 40 | typedef traits_type::int_type int_type; | |
| 41 | 41 | ||
| 42 | if (!__this->_M_in_input_mode) { | ||
| 43 | if (!__this->_M_switch_to_input_mode()) | ||
| 42 | if ( (__this->int_flags_ & basic_filebuf<char, char_traits<char> >::_in_input_mode) == 0 ) { | ||
| 43 | if ( !__this->_M_switch_to_input_mode() ) { | ||
| 44 | 44 | return traits_type::eof(); | |
| 45 | } | ||
| 46 | else if (__this->_M_in_putback_mode) { | ||
| 45 | } | ||
| 46 | } else if ( __this->int_flags_ & basic_filebuf<char, char_traits<char> >::_in_putback_mode ) { | ||
| 47 | 47 | __this->_M_exit_putback_mode(); | |
| 48 | 48 | if (__this->gptr() != __this->egptr()) { | |
| 49 | 49 | int_type __c = traits_type::to_int_type(*__this->gptr()); | |
| … | … | ||
| 55 | 55 | // sequences are guaranteed to be identical, then try to use memory | |
| 56 | 56 | // mapped I/O. Otherwise, revert to ordinary read. | |
| 57 | 57 | if (__this->_M_base.__regular_file() | |
| 58 | && __this->_M_always_noconv | ||
| 58 | && ((__this->int_flags_ & basic_filebuf<char, char_traits<char> >::_always_noconv) != 0) | ||
| 59 | 59 | && __this->_M_base._M_in_binary_mode()) { | |
| 60 | 60 | // If we've mmapped part of the file already, then unmap it. | |
| 61 | 61 | if (__this->_M_mmap_base) |
stlport/stl/_fstream.c
(149 / 111)
|   | |||
| 44 | 44 | // Public basic_filebuf<> member functions | |
| 45 | 45 | ||
| 46 | 46 | template <class _CharT, class _Traits> | |
| 47 | basic_filebuf<_CharT, _Traits>::basic_filebuf() | ||
| 48 | : basic_streambuf<_CharT, _Traits>(), _M_base(), | ||
| 49 | _M_constant_width(false), _M_always_noconv(false), | ||
| 50 | _M_int_buf_dynamic(false), | ||
| 51 | _M_in_input_mode(false), _M_in_output_mode(false), | ||
| 52 | _M_in_error_mode(false), _M_in_putback_mode(false), | ||
| 53 | _M_int_buf(0), _M_int_buf_EOS(0), | ||
| 54 | _M_ext_buf(0), _M_ext_buf_EOS(0), | ||
| 55 | _M_ext_buf_converted(0), _M_ext_buf_end(0), | ||
| 47 | basic_filebuf<_CharT, _Traits>::basic_filebuf() : | ||
| 48 | basic_streambuf<_CharT, _Traits>(), | ||
| 49 | _M_base(), | ||
| 50 | int_flags_(0), | ||
| 51 | _M_int_buf(0), | ||
| 52 | _M_int_buf_EOS(0), | ||
| 53 | _M_ext_buf(0), | ||
| 54 | _M_ext_buf_EOS(0), | ||
| 55 | _M_ext_buf_converted(0), | ||
| 56 | _M_ext_buf_end(0), | ||
| 56 | 57 | _M_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), | |
| 57 | 58 | _M_end_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), | |
| 58 | _M_mmap_base(0), _M_mmap_len(0), | ||
| 59 | _M_saved_eback(0), _M_saved_gptr(0), _M_saved_egptr(0), | ||
| 59 | _M_mmap_base(0), | ||
| 60 | _M_mmap_len(0), | ||
| 61 | _M_saved_eback(0), | ||
| 62 | _M_saved_gptr(0), | ||
| 63 | _M_saved_egptr(0), | ||
| 60 | 64 | _M_codecvt(0), | |
| 61 | _M_width(1), _M_max_width(1) | ||
| 65 | _M_width(1), | ||
| 66 | _M_max_width(1) | ||
| 62 | 67 | { | |
| 63 | 68 | this->_M_setup_codecvt(locale(), false); | |
| 64 | 69 | } | |
| … | … | ||
| 83 | 83 | ||
| 84 | 84 | template <class _CharT, class _Traits> | |
| 85 | 85 | basic_filebuf<_CharT, _Traits>* | |
| 86 | basic_filebuf<_CharT, _Traits>::close() { | ||
| 86 | basic_filebuf<_CharT, _Traits>::close() | ||
| 87 | { | ||
| 87 | 88 | bool __ok = this->is_open(); | |
| 88 | 89 | ||
| 89 | if (_M_in_output_mode) { | ||
| 90 | if ( int_flags_ & _in_output_mode ) { | ||
| 90 | 91 | __ok = __ok && !_Traits::eq_int_type(this->overflow(traits_type::eof()), | |
| 91 | 92 | traits_type::eof()); | |
| 92 | 93 | __ok == __ok && this->_M_unshift(); | |
| 94 | } else if ( int_flags_ & _in_input_mode ) { | ||
| 95 | this->_M_exit_input_mode(); | ||
| 93 | 96 | } | |
| 94 | else if (_M_in_input_mode) | ||
| 95 | this->_M_exit_input_mode(); | ||
| 96 | 97 | ||
| 97 | 98 | // Note order of arguments. We close the file even if __ok is false. | |
| 98 | 99 | __ok = _M_base._M_close() && __ok; | |
| … | … | ||
| 111 | 111 | ||
| 112 | 112 | _M_saved_eback = _M_saved_gptr = _M_saved_egptr = 0; | |
| 113 | 113 | ||
| 114 | _M_in_input_mode = _M_in_output_mode = _M_in_error_mode = _M_in_putback_mode | ||
| 115 | = false; | ||
| 114 | int_flags_ &= ~(_in_input_mode | _in_output_mode & _in_error_mode | _in_putback_mode ); | ||
| 116 | 115 | ||
| 117 | 116 | return __ok ? this : 0; | |
| 118 | 117 | } | |
| … | … | ||
| 120 | 120 | // It unmaps the memory-mapped file, if any, and sets | |
| 121 | 121 | // _M_in_input_mode to false. | |
| 122 | 122 | template <class _CharT, class _Traits> | |
| 123 | void basic_filebuf<_CharT, _Traits>::_M_exit_input_mode() { | ||
| 123 | void basic_filebuf<_CharT, _Traits>::_M_exit_input_mode() | ||
| 124 | { | ||
| 124 | 125 | if (_M_mmap_base != 0) { | |
| 125 | 126 | _M_base._M_unmap(_M_mmap_base, _M_mmap_len); | |
| 126 | 127 | _M_mmap_base = 0; | |
| 127 | 128 | _M_mmap_len = 0; | |
| 128 | 129 | } | |
| 129 | _M_in_input_mode = false; | ||
| 130 | |||
| 131 | int_flags_ &= ~_in_input_mode; | ||
| 130 | 132 | } | |
| 131 | 133 | ||
| 132 | 134 | ||
| … | … | ||
| 136 | 136 | // basic_filebuf<> overridden protected virtual member functions | |
| 137 | 137 | ||
| 138 | 138 | template <class _CharT, class _Traits> | |
| 139 | streamsize basic_filebuf<_CharT, _Traits>::showmanyc() { | ||
| 139 | streamsize basic_filebuf<_CharT, _Traits>::showmanyc() | ||
| 140 | { | ||
| 140 | 141 | // Is there any possibility that reads can succeed? | |
| 141 | if (!this->is_open() || _M_in_output_mode || _M_in_error_mode) | ||
| 142 | if ( !this->is_open() || ((int_flags_ & (_in_output_mode | _in_error_mode)) != 0 ) ) { | ||
| 142 | 143 | return -1; | |
| 143 | else if (_M_in_putback_mode) | ||
| 144 | } else if ( (int_flags_ & _in_putback_mode) ) { | ||
| 144 | 145 | return this->egptr() - this->gptr(); | |
| 145 | else if (_M_constant_width) { | ||
| 146 | } else if ( (int_flags_ & _constant_width) ) { | ||
| 146 | 147 | streamoff __pos = _M_base._M_seek(0, ios_base::cur); | |
| 147 | 148 | streamoff __size = _M_base._M_file_size(); | |
| 148 | 149 | return __pos >= 0 && __size > __pos ? __size - __pos : 0; | |
| 149 | 150 | } | |
| 150 | else | ||
| 151 | return 0; | ||
| 151 | |||
| 152 | return 0; | ||
| 152 | 153 | } | |
| 153 | 154 | ||
| 154 | 155 | ||
| … | … | ||
| 162 | 162 | // but the beginning is usually not _M_pback_buf. | |
| 163 | 163 | template <class _CharT, class _Traits> | |
| 164 | 164 | __BF_int_type__ | |
| 165 | basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) { | ||
| 165 | basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) | ||
| 166 | { | ||
| 166 | 167 | const int_type __eof = traits_type::eof(); | |
| 167 | 168 | ||
| 168 | 169 | // If we aren't already in input mode, pushback is impossible. | |
| 169 | if (!_M_in_input_mode) | ||
| 170 | if ( (int_flags_ & _in_input_mode) == 0 ) { | ||
| 170 | 171 | return __eof; | |
| 172 | } | ||
| 171 | 173 | ||
| 172 | 174 | // We can use the ordinary get buffer if there's enough space, and | |
| 173 | 175 | // if it's a buffer that we're allowed to write to. | |
| … | … | ||
| 181 | 181 | if (traits_type::eq_int_type(__c, __eof) || | |
| 182 | 182 | traits_type::eq(traits_type::to_char_type(__c), *this->gptr())) | |
| 183 | 183 | return traits_type::to_int_type(*this->gptr()); | |
| 184 | } | ||
| 185 | else if (!traits_type::eq_int_type(__c, __eof)) { | ||
| 184 | } else if (!traits_type::eq_int_type(__c, __eof)) { | ||
| 186 | 185 | // Are we in the putback buffer already? | |
| 187 | 186 | _CharT* __pback_end = _M_pback_buf + __STATIC_CAST(int,_S_pback_buf_size); | |
| 188 | if (_M_in_putback_mode) { | ||
| 187 | if ( int_flags_ & _in_putback_mode ) { | ||
| 189 | 188 | // Do we have more room in the putback buffer? | |
| 190 | if (this->eback() != _M_pback_buf) | ||
| 189 | if (this->eback() != _M_pback_buf) { | ||
| 191 | 190 | this->setg(this->egptr() - 1, this->egptr() - 1, __pback_end); | |
| 192 | else | ||
| 191 | } else { | ||
| 193 | 192 | return __eof; // No more room in the buffer, so fail. | |
| 194 | } | ||
| 195 | else { // We're not yet in the putback buffer. | ||
| 193 | } | ||
| 194 | } else { // We're not yet in the putback buffer. | ||
| 196 | 195 | _M_saved_eback = this->eback(); | |
| 197 | 196 | _M_saved_gptr = this->gptr(); | |
| 198 | 197 | _M_saved_egptr = this->egptr(); | |
| 199 | 198 | this->setg(__pback_end - 1, __pback_end - 1, __pback_end); | |
| 200 | _M_in_putback_mode = true; | ||
| 199 | int_flags_ |= _in_putback_mode; | ||
| 201 | 200 | } | |
| 202 | } | ||
| 203 | else | ||
| 201 | } else { | ||
| 204 | 202 | return __eof; | |
| 203 | } | ||
| 205 | 204 | ||
| 206 | 205 | // We have made a putback position available. Assign to it, and return. | |
| 207 | 206 | *this->gptr() = traits_type::to_char_type(__c); | |
| … | … | ||
| 214 | 214 | // the base class only sees [_M_int_buf, _M_int_buf_EOS - 1). | |
| 215 | 215 | template <class _CharT, class _Traits> | |
| 216 | 216 | __BF_int_type__ | |
| 217 | basic_filebuf<_CharT, _Traits>::overflow(int_type __c) { | ||
| 217 | basic_filebuf<_CharT, _Traits>::overflow(int_type __c) | ||
| 218 | { | ||
| 218 | 219 | // Switch to output mode, if necessary. | |
| 219 | if (!_M_in_output_mode) | ||
| 220 | if (!_M_switch_to_output_mode()) | ||
| 220 | if ( (int_flags_ & _in_output_mode) == 0 ) { | ||
| 221 | if ( !_M_switch_to_output_mode() ) { | ||
| 221 | 222 | return traits_type::eof(); | |
| 223 | } | ||
| 224 | } | ||
| 222 | 225 | ||
| 223 | 226 | _CharT* __ibegin = this->_M_int_buf; | |
| 224 | 227 | _CharT* __iend = this->pptr(); | |
| … | … | ||
| 231 | 231 | if (!traits_type::eq_int_type(__c, traits_type::eof())) | |
| 232 | 232 | *__iend++ = _Traits::to_char_type(__c); | |
| 233 | 233 | ||
| 234 | const _CharT* __inext; | ||
| 235 | char* __enext; | ||
| 236 | typename _Codecvt::result __status; | ||
| 237 | |||
| 234 | 238 | // For variable-width encodings, output may take more than one pass. | |
| 235 | while (__ibegin != __iend) { | ||
| 236 | const _CharT* __inext = __ibegin; | ||
| 237 | char* __enext = _M_ext_buf; | ||
| 238 | typename _Codecvt::result __status | ||
| 239 | = _M_codecvt->out(_M_state, __ibegin, __iend, __inext, | ||
| 240 | _M_ext_buf, _M_ext_buf_EOS, __enext); | ||
| 239 | while ( __ibegin != __iend ) { | ||
| 240 | __inext = __ibegin; | ||
| 241 | __enext = _M_ext_buf; | ||
| 242 | __status = _M_codecvt->out(_M_state, __ibegin, __iend, __inext, | ||
| 243 | _M_ext_buf, _M_ext_buf_EOS, __enext); | ||
| 241 | 244 | if (__status == _Codecvt::noconv) { | |
| 242 | 245 | return _Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend) | |
| 243 | 246 | ? traits_type::not_eof(__c) | |
| … | … | ||
| 255 | 255 | else if (__status != _Codecvt::error && | |
| 256 | 256 | (((__inext == __iend) && | |
| 257 | 257 | (__enext - _M_ext_buf == _M_width * (__iend - __ibegin))) || | |
| 258 | (!_M_constant_width && __inext != __ibegin))) { | ||
| 258 | ( ((int_flags_ & _constant_width) == 0) && __inext != __ibegin))) { | ||
| 259 | 259 | // We successfully converted part or all of the internal buffer. | |
| 260 | 260 | ptrdiff_t __n = __enext - _M_ext_buf; | |
| 261 | if (_M_write(_M_ext_buf, __n)) | ||
| 261 | if (_M_write(_M_ext_buf, __n)) { | ||
| 262 | 262 | __ibegin += __inext - __ibegin; | |
| 263 | else | ||
| 263 | } else { | ||
| 264 | 264 | return _M_output_error(); | |
| 265 | } | ||
| 266 | else | ||
| 265 | } | ||
| 266 | } else { | ||
| 267 | 267 | return _M_output_error(); | |
| 268 | } | ||
| 268 | 269 | } | |
| 269 | 270 | ||
| 270 | 271 | return traits_type::not_eof(__c); | |
| … | … | ||
| 281 | 281 | // size is at least __n. | |
| 282 | 282 | template <class _CharT, class _Traits> | |
| 283 | 283 | basic_streambuf<_CharT, _Traits>* | |
| 284 | basic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n) { | ||
| 285 | if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode && | ||
| 286 | _M_int_buf == 0) { | ||
| 287 | if (__buf == 0 && __n == 0) | ||
| 284 | basic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n) | ||
| 285 | { | ||
| 286 | if ( ((int_flags_ & (_in_input_mode | _in_output_mode | _in_error_mode)) == 0) && | ||
| 287 | (_M_int_buf == 0) ) { | ||
| 288 | if ((__buf == 0) && (__n == 0)) { | ||
| 288 | 289 | _M_allocate_buffers(0, 1); | |
| 289 | else if (__buf != 0 && __n > 0) | ||
| 290 | } else if (__buf != 0 && __n > 0) { | ||
| 290 | 291 | _M_allocate_buffers(__buf, __n); | |
| 292 | } | ||
| 291 | 293 | } | |
| 292 | 294 | return this; | |
| 293 | 295 | } | |
| … | … | ||
| 312 | 312 | if (!this->is_open()) | |
| 313 | 313 | return pos_type(-1); | |
| 314 | 314 | ||
| 315 | if (!_M_constant_width && __off != 0) | ||
| 315 | if ( ((int_flags_ & _constant_width) == 0) && (__off != 0) ) { | ||
| 316 | 316 | return pos_type(-1); | |
| 317 | } | ||
| 317 | 318 | ||
| 318 | 319 | if (!_M_seek_init(__off != 0 || __whence != ios_base::cur)) | |
| 319 | 320 | return pos_type(-1); | |
| … | … | ||
| 326 | 326 | ||
| 327 | 327 | // Seek relative to current position. Complicated if we're in input mode. | |
| 328 | 328 | _STLP_ASSERT(__whence == ios_base::cur) | |
| 329 | if (!_M_in_input_mode) | ||
| 330 | return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), | ||
| 331 | _State_type()); | ||
| 329 | if ( ((int_flags_ & _in_input_mode) == 0) ) { | ||
| 330 | return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), _State_type()); | ||
| 331 | } | ||
| 332 | 332 | ||
| 333 | 333 | if (_M_mmap_base != 0) { | |
| 334 | 334 | // __off is relative to gptr(). We need to do a bit of arithmetic | |
| … | … | ||
| 340 | 340 | : _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type()); | |
| 341 | 341 | } | |
| 342 | 342 | ||
| 343 | if (_M_constant_width) { // Get or set the position. | ||
| 343 | if ( (int_flags_ & _constant_width) ) { // Get or set the position. | ||
| 344 | 344 | streamoff __iadj = _M_width * (this->gptr() - this->eback()); | |
| 345 | 345 | ||
| 346 | 346 | // Compensate for offset relative to gptr versus offset relative | |
| … | … | ||
| 354 | 354 | return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj) | |
| 355 | 355 | : _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type()); | |
| 356 | 356 | } | |
| 357 | } | ||
| 358 | else { // Get the position. Encoding is var width. | ||
| 357 | } else { // Get the position. Encoding is var width. | ||
| 359 | 358 | // Get position in internal buffer. | |
| 360 | 359 | ptrdiff_t __ipos = this->gptr() - this->eback(); | |
| 361 | 360 | ||
| … | … | ||
| 417 | 417 | ||
| 418 | 418 | ||
| 419 | 419 | template <class _CharT, class _Traits> | |
| 420 | int basic_filebuf<_CharT, _Traits>::sync() { | ||
| 421 | if (_M_in_output_mode) | ||
| 420 | int basic_filebuf<_CharT, _Traits>::sync() | ||
| 421 | { | ||
| 422 | if ( int_flags_ & _in_output_mode ) { | ||
| 422 | 423 | return traits_type::eq_int_type(this->overflow(traits_type::eof()), | |
| 423 | 424 | traits_type::eof()) ? -1 : 0; | |
| 425 | } | ||
| 424 | 426 | return 0; | |
| 425 | 427 | } | |
| 426 | 428 | ||
| … | … | ||
| 430 | 430 | // Change the filebuf's locale. This member function has no effect | |
| 431 | 431 | // unless it is called before any I/O is performed on the stream. | |
| 432 | 432 | template <class _CharT, class _Traits> | |
| 433 | void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) { | ||
| 434 | if (!_M_in_input_mode && !_M_in_output_mode && !_M_in_error_mode) { | ||
| 433 | void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) | ||
| 434 | { | ||
| 435 | if ( (int_flags_ & (_in_input_mode | _in_output_mode | _in_error_mode)) == 0 ) { | ||
| 435 | 436 | this->_M_setup_codecvt(__loc); | |
| 436 | 437 | } | |
| 437 | 438 | } | |
| … | … | ||
| 447 | 447 | // operation on a filebuf, or if we're performing an input operation | |
| 448 | 448 | // immediately after a seek. | |
| 449 | 449 | template <class _CharT, class _Traits> | |
| 450 | bool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode() { | ||
| 451 | if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) !=0) | ||
| 452 | && (_M_in_output_mode == 0) && (_M_in_error_mode == 0)) { | ||
| 453 | if (!_M_int_buf && !_M_allocate_buffers()) | ||
| 450 | bool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode() | ||
| 451 | { | ||
| 452 | if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) != 0) | ||
| 453 | && ( (int_flags_ & (/* _in_output_mode | */ _in_error_mode)) == 0 ) ) { | ||
| 454 | if (!_M_int_buf && !_M_allocate_buffers()) { | ||
| 454 | 455 | return false; | |
| 456 | } | ||
| 455 | 457 | ||
| 456 | 458 | _M_ext_buf_converted = _M_ext_buf; | |
| 457 | 459 | _M_ext_buf_end = _M_ext_buf; | |
| 458 | 460 | ||
| 459 | _M_end_state = _M_state; | ||
| 461 | _M_end_state = _M_state; | ||
| 462 | int_flags_ |= _in_input_mode; | ||
| 460 | 463 | ||
| 461 | _M_in_input_mode = true; | ||
| 462 | 464 | return true; | |
| 463 | 465 | } | |
| 464 | 466 | ||
| … | … | ||
| 472 | 472 | // operation on a filebuf, or if we're performing an output operation | |
| 473 | 473 | // immediately after a seek. | |
| 474 | 474 | template <class _CharT, class _Traits> | |
| 475 | bool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode() { | ||
| 476 | if (this->is_open() && (_M_base.__o_mode() & (int)ios_base::out) && | ||
| 477 | _M_in_input_mode == 0 && _M_in_error_mode == 0) { | ||
| 475 | bool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode() | ||
| 476 | { | ||
| 477 | if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::out) != 0) | ||
| 478 | && ( (int_flags_ & (/* _in_input_mode | */ _in_error_mode)) == 0 ) ) { | ||
| 478 | 479 | ||
| 479 | if (!_M_int_buf && !_M_allocate_buffers()) | ||
| 480 | if (!_M_int_buf && !_M_allocate_buffers()) { | ||
| 480 | 481 | return false; | |
| 482 | } | ||
| 481 | 483 | ||
| 482 | 484 | // In append mode, every write does an implicit seek to the end | |
| 483 | 485 | // of the file. Whenever leaving output mode, the end of file | |
| 484 | 486 | // get put in the initial shift state. | |
| 485 | if (_M_base.__o_mode() & ios_base::app) | ||
| 487 | if (_M_base.__o_mode() & ios_base::app) { | ||
| 486 | 488 | _M_state = _State_type(); | |
| 489 | } | ||
| 487 | 490 | ||
| 488 | 491 | this->setp(_M_int_buf, _M_int_buf_EOS - 1); | |
| 489 | _M_in_output_mode = true; | ||
| 492 | int_flags_ |= _in_output_mode; | ||
| 493 | |||
| 490 | 494 | return true; | |
| 491 | 495 | } | |
| 492 | 496 | ||
| … | … | ||
| 509 | 509 | ||
| 510 | 510 | template <class _CharT, class _Traits> | |
| 511 | 511 | __BF_int_type__ | |
| 512 | basic_filebuf<_CharT, _Traits>::_M_input_error() { | ||
| 513 | this->_M_exit_input_mode(); | ||
| 514 | _M_in_output_mode = false; | ||
| 515 | _M_in_error_mode = true; | ||
| 512 | basic_filebuf<_CharT, _Traits>::_M_input_error() | ||
| 513 | { | ||
| 514 | this->_M_exit_input_mode(); | ||
| 515 | int_flags_ |= _in_error_mode; | ||
| 516 | int_flags_ &= ~_in_output_mode; | ||
| 516 | 517 | this->setg(0, 0, 0); | |
| 518 | |||
| 517 | 519 | return traits_type::eof(); | |
| 518 | 520 | } | |
| 519 | 521 | ||
| … | … | ||
| 577 | 577 | return _Noconv_input<_Traits>::_M_doit(this); | |
| 578 | 578 | else if (__status == _Codecvt::error || | |
| 579 | 579 | (__inext != _M_int_buf && __enext == _M_ext_buf) || | |
| 580 | (_M_constant_width && (__inext - _M_int_buf) * _M_width != (__enext - _M_ext_buf)) || | ||
| 580 | ( ((int_flags_ & _constant_width) != 0) && (__inext - _M_int_buf) * _M_width != (__enext - _M_ext_buf)) || | ||
| 581 | 581 | (__inext == _M_int_buf && __enext - _M_ext_buf >= _M_max_width)) | |
| 582 | 582 | return _M_input_error(); | |
| 583 | 583 | else if (__inext != _M_int_buf) { | |
| … | … | ||
| 605 | 605 | // seek. | |
| 606 | 606 | template <class _CharT, class _Traits> | |
| 607 | 607 | __BF_int_type__ | |
| 608 | basic_filebuf<_CharT, _Traits>::_M_output_error() { | ||
| 609 | _M_in_output_mode = false; | ||
| 610 | _M_in_input_mode = false; | ||
| 611 | _M_in_error_mode = true; | ||
| 608 | basic_filebuf<_CharT, _Traits>::_M_output_error() | ||
| 609 | { | ||
| 610 | int_flags_ &= ~(_in_output_mode | _in_input_mode); | ||
| 611 | int_flags_ |= _in_error_mode; | ||
| 612 | 612 | this->setp(0, 0); | |
| 613 | |||
| 613 | 614 | return traits_type::eof(); | |
| 614 | 615 | } | |
| 615 | 616 | ||
| … | … | ||
| 620 | 620 | // buffer, changes the external file position, and changes the state. | |
| 621 | 621 | // Precondition: the internal buffer is empty. | |
| 622 | 622 | template <class _CharT, class _Traits> | |
| 623 | bool basic_filebuf<_CharT, _Traits>::_M_unshift() { | ||
| 624 | if (_M_in_output_mode && !_M_constant_width) { | ||
| 623 | bool basic_filebuf<_CharT, _Traits>::_M_unshift() | ||
| 624 | { | ||
| 625 | if ( ((int_flags_ & _in_output_mode) != 0) && ((int_flags_ & _constant_width) == 0) ) { | ||
| 625 | 626 | typename _Codecvt::result __status; | |
| 627 | char* __enext; | ||
| 626 | 628 | do { | |
| 627 | char* __enext = _M_ext_buf; | ||
| 629 | __enext = _M_ext_buf; | ||
| 628 | 630 | __status = _M_codecvt->unshift(_M_state, | |
| 629 | 631 | _M_ext_buf, _M_ext_buf_EOS, __enext); | |
| 630 | 632 | if (__status == _Codecvt::noconv || | |
| … | … | ||
| 674 | 674 | (__bufsize > __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) | |
| 675 | 675 | return false; | |
| 676 | 676 | _M_int_buf = __STATIC_CAST(_CharT*, malloc(__STATIC_CAST(size_t, __bufsize))); | |
| 677 | if (!_M_int_buf) | ||
| 677 | if ( !_M_int_buf ) { | ||
| 678 | 678 | return false; | |
| 679 | _M_int_buf_dynamic = true; | ||
| 680 | } | ||
| 681 | else { | ||
| 679 | } | ||
| 680 | int_flags_ |= _int_buf_dynamic; | ||
| 681 | } else { | ||
| 682 | 682 | _M_int_buf = __buf; | |
| 683 | _M_int_buf_dynamic = false; | ||
| 683 | int_flags_ &= ~_int_buf_dynamic; | ||
| 684 | 684 | } | |
| 685 | 685 | ||
| 686 | 686 | streamsize __ebufsiz = (max)(__n * __STATIC_CAST(streamsize, _M_width), | |
| … | … | ||
| 715 | 715 | ||
| 716 | 716 | template <class _CharT, class _Traits> | |
| 717 | 717 | void basic_filebuf<_CharT, _Traits>::_M_deallocate_buffers() { | |
| 718 | if (_M_int_buf_dynamic) | ||
| 718 | if ( int_flags_ & _int_buf_dynamic ) { | ||
| 719 | 719 | free(_M_int_buf); | |
| 720 | } | ||
| 720 | 721 | free(_M_ext_buf); | |
| 721 | 722 | _M_int_buf = 0; | |
| 722 | 723 | _M_int_buf_EOS = 0; | |
| … | … | ||
| 730 | 730 | // Helper functiosn for seek and imbue | |
| 731 | 731 | ||
| 732 | 732 | template <class _CharT, class _Traits> | |
| 733 | bool basic_filebuf<_CharT, _Traits>::_M_seek_init(bool __do_unshift) { | ||
| 733 | bool basic_filebuf<_CharT, _Traits>::_M_seek_init(bool __do_unshift) | ||
| 734 | { | ||
| 734 | 735 | // If we're in error mode, leave it. | |
| 735 | _M_in_error_mode = false; | ||
| 736 | int_flags_ &= ~_in_error_mode; | ||
| 736 | 737 | ||
| 737 | 738 | // Flush the output buffer if we're in output mode, and (conditionally) | |
| 738 | 739 | // emit an unshift sequence. | |
| 739 | if (_M_in_output_mode) { | ||
| 740 | if ( int_flags_ & _in_output_mode ) { | ||
| 740 | 741 | bool __ok = !traits_type::eq_int_type(this->overflow(traits_type::eof()), | |
| 741 | 742 | traits_type::eof()); | |
| 742 | if (__do_unshift) | ||
| 743 | if (__do_unshift) { | ||
| 743 | 744 | __ok = __ok && this->_M_unshift(); | |
| 745 | } | ||
| 744 | 746 | if (!__ok) { | |
| 745 | _M_in_output_mode = false; | ||
| 746 | _M_in_error_mode = true; | ||
| 747 | int_flags_ &= ~_in_output_mode; | ||
| 748 | int_flags_ |= _in_error_mode; | ||
| 747 | 749 | this->setp(0, 0); | |
| 750 | |||
| 748 | 751 | return false; | |
| 749 | 752 | } | |
| 750 | 753 | } | |
| 751 | 754 | ||
| 752 | 755 | // Discard putback characters, if any. | |
| 753 | if (_M_in_input_mode && _M_in_putback_mode) | ||
| 756 | if ( (int_flags_ & (_in_input_mode | _in_putback_mode) ) == (_in_input_mode | _in_putback_mode) ) { | ||
| 754 | 757 | _M_exit_putback_mode(); | |
| 758 | } | ||
| 755 | 759 | ||
| 756 | 760 | return true; | |
| 757 | 761 | } | |
| … | … | ||
| 769 | 769 | * The user will have to call imbue before any I/O operation. | |
| 770 | 770 | */ | |
| 771 | 771 | template <class _CharT, class _Traits> | |
| 772 | void basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc, bool __on_imbue) { | ||
| 772 | void basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc, bool __on_imbue) | ||
| 773 | { | ||
| 773 | 774 | if (has_facet<_Codecvt>(__loc)) { | |
| 774 | 775 | _M_codecvt = &use_facet<_Codecvt>(__loc) ; | |
| 775 | 776 | int __encoding = _M_codecvt->encoding(); | |
| 776 | 777 | ||
| 777 | 778 | _M_width = (max)(__encoding, 1); | |
| 778 | 779 | _M_max_width = _M_codecvt->max_length(); | |
| 779 | _M_constant_width = __encoding > 0; | ||
| 780 | _M_always_noconv = _M_codecvt->always_noconv(); | ||
| 781 | } | ||
| 782 | else { | ||
| 780 | |||
| 781 | int_flags_ = __encoding > 0 ? (int_flags_ | _constant_width) : (int_flags_ & ~_constant_width); | ||
| 782 | int_flags_ = _M_codecvt->always_noconv() ? (int_flags_ | _always_noconv) : (int_flags_ & ~_always_noconv); | ||
| 783 | } else { | ||
| 783 | 784 | _M_codecvt = 0; | |
| 784 | 785 | _M_width = _M_max_width = 1; | |
| 785 | _M_constant_width = _M_always_noconv = false; | ||
| 786 | int_flags_ &= ~(_constant_width | _always_noconv); | ||
| 786 | 787 | if (__on_imbue) { | |
| 787 | 788 | //This call will generate an exception reporting the problem. | |
| 788 | 789 | use_facet<_Codecvt>(__loc); |
stlport/stl/_fstream.h
(37 / 35)
|   | |||
| 224 | 224 | virtual int sync(); | |
| 225 | 225 | virtual void imbue(const locale&); | |
| 226 | 226 | ||
| 227 | private: // Helper functions. | ||
| 227 | private: // Helper functions. | ||
| 228 | 228 | ||
| 229 | // Precondition: we are currently in putback input mode. Effect: | ||
| 230 | // switches back to ordinary input mode. | ||
| 231 | void _M_exit_putback_mode() { | ||
| 232 | this->setg(_M_saved_eback, _M_saved_gptr, _M_saved_egptr); | ||
| 233 | _M_in_putback_mode = false; | ||
| 234 | } | ||
| 229 | // Precondition: we are currently in putback input mode. Effect: | ||
| 230 | // switches back to ordinary input mode. | ||
| 231 | void _M_exit_putback_mode() | ||
| 232 | { | ||
| 233 | this->setg(_M_saved_eback, _M_saved_gptr, _M_saved_egptr); | ||
| 234 | int_flags_ &= ~_in_putback_mode; | ||
| 235 | } | ||
| 235 | 236 | bool _M_switch_to_input_mode(); | |
| 236 | 237 | void _M_exit_input_mode(); | |
| 237 | 238 | bool _M_switch_to_output_mode(); | |
| … | … | ||
| 248 | 248 | bool _M_allocate_buffers(); | |
| 249 | 249 | void _M_deallocate_buffers(); | |
| 250 | 250 | ||
| 251 | pos_type _M_seek_return(off_type __off, _State_type __state) { | ||
| 252 | if (__off != -1) { | ||
| 253 | if (_M_in_input_mode) | ||
| 254 | _M_exit_input_mode(); | ||
| 255 | _M_in_input_mode = false; | ||
| 256 | _M_in_output_mode = false; | ||
| 257 | _M_in_putback_mode = false; | ||
| 258 | _M_in_error_mode = false; | ||
| 259 | this->setg(0, 0, 0); | ||
| 260 | this->setp(0, 0); | ||
| 261 | } | ||
| 251 | pos_type _M_seek_return(off_type __off, _State_type __state) | ||
| 252 | { | ||
| 253 | if (__off != -1) { | ||
| 254 | if ( int_flags_ & _in_input_mode ) { | ||
| 255 | _M_exit_input_mode(); | ||
| 256 | } | ||
| 257 | int_flags_ &= ~(_in_input_mode | _in_output_mode | _in_putback_mode | _in_error_mode ); | ||
| 258 | this->setg(0, 0, 0); | ||
| 259 | this->setp(0, 0); | ||
| 260 | } | ||
| 262 | 261 | ||
| 263 | pos_type __result(__off); | ||
| 264 | __result.state(__state); | ||
| 265 | return __result; | ||
| 266 | } | ||
| 262 | pos_type __result(__off); | ||
| 263 | __result.state(__state); | ||
| 264 | return __result; | ||
| 265 | } | ||
| 267 | 266 | ||
| 268 | 267 | bool _M_seek_init(bool __do_unshift); | |
| 269 | 268 | ||
| … | … | ||
| 274 | 274 | ||
| 275 | 275 | private: // Locale-related information. | |
| 276 | 276 | ||
| 277 | unsigned char _M_constant_width; | ||
| 278 | unsigned char _M_always_noconv; | ||
| 277 | enum { | ||
| 278 | _constant_width = 0x1, | ||
| 279 | _always_noconv = 0x2, | ||
| 280 | _int_buf_dynamic = 0x4, // set if internal buffer is heap allocated, | ||
| 281 | // unset if it was supplied by the user; | ||
| 282 | _in_input_mode = 0x8, | ||
| 283 | _in_output_mode = 0x10, | ||
| 284 | _in_error_mode = 0x20, | ||
| 285 | _in_putback_mode = 0x40 | ||
| 286 | }; | ||
| 279 | 287 | ||
| 280 | // private: // Mode flags. | ||
| 281 | unsigned char _M_int_buf_dynamic; // True if internal buffer is heap allocated, | ||
| 282 | // false if it was supplied by the user. | ||
| 283 | unsigned char _M_in_input_mode; | ||
| 284 | unsigned char _M_in_output_mode; | ||
| 285 | unsigned char _M_in_error_mode; | ||
| 286 | unsigned char _M_in_putback_mode; | ||
| 288 | unsigned int_flags_; | ||
| 287 | 289 | ||
| 288 | 290 | // Internal buffer: characters seen by the filebuf's clients. | |
| 289 | 291 | _CharT* _M_int_buf; | |
| … | … | ||
| 419 | 419 | // There is a specialized version of underflow, for basic_filebuf<char>, | |
| 420 | 420 | // in fstream.cpp. | |
| 421 | 421 | static int_type _STLP_CALL _M_doit(basic_filebuf<_CharT, _Traits>* __this) { | |
| 422 | if (!__this->_M_in_input_mode) { | ||
| 423 | if (!__this->_M_switch_to_input_mode()) | ||
| 422 | if ( (__this->int_flags_ & basic_filebuf<_CharT, _Traits>::_in_input_mode) == 0) { | ||
| 423 | if (!__this->_M_switch_to_input_mode()) { | ||
| 424 | 424 | return traits_type::eof(); | |
| 425 | } | ||
| 426 | else if (__this->_M_in_putback_mode) { | ||
| 425 | } | ||
| 426 | } else if ( __this->int_flags_ & basic_filebuf<_CharT, _Traits>::_in_putback_mode ) { | ||
| 427 | 427 | __this->_M_exit_putback_mode(); | |
| 428 | 428 | if (__this->gptr() != __this->egptr()) { | |
| 429 | 429 | int_type __c = traits_type::to_int_type(*__this->gptr()); |
test/unit/fstream_test.cpp
(49 / 1)
|   | |||
| 1 | // -*- C++ -*- Time-stamp: <09/01/28 14:38:25 ptr> | ||
| 1 | // -*- C++ -*- Time-stamp: <09/10/22 23:31:10 ptr> | ||
| 2 | 2 | ||
| 3 | 3 | /* | |
| 4 | 4 | * Copyright (c) 2004-2008 | |
| … | … | ||
| 25 | 25 | #include <stdexcept> | |
| 26 | 26 | #include <stdio.h> | |
| 27 | 27 | ||
| 28 | #ifdef __unix__ | ||
| 29 | #include <unistd.h> | ||
| 30 | #endif | ||
| 31 | |||
| 28 | 32 | #include "full_streambuf.h" | |
| 29 | 33 | ||
| 30 | 34 | #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) | |
| … | … | ||
| 297 | 297 | EXAM_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(10) ); | |
| 298 | 298 | EXAM_CHECK( o.tellp() == ofstream::pos_type(10) ); | |
| 299 | 299 | } | |
| 300 | |||
| 301 | return EXAM_RESULT; | ||
| 302 | } | ||
| 303 | |||
| 304 | int EXAM_IMPL(fstream_test::rewind) | ||
| 305 | { | ||
| 306 | #ifdef __unix__ | ||
| 307 | const char fname[] = "/tmp/stlport.test"; | ||
| 308 | { | ||
| 309 | fstream f( fname, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary ); | ||
| 310 | |||
| 311 | int n = 0; | ||
| 312 | |||
| 313 | EXAM_CHECK( f.is_open() ); | ||
| 314 | EXAM_CHECK( f.good() ); | ||
| 315 | |||
| 316 | f.write( (const char*)&n, sizeof(int) ); | ||
| 317 | EXAM_CHECK( f.good() ); | ||
| 318 | f.seekg( sizeof(int), ios_base::beg ); | ||
| 319 | EXAM_CHECK( f.good() ); | ||
| 320 | f.read( (char *)&n, sizeof(int) ); | ||
| 321 | EXAM_CHECK( f.fail() ); | ||
| 322 | f.clear(); | ||
| 323 | EXAM_CHECK( f.good() ); | ||
| 324 | n = 0; | ||
| 325 | f.write( (const char*)&n, sizeof(int) ); | ||
| 326 | EXAM_CHECK( f.good() ); | ||
| 327 | } | ||
| 328 | { | ||
| 329 | ifstream f( fname ); | ||
| 330 | char c = -1; | ||
| 331 | for ( int i = 0; i < 2 * sizeof(int); ++i ) { | ||
| 332 | f.get( c ); | ||
| 333 | EXAM_CHECK( !f.fail() ); | ||
| 334 | EXAM_CHECK( c == '\0' ); | ||
| 335 | } | ||
| 336 | f.get( c ); | ||
| 337 | EXAM_CHECK( f.fail() ); | ||
| 338 | } | ||
| 339 | |||
| 340 | unlink( fname ); | ||
| 341 | #else | ||
| 342 | throw exam::skip_exception(); | ||
| 343 | #endif | ||
| 300 | 344 | ||
| 301 | 345 | return EXAM_RESULT; | |
| 302 | 346 | } |
test/unit/stream_test.h
(2 / 1)
|   | |||
| 1 | // -*- C++ -*- Time-stamp: <09/04/03 17:06:37 ptr> | ||
| 1 | // -*- C++ -*- Time-stamp: <09/10/16 22:15:32 ptr> | ||
| 2 | 2 | ||
| 3 | 3 | /* | |
| 4 | 4 | * Copyright (c) 2004-2008 | |
| … | … | ||
| 61 | 61 | int EXAM_DECL(seek_binary); | |
| 62 | 62 | int EXAM_DECL(seek_text); | |
| 63 | 63 | int EXAM_DECL(seek_wide_stream); | |
| 64 | int EXAM_DECL(rewind); | ||
| 64 | 65 | int EXAM_DECL(buf); | |
| 65 | 66 | int EXAM_DECL(rdbuf); | |
| 66 | 67 | int EXAM_DECL(streambuf_output); |
test/unit/suite.cc
(4 / 2)
|   | |||
| 1 | // -*- C++ -*- Time-stamp: <09/04/21 10:28:44 ptr> | ||
| 1 | // -*- C++ -*- Time-stamp: <09/10/16 22:18:36 ptr> | ||
| 2 | 2 | ||
| 3 | 3 | /* | |
| 4 | 4 | * Copyright (c) 2008, 2009 | |
| … | … | ||
| 417 | 417 | t.add( &fstream_test::offset, fstrm_test, "fstream offset", fstream_tc[0] ); | |
| 418 | 418 | t.add( &fstream_test::big_file, fstrm_test, "fstream big_file", fstream_tc[0] ); | |
| 419 | 419 | fstream_tc[2] = t.add( &fstream_test::custom_facet, fstrm_test, "fstream custom_facet", fstream_tc[0] ); | |
| 420 | |||
| 420 | |||
| 421 | t.add( &fstream_test::rewind, fstrm_test, "fstream write after read fail", fstream_tc[1] ); | ||
| 422 | |||
| 421 | 423 | search_test sch_test; | |
| 422 | 424 | ||
| 423 | 425 | t.add( &search_test::search0, sch_test, "search0" ); |

