1.1 --- a/epoc32/include/stdapis/stlportv5/stl/_fstream.c Wed Mar 31 12:27:01 2010 +0100
1.2 +++ b/epoc32/include/stdapis/stlportv5/stl/_fstream.c Wed Mar 31 12:33:34 2010 +0100
1.3 @@ -1,16 +1,14 @@
1.4 /*
1.5 - * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
1.6 - *
1.7 * Copyright (c) 1996,1997
1.8 * Silicon Graphics Computer Systems, Inc.
1.9 *
1.10 - * Copyright (c) 1999
1.11 + * Copyright (c) 1999
1.12 * Boris Fomitchev
1.13 *
1.14 * This material is provided "as is", with absolutely no warranty expressed
1.15 * or implied. Any use is at your own risk.
1.16 *
1.17 - * Permission to use or copy this software for any purpose is hereby granted
1.18 + * Permission to use or copy this software for any purpose is hereby granted
1.19 * without fee, provided the above notices are retained on all copies.
1.20 * Permission to modify the code and to distribute modified code is granted,
1.21 * provided the above notices are retained, and a notice that the code was
1.22 @@ -20,11 +18,13 @@
1.23 #ifndef _STLP_FSTREAM_C
1.24 #define _STLP_FSTREAM_C
1.25
1.26 -# ifndef _STLP_INTERNAL_FSTREAM_H
1.27 +#ifndef _STLP_INTERNAL_FSTREAM_H
1.28 # include <stl/_fstream.h>
1.29 -# endif
1.30 +#endif
1.31
1.32 -# if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION)
1.33 +#ifndef _STLP_INTERNAL_LIMITS
1.34 +# include <stl/_limits.h>
1.35 +#endif
1.36
1.37 _STLP_BEGIN_NAMESPACE
1.38
1.39 @@ -60,7 +60,7 @@
1.40 _M_codecvt(0),
1.41 _M_width(1), _M_max_width(1)
1.42 {
1.43 - this->_M_setup_codecvt(locale());
1.44 + this->_M_setup_codecvt(locale(), false);
1.45 }
1.46
1.47 template <class _CharT, class _Traits>
1.48 @@ -71,16 +71,14 @@
1.49
1.50
1.51 template <class _CharT, class _Traits>
1.52 -_STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type
1.53 -basic_filebuf<_CharT, _Traits>::underflow()
1.54 -{
1.55 +_STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type
1.56 +basic_filebuf<_CharT, _Traits>::underflow() {
1.57 return _Underflow<_CharT, _Traits>::_M_doit(this);
1.58 }
1.59
1.60 template <class _CharT, class _Traits>
1.61 -basic_filebuf<_CharT, _Traits>*
1.62 -basic_filebuf<_CharT, _Traits>::close()
1.63 -{
1.64 +basic_filebuf<_CharT, _Traits>*
1.65 +basic_filebuf<_CharT, _Traits>::close() {
1.66 bool __ok = this->is_open();
1.67
1.68 if (_M_in_output_mode) {
1.69 @@ -102,14 +100,8 @@
1.70 _M_mmap_base = 0;
1.71 _M_mmap_len = 0;
1.72
1.73 -#ifdef __SYMBIAN32__
1.74 - if (__ok) {
1.75 -#endif // __SYMBIAN32__
1.76 this->setg(0, 0, 0);
1.77 this->setp(0, 0);
1.78 -#ifdef __SYMBIAN32__
1.79 - }
1.80 -#endif // __SYMBIAN32__
1.81
1.82 _M_saved_eback = _M_saved_gptr = _M_saved_egptr = 0;
1.83
1.84 @@ -121,12 +113,11 @@
1.85
1.86 // This member function is called whenever we exit input mode.
1.87 // It unmaps the memory-mapped file, if any, and sets
1.88 -// _M_in_input_mode to false.
1.89 +// _M_in_input_mode to false.
1.90 template <class _CharT, class _Traits>
1.91 -void basic_filebuf<_CharT, _Traits>::_M_exit_input_mode()
1.92 -{
1.93 +void basic_filebuf<_CharT, _Traits>::_M_exit_input_mode() {
1.94 if (_M_mmap_base != 0)
1.95 - _M_base._M_unmap(_M_mmap_base, _M_mmap_len);
1.96 + _M_base._M_unmap(_M_mmap_base, _M_mmap_len);
1.97 _M_in_input_mode = false;
1.98 _M_mmap_base = 0;
1.99 }
1.100 @@ -136,35 +127,23 @@
1.101 // basic_filebuf<> overridden protected virtual member functions
1.102
1.103 template <class _CharT, class _Traits>
1.104 -streamsize basic_filebuf<_CharT, _Traits>::showmanyc()
1.105 -{
1.106 +streamsize basic_filebuf<_CharT, _Traits>::showmanyc() {
1.107 // Is there any possibility that reads can succeed?
1.108 -#ifdef __SYMBIAN32__
1.109 - if (!this->is_open() || !(_M_base.__o_mode() & (int)ios_base::in) || _M_in_error_mode)
1.110 -#else
1.111 if (!this->is_open() || _M_in_output_mode || _M_in_error_mode)
1.112 -#endif
1.113 return -1;
1.114 -
1.115 else if (_M_in_putback_mode)
1.116 return this->egptr() - this->gptr();
1.117 -
1.118 else if (_M_constant_width) {
1.119 streamoff __pos = _M_base._M_seek(0, ios_base::cur);
1.120 streamoff __size = _M_base._M_file_size();
1.121 -#ifdef __SYMBIAN32__
1.122 - if(__size == 0)
1.123 - return 0;
1.124 -#endif
1.125 - return __pos >= 0 && __size > __pos ? __size - __pos : -1;
1.126 + return __pos >= 0 && __size > __pos ? __size - __pos : 0;
1.127 }
1.128 -
1.129 - else
1.130 + else
1.131 return 0;
1.132 }
1.133
1.134
1.135 -// Make a putback position available, if necessary, by switching to a
1.136 +// Make a putback position available, if necessary, by switching to a
1.137 // special internal buffer used only for putback. The buffer is
1.138 // [_M_pback_buf, _M_pback_buf + _S_pback_buf_size), but the base
1.139 // class only sees a piece of it at a time. (We want to make sure
1.140 @@ -172,9 +151,8 @@
1.141 // The end of the putback buffer is always _M_pback_buf + _S_pback_buf_size,
1.142 // but the beginning is usually not _M_pback_buf.
1.143 template <class _CharT, class _Traits>
1.144 -__BF_int_type__
1.145 -basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
1.146 -{
1.147 +__BF_int_type__
1.148 +basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
1.149 const int_type __eof = traits_type::eof();
1.150
1.151 // If we aren't already in input mode, pushback is impossible.
1.152 @@ -197,7 +175,7 @@
1.153 _CharT* __pback_end = _M_pback_buf + __STATIC_CAST(int,_S_pback_buf_size);
1.154 if (_M_in_putback_mode) {
1.155 // Do we have more room in the putback buffer?
1.156 - if (this->eback() != _M_pback_buf)
1.157 + if (this->eback() != _M_pback_buf)
1.158 this->setg(this->egptr() - 1, this->egptr() - 1, __pback_end);
1.159 else
1.160 return __eof; // No more room in the buffer, so fail.
1.161 @@ -211,45 +189,8 @@
1.162 }
1.163 }
1.164 else
1.165 - {
1.166 -#ifdef __SYMBIAN32__
1.167 - if (traits_type::eq_int_type(__c, __eof) )
1.168 - {
1.169 - if(_M_in_putback_mode)
1.170 - {
1.171 - _M_in_putback_mode = false;
1.172 - // we are at putback mode
1.173 - if(_M_saved_eback != _M_saved_gptr)
1.174 - {
1.175 - this->setg(_M_saved_eback, _M_saved_gptr - 1, _M_saved_egptr);
1.176 - return *this->gptr();
1.177 - }
1.178 - else
1.179 - this->setg(_M_saved_eback, _M_saved_gptr, _M_saved_egptr);
1.180 -
1.181 - }
1.182 - else
1.183 - {
1.184 - if(!this->eback())
1.185 - {
1.186 - streamoff __pos = _M_base._M_seek(0, ios_base::cur);
1.187 - streamoff __size = _M_base._M_file_size();
1.188 - if( __size > 0 && __pos > 0 && __pos == __size)
1.189 - __pos = _M_base._M_seek(__pos - 1, ios_base::beg);
1.190 - this->underflow();
1.191 - this->setg(this->eback(), this->gptr(), this->egptr());
1.192 - return *this->gptr();
1.193 - }
1.194 - else
1.195 - {
1.196 - this->setg(this->eback(), this->gptr() - 1, this->egptr());
1.197 - return *this->gptr();
1.198 - }
1.199 - }
1.200 - }
1.201 -#endif
1.202 return __eof;
1.203 - }
1.204 +
1.205 // We have made a putback position available. Assign to it, and return.
1.206 *this->gptr() = traits_type::to_char_type(__c);
1.207 return __c;
1.208 @@ -262,32 +203,19 @@
1.209 // the base class only sees [_M_int_buf, _M_int_buf_EOS - 1).
1.210 template <class _CharT, class _Traits>
1.211 __BF_int_type__
1.212 -basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
1.213 -{
1.214 +basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
1.215 // Switch to output mode, if necessary.
1.216 - bool putflag = false;
1.217 if (!_M_in_output_mode)
1.218 - {
1.219 -#ifdef __SYMBIAN32__
1.220 - if(this->_M_int_buf)
1.221 - putflag = true;
1.222 -#endif
1.223 if (!_M_switch_to_output_mode())
1.224 return traits_type::eof();
1.225 - }
1.226 +
1.227 _CharT* __ibegin = this->_M_int_buf;
1.228 _CharT* __iend = this->pptr();
1.229 this->setp(_M_int_buf, _M_int_buf_EOS - 1);
1.230
1.231 // Put __c at the end of the internal buffer.
1.232 if (!traits_type::eq_int_type(__c, traits_type::eof()))
1.233 - *__iend++ = __c;
1.234 -#ifdef __SYMBIAN32__
1.235 - int current_pos = this->gptr() - this->eback();
1.236 - streamoff __size = _M_base._M_file_size();
1.237 - if(current_pos > 0 && current_pos < __size && _M_base.__is_open())
1.238 - _M_base._M_seek(current_pos, ios_base::beg);
1.239 -#endif
1.240 + *__iend++ = _Traits::to_char_type(__c);
1.241
1.242 // For variable-width encodings, output may take more than one pass.
1.243 while (__ibegin != __iend) {
1.244 @@ -295,37 +223,21 @@
1.245 char* __enext = _M_ext_buf;
1.246 typename _Codecvt::result __status
1.247 = _M_codecvt->out(_M_state, __ibegin, __iend, __inext,
1.248 - _M_ext_buf, _M_ext_buf_EOS, __enext);
1.249 - if (__status == _Codecvt::noconv)
1.250 -#ifdef __SYMBIAN32__
1.251 - {
1.252 - if(_Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend))
1.253 - {
1.254 - if (this->eback())
1.255 - {
1.256 - *(this->gptr()) = __c;
1.257 - this->setg(this->eback(), this->gptr() + 1, this->egptr());
1.258 - }
1.259 - if(putflag && this->pptr() < this->epptr())
1.260 - this->setp(this->pptr() + 1, this->epptr());
1.261 - return traits_type::not_eof(__c);
1.262 - }
1.263 - else
1.264 - return _M_output_error();
1.265 - }
1.266 -#else
1.267 + _M_ext_buf, _M_ext_buf_EOS, __enext);
1.268 + if (__status == _Codecvt::noconv) {
1.269 return _Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend)
1.270 ? traits_type::not_eof(__c)
1.271 : _M_output_error();
1.272 -#endif
1.273 + }
1.274 +
1.275 // For a constant-width encoding we know that the external buffer
1.276 // is large enough, so failure to consume the entire internal buffer
1.277 // or to produce the correct number of external characters, is an error.
1.278 - // For a variable-width encoding, however, we require only that we
1.279 + // For a variable-width encoding, however, we require only that we
1.280 // consume at least one internal character
1.281 - else if (__status != _Codecvt::error &&
1.282 - ((__inext == __iend && (__enext - _M_ext_buf ==
1.283 - _M_width * (__iend - __ibegin))) ||
1.284 + else if (__status != _Codecvt::error &&
1.285 + (((__inext == __iend) &&
1.286 + (__enext - _M_ext_buf == _M_width * (__iend - __ibegin))) ||
1.287 (!_M_constant_width && __inext != __ibegin))) {
1.288 // We successfully converted part or all of the internal buffer.
1.289 ptrdiff_t __n = __enext - _M_ext_buf;
1.290 @@ -344,15 +256,14 @@
1.291 // This member function must be called before any I/O has been
1.292 // performed on the stream, otherwise it has no effect.
1.293 //
1.294 -// __buf == 0 && __n == 0 means to make ths stream unbuffered.
1.295 +// __buf == 0 && __n == 0 means to make this stream unbuffered.
1.296 // __buf != 0 && __n > 0 means to use __buf as the stream's internal
1.297 // buffer, rather than the buffer that would otherwise be allocated
1.298 // automatically. __buf must be a pointer to an array of _CharT whose
1.299 // size is at least __n.
1.300 template <class _CharT, class _Traits>
1.301 basic_streambuf<_CharT, _Traits>*
1.302 -basic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n)
1.303 -{
1.304 +basic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n) {
1.305 if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode &&
1.306 _M_int_buf == 0) {
1.307 if (__buf == 0 && __n == 0)
1.308 @@ -367,8 +278,7 @@
1.309 __BF_pos_type__
1.310 basic_filebuf<_CharT, _Traits>::seekoff(off_type __off,
1.311 ios_base::seekdir __whence,
1.312 - ios_base::openmode /* dummy */)
1.313 -{
1.314 + ios_base::openmode /* dummy */) {
1.315 if (this->is_open() &&
1.316 (__off == 0 || (_M_constant_width && this->_M_base._M_in_binary_mode()))) {
1.317
1.318 @@ -380,9 +290,8 @@
1.319 return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence),
1.320 _State_type());
1.321
1.322 - // Seek relative to current position. Complicated if we're in input mode.
1.323 + // Seek relative to current position. Complicated if we're in input mode.
1.324 else if (__whence == ios_base::cur) {
1.325 -
1.326 if (!_M_in_input_mode)
1.327 return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence),
1.328 _State_type());
1.329 @@ -392,91 +301,74 @@
1.330 streamoff __adjust = _M_mmap_len - (this->gptr() - (_CharT*) _M_mmap_base);
1.331
1.332 // if __off == 0, we do not need to exit input mode and to shift file pointer
1.333 - if (__off == 0) {
1.334 - return pos_type(_M_base._M_seek(0, ios_base::cur) - __adjust);
1.335 - }
1.336 - else
1.337 -#ifdef __SYMBIAN32__
1.338 - return _M_seek_return(_M_base._M_seek(__off, ios_base::cur), _State_type());
1.339 -#else
1.340 - return _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type());
1.341 -#endif
1.342 + return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __adjust)
1.343 + : _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type());
1.344 }
1.345 - else if (_M_constant_width) { // Get or set the position.
1.346 + else if (_M_constant_width) { // Get or set the position.
1.347 + streamoff __iadj = _M_width * (this->gptr() - this->eback());
1.348
1.349 - streamoff __iadj = _M_width * (this->gptr() - this->eback());
1.350 -
1.351 // Compensate for offset relative to gptr versus offset relative
1.352 - // to external pointer. For a text-oriented stream, where the
1.353 + // to external pointer. For a text-oriented stream, where the
1.354 // compensation is more than just pointer arithmetic, we may get
1.355 // but not set the current position.
1.356 -
1.357 +
1.358 if (__iadj <= _M_ext_buf_end - _M_ext_buf) {
1.359 -
1.360 - streamoff __eadj = _M_base._M_get_offset(_M_ext_buf + __iadj, _M_ext_buf_end);
1.361 + streamoff __eadj = _M_base._M_get_offset(_M_ext_buf + __STATIC_CAST(ptrdiff_t, __iadj), _M_ext_buf_end);
1.362
1.363 - if (__off == 0) {
1.364 - return pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj);
1.365 - } else {
1.366 - return _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type());
1.367 - }
1.368 + return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj)
1.369 + : _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type());
1.370 }
1.371 - else
1.372 - return pos_type(-1);
1.373 - }
1.374 - else { // Get the position. Encoding is var width.
1.375 + } else { // Get the position. Encoding is var width.
1.376 // Get position in internal buffer.
1.377 ptrdiff_t __ipos = this->gptr() - this->eback();
1.378 -
1.379 +
1.380 // Get corresponding position in external buffer.
1.381 _State_type __state = _M_state;
1.382 int __epos = _M_codecvt->length(__state, _M_ext_buf, _M_ext_buf_end,
1.383 __ipos);
1.384
1.385 - // Sanity check (expensive): make sure __epos is the right answer.
1.386 - _State_type __tmp_state = _M_state;
1.387 - _Filebuf_Tmp_Buf<_CharT> __buf(__ipos);
1.388 - _CharT* __ibegin = __buf._M_ptr;
1.389 - _CharT* __inext = __ibegin;
1.390 + if (__epos >= 0) {
1.391 + // Sanity check (expensive): make sure __epos is the right answer.
1.392 + _State_type __tmp_state = _M_state;
1.393 + _Filebuf_Tmp_Buf<_CharT> __buf(__ipos);
1.394 + _CharT* __ibegin = __buf._M_ptr;
1.395 + _CharT* __inext = __ibegin;
1.396
1.397 - const char* __dummy;
1.398 - typename _Codecvt::result __status
1.399 - = _M_codecvt->in(__tmp_state,
1.400 - _M_ext_buf, _M_ext_buf + __epos, __dummy,
1.401 - __ibegin, __ibegin + __ipos, __inext);
1.402 - if (__status != _Codecvt::error &&
1.403 - (__status == _Codecvt::noconv ||
1.404 - (__inext == __ibegin + __ipos &&
1.405 - equal(this->gptr(), this->eback(), __ibegin,
1.406 - _Eq_traits<traits_type>())))) {
1.407 - // Get the current position (at the end of the external buffer),
1.408 - // then adjust it. Again, it might be a text-oriented stream.
1.409 - streamoff __cur = _M_base._M_seek(0, ios_base::cur);
1.410 - streamoff __adj =
1.411 - _M_base._M_get_offset(_M_ext_buf, _M_ext_buf + __epos) -
1.412 - _M_base._M_get_offset(_M_ext_buf, _M_ext_buf_end);
1.413 - if (__cur != -1 && __cur + __adj >= 0)
1.414 - return _M_seek_return(__cur + __adj, __state);
1.415 - else
1.416 - return pos_type(-1);
1.417 + const char* __dummy;
1.418 + typename _Codecvt::result __status
1.419 + = _M_codecvt->in(__tmp_state,
1.420 + _M_ext_buf, _M_ext_buf + __epos, __dummy,
1.421 + __ibegin, __ibegin + __ipos, __inext);
1.422 + if (__status != _Codecvt::error &&
1.423 + (__status == _Codecvt::noconv ||
1.424 + (__inext == __ibegin + __ipos &&
1.425 + equal(this->eback(), this->gptr(), __ibegin, _STLP_PRIV _Eq_traits<traits_type>())))) {
1.426 + // Get the current position (at the end of the external buffer),
1.427 + // then adjust it. Again, it might be a text-oriented stream.
1.428 + streamoff __cur = _M_base._M_seek(0, ios_base::cur);
1.429 + streamoff __adj =
1.430 + _M_base._M_get_offset(_M_ext_buf, _M_ext_buf + __epos) -
1.431 + _M_base._M_get_offset(_M_ext_buf, _M_ext_buf_end);
1.432 + if (__cur != -1 && __cur + __adj >= 0)
1.433 + return __off == 0 ? pos_type(__cur + __adj)
1.434 + : _M_seek_return(__cur + __adj, __state);
1.435 + //return _M_seek_return(__cur + __adj, __state);
1.436 + }
1.437 + // We failed the sanity check here.
1.438 }
1.439 - else // We failed the sanity check.
1.440 - return pos_type(-1);
1.441 }
1.442 }
1.443 - else // Unrecognized value for __whence.
1.444 - return pos_type(-1);
1.445 + // Unrecognized value for __whence here.
1.446 }
1.447 - else
1.448 - return pos_type(-1);
1.449 +
1.450 + return pos_type(-1);
1.451 }
1.452
1.453
1.454 template <class _CharT, class _Traits>
1.455 __BF_pos_type__
1.456 basic_filebuf<_CharT, _Traits>::seekpos(pos_type __pos,
1.457 - ios_base::openmode /* dummy */)
1.458 -{
1.459 + ios_base::openmode /* dummy */) {
1.460 if (this->is_open()) {
1.461 if (!_M_seek_init(true))
1.462 return pos_type(-1);
1.463 @@ -486,33 +378,26 @@
1.464 _M_state = __pos.state();
1.465 return _M_seek_return(__off, __pos.state());
1.466 }
1.467 - else
1.468 - return pos_type(-1);
1.469 }
1.470 - else
1.471 - return pos_type(-1);
1.472 +
1.473 + return pos_type(-1);
1.474 }
1.475
1.476
1.477 template <class _CharT, class _Traits>
1.478 -int basic_filebuf<_CharT, _Traits>::sync()
1.479 -{
1.480 +int basic_filebuf<_CharT, _Traits>::sync() {
1.481 if (_M_in_output_mode)
1.482 return traits_type::eq_int_type(this->overflow(traits_type::eof()),
1.483 - traits_type::eof())
1.484 - ? -1
1.485 - : 0;
1.486 - else
1.487 - return 0;
1.488 + traits_type::eof()) ? -1 : 0;
1.489 + return 0;
1.490 }
1.491
1.492
1.493 // Change the filebuf's locale. This member function has no effect
1.494 // unless it is called before any I/O is performed on the stream.
1.495 template <class _CharT, class _Traits>
1.496 -void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
1.497 -{
1.498 - if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode) {
1.499 +void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
1.500 + if (!_M_in_input_mode && !_M_in_output_mode && !_M_in_error_mode) {
1.501 this->_M_setup_codecvt(__loc);
1.502 }
1.503 }
1.504 @@ -524,27 +409,13 @@
1.505 // Helper functions for switching between modes.
1.506
1.507 // This member function is called if we're performing the first I/O
1.508 -// operation on a filebuf, or if we're performing an input operation
1.509 +// operation on a filebuf, or if we're performing an input operation
1.510 // immediately after a seek.
1.511 template <class _CharT, class _Traits>
1.512 -bool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode()
1.513 -{
1.514 -
1.515 - if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) !=0)
1.516 -#ifndef __SYMBIAN32__
1.517 - && (_M_in_output_mode == 0)
1.518 -#endif
1.519 - && (_M_in_error_mode == 0)) {
1.520 -#ifdef __STLP_NO_WRITE_SIDE_BUFFERING__
1.521 - // If file has been opened in input|output mode
1.522 - if ((((int)_M_base.__o_mode() & (int)ios_base::out) !=0)
1.523 -#ifndef __SYMBIAN32__
1.524 - && sync()
1.525 -#endif
1.526 - && !_M_int_buf && !_M_allocate_buffers(0, 1))
1.527 -#else
1.528 +bool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode() {
1.529 + if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) != 0)
1.530 + && (_M_in_output_mode == 0) && (_M_in_error_mode == 0)) {
1.531 if (!_M_int_buf && !_M_allocate_buffers())
1.532 -#endif
1.533 return false;
1.534
1.535 _M_ext_buf_converted = _M_ext_buf;
1.536 @@ -555,30 +426,20 @@
1.537 _M_in_input_mode = true;
1.538 return true;
1.539 }
1.540 - else
1.541
1.542 - return false;
1.543 + return false;
1.544 }
1.545
1.546
1.547 // This member function is called if we're performing the first I/O
1.548 -// operation on a filebuf, or if we're performing an output operation
1.549 +// operation on a filebuf, or if we're performing an output operation
1.550 // immediately after a seek.
1.551 template <class _CharT, class _Traits>
1.552 -bool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode()
1.553 -{
1.554 +bool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode() {
1.555 if (this->is_open() && (_M_base.__o_mode() & (int)ios_base::out) &&
1.556 -#ifdef __SYMBIAN32__
1.557 - _M_in_error_mode == 0) {
1.558 -#else
1.559 _M_in_input_mode == 0 && _M_in_error_mode == 0) {
1.560 -#endif //__SYMBIAN32__
1.561
1.562 -#ifdef __STLP_NO_WRITE_SIDE_BUFFERING__
1.563 - if (!_M_int_buf && !_M_allocate_buffers(0, 1))
1.564 -#else
1.565 if (!_M_int_buf && !_M_allocate_buffers())
1.566 -#endif
1.567 return false;
1.568
1.569 // In append mode, every write does an implicit seek to the end
1.570 @@ -589,11 +450,10 @@
1.571
1.572 this->setp(_M_int_buf, _M_int_buf_EOS - 1);
1.573 _M_in_output_mode = true;
1.574 -
1.575 return true;
1.576 }
1.577 - else
1.578 - return false;
1.579 +
1.580 + return false;
1.581 }
1.582
1.583
1.584 @@ -608,9 +468,8 @@
1.585
1.586 template <class _CharT, class _Traits>
1.587 __BF_int_type__
1.588 -basic_filebuf<_CharT, _Traits>::_M_input_error()
1.589 -{
1.590 - this->_M_exit_input_mode();
1.591 +basic_filebuf<_CharT, _Traits>::_M_input_error() {
1.592 + this->_M_exit_input_mode();
1.593 _M_in_output_mode = false;
1.594 _M_in_error_mode = true;
1.595 this->setg(0, 0, 0);
1.596 @@ -618,9 +477,8 @@
1.597 }
1.598
1.599 template <class _CharT, class _Traits>
1.600 -__BF_int_type__
1.601 -basic_filebuf<_CharT, _Traits>::_M_underflow_aux()
1.602 -{
1.603 +__BF_int_type__
1.604 +basic_filebuf<_CharT, _Traits>::_M_underflow_aux() {
1.605 // We have the state and file position from the end of the internal
1.606 // buffer. This round, they become the beginning of the internal buffer.
1.607 _M_state = _M_end_state;
1.608 @@ -631,33 +489,23 @@
1.609
1.610 _M_ext_buf_end = copy(_M_ext_buf_converted, _M_ext_buf_end, _M_ext_buf);
1.611 // boris : copy_backward did not work
1.612 - //_M_ext_buf_end = copy_backward(_M_ext_buf_converted, _M_ext_buf_end,
1.613 + //_M_ext_buf_end = copy_backward(_M_ext_buf_converted, _M_ext_buf_end,
1.614 //_M_ext_buf+ (_M_ext_buf_end - _M_ext_buf_converted));
1.615 else
1.616 - {
1.617 -#ifdef __SYMBIAN32__
1.618 - if(_M_ext_buf == NULL)
1.619 - _M_allocate_buffers(0, MMAP_CHUNK);
1.620 -#endif
1.621 _M_ext_buf_end = _M_ext_buf;
1.622 - }
1.623 +
1.624 // Now fill the external buffer with characters from the file. This is
1.625 - // a loop because occasonally we don't get enough external characters
1.626 + // a loop because occasionally we don't get enough external characters
1.627 // to make progress.
1.628 - while (true) {
1.629 + for (;;) {
1.630 ptrdiff_t __n = _M_base._M_read(_M_ext_buf_end, _M_ext_buf_EOS - _M_ext_buf_end);
1.631 -
1.632 +
1.633 // Don't enter error mode for a failed read. Error mode is sticky,
1.634 // and we might succeed if we try again.
1.635 -#ifdef __SYMBIAN32__ //plum hall bug 577
1.636 - int nn = (char*)_M_ext_buf_end-(char*)_M_ext_buf; //number of chars unconverted last time
1.637 - if ( (__n <= 0) && ( nn<=0 ) )
1.638 -#else
1.639 - if (__n <= 0)
1.640 -#endif
1.641 + if (__n <= 0)
1.642 return traits_type::eof();
1.643
1.644 - // Convert the external buffer to internal characters.
1.645 + // Convert the external buffer to internal characters.
1.646 _M_ext_buf_end += __n;
1.647 const char* __enext;
1.648 _CharT* __inext;
1.649 @@ -670,12 +518,11 @@
1.650 // Error conditions: (1) Return value of error. (2) Producing internal
1.651 // characters without consuming external characters. (3) In fixed-width
1.652 // encodings, producing an internal sequence whose length is inconsistent
1.653 - // with that of the internal sequence. (4) Failure to produce any
1.654 + // with that of the internal sequence. (4) Failure to produce any
1.655 // characters if we have enough characters in the external buffer, where
1.656 // "enough" means the largest possible width of a single character.
1.657 if (__status == _Codecvt::noconv)
1.658 return _Noconv_input<_Traits>::_M_doit(this);
1.659 -
1.660 else if (__status == _Codecvt::error ||
1.661 (__inext != _M_int_buf && __enext == _M_ext_buf) ||
1.662 (_M_constant_width &&
1.663 @@ -683,14 +530,13 @@
1.664 (__inext - _M_int_buf) * _M_width != (__enext - _M_ext_buf)) ||
1.665 (__inext == _M_int_buf && __enext - _M_ext_buf >= _M_max_width))
1.666 return _M_input_error();
1.667 -
1.668 else if (__inext != _M_int_buf) {
1.669 _M_ext_buf_converted = _M_ext_buf + (__enext - _M_ext_buf);
1.670 this->setg(_M_int_buf, _M_int_buf, __inext);
1.671 return traits_type::to_int_type(*_M_int_buf);
1.672 }
1.673 // We need to go around the loop again to get more external characters.
1.674 - }
1.675 + }
1.676 }
1.677
1.678 //----------------------------------------
1.679 @@ -702,8 +548,7 @@
1.680 // seek.
1.681 template <class _CharT, class _Traits>
1.682 __BF_int_type__
1.683 -basic_filebuf<_CharT, _Traits>::_M_output_error()
1.684 -{
1.685 +basic_filebuf<_CharT, _Traits>::_M_output_error() {
1.686 _M_in_output_mode = false;
1.687 _M_in_input_mode = false;
1.688 _M_in_error_mode = true;
1.689 @@ -717,8 +562,7 @@
1.690 // buffer, changes the external file position, and changes the state.
1.691 // Precondition: the internal buffer is empty.
1.692 template <class _CharT, class _Traits>
1.693 -bool basic_filebuf<_CharT, _Traits>::_M_unshift()
1.694 -{
1.695 +bool basic_filebuf<_CharT, _Traits>::_M_unshift() {
1.696 if (_M_in_output_mode && !_M_constant_width) {
1.697 typename _Codecvt::result __status;
1.698 do {
1.699 @@ -732,7 +576,7 @@
1.700 return false;
1.701 else if (!_M_write(_M_ext_buf, __enext - _M_ext_buf))
1.702 return false;
1.703 - } while(__status == _Codecvt::partial);
1.704 + } while (__status == _Codecvt::partial);
1.705 }
1.706
1.707 return true;
1.708 @@ -746,22 +590,31 @@
1.709 // internal and external buffers. The argument is the size of the
1.710 // internal buffer; the external buffer is sized using the character
1.711 // width in the current encoding. Preconditions: the buffers are currently
1.712 -// null. __n >= 1. __buf is either a null pointer or a pointer to an
1.713 +// null. __n >= 1. __buf is either a null pointer or a pointer to an
1.714 // array show size is at least __n.
1.715
1.716 // We need __n >= 1 for two different reasons. For input, the base
1.717 -// class always needs a buffer because of the sementics of underflow().
1.718 +// class always needs a buffer because of the semantics of underflow().
1.719 // For output, we want to have an internal buffer that's larger by one
1.720 -// element than the buffer that the base class knows about. (See
1.721 +// element than the buffer that the base class knows about. (See
1.722 // basic_filebuf<>::overflow() for the reason.)
1.723 template <class _CharT, class _Traits>
1.724 -bool
1.725 -basic_filebuf<_CharT, _Traits>::_M_allocate_buffers(_CharT* __buf, streamsize __n)
1.726 -{
1.727 +bool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers(_CharT* __buf, streamsize __n) {
1.728 + //The major hypothesis in the following implementation is that size_t is unsigned.
1.729 + //We also need streamsize byte representation to be larger or equal to the int
1.730 + //representation to correctly store the encoding information.
1.731 + _STLP_STATIC_ASSERT(!numeric_limits<size_t>::is_signed &&
1.732 + sizeof(streamsize) >= sizeof(int))
1.733
1.734 if (__buf == 0) {
1.735 - _M_int_buf = __STATIC_CAST(_CharT*,malloc(__n * sizeof(_CharT)));
1.736 - if (! _M_int_buf)
1.737 + streamsize __bufsize = __n * sizeof(_CharT);
1.738 + //We first check that the streamsize representation can't overflow a size_t one.
1.739 + //If it can, we check that __bufsize is not higher than the size_t max value.
1.740 + if ((sizeof(streamsize) > sizeof(size_t)) &&
1.741 + (__bufsize > __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)())))
1.742 + return false;
1.743 + _M_int_buf = __STATIC_CAST(_CharT*, malloc(__STATIC_CAST(size_t, __bufsize)));
1.744 + if (!_M_int_buf)
1.745 return false;
1.746 _M_int_buf_dynamic = true;
1.747 }
1.748 @@ -769,25 +622,29 @@
1.749 _M_int_buf = __buf;
1.750 _M_int_buf_dynamic = false;
1.751 }
1.752 -
1.753 - size_t __ebufsiz = (max)(__n * (max)(_M_codecvt->encoding(), 1),
1.754 - streamsize(_M_codecvt->max_length()));
1.755
1.756 - _M_ext_buf = __STATIC_CAST(char*,malloc(__ebufsiz));
1.757 + streamsize __ebufsiz = (max)(__n * __STATIC_CAST(streamsize, _M_width),
1.758 + __STATIC_CAST(streamsize, _M_codecvt->max_length()));
1.759 + _M_ext_buf = 0;
1.760 + if ((sizeof(streamsize) < sizeof(size_t)) ||
1.761 + ((sizeof(streamsize) == sizeof(size_t)) && numeric_limits<streamsize>::is_signed) ||
1.762 + (__ebufsiz <= __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) {
1.763 + _M_ext_buf = __STATIC_CAST(char*, malloc(__STATIC_CAST(size_t, __ebufsiz)));
1.764 + }
1.765 +
1.766 if (!_M_ext_buf) {
1.767 _M_deallocate_buffers();
1.768 return false;
1.769 }
1.770
1.771 - _M_int_buf_EOS = _M_int_buf + __n;
1.772 - _M_ext_buf_EOS = _M_ext_buf + __ebufsiz;
1.773 + _M_int_buf_EOS = _M_int_buf + __STATIC_CAST(ptrdiff_t, __n);
1.774 + _M_ext_buf_EOS = _M_ext_buf + __STATIC_CAST(ptrdiff_t, __ebufsiz);
1.775 return true;
1.776 }
1.777
1.778 // Abbreviation for the most common case.
1.779 template <class _CharT, class _Traits>
1.780 -bool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers()
1.781 -{
1.782 +bool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers() {
1.783 // Choose a buffer that's at least 4096 characters long and that's a
1.784 // multiple of the page size.
1.785 streamsize __default_bufsiz =
1.786 @@ -796,8 +653,7 @@
1.787 }
1.788
1.789 template <class _CharT, class _Traits>
1.790 -void basic_filebuf<_CharT, _Traits>::_M_deallocate_buffers()
1.791 -{
1.792 +void basic_filebuf<_CharT, _Traits>::_M_deallocate_buffers() {
1.793 if (_M_int_buf_dynamic)
1.794 free(_M_int_buf);
1.795 free(_M_ext_buf);
1.796 @@ -815,7 +671,7 @@
1.797 bool basic_filebuf<_CharT, _Traits>::_M_seek_init(bool __do_unshift) {
1.798 // If we're in error mode, leave it.
1.799 _M_in_error_mode = false;
1.800 -
1.801 +
1.802 // Flush the output buffer if we're in output mode, and (conditionally)
1.803 // emit an unshift sequence.
1.804 if (_M_in_output_mode) {
1.805 @@ -839,53 +695,43 @@
1.806 }
1.807
1.808
1.809 -// Change the filebuf's locale. This member function has no effect
1.810 -// unless it is called before any I/O is performed on the stream.
1.811 +/* Change the filebuf's locale. This member function has no effect
1.812 + * unless it is called before any I/O is performed on the stream.
1.813 + * This function is called on construction and on an imbue call. In the
1.814 + * case of the construction the codecvt facet might be a custom one if
1.815 + * the basic_filebuf user has instanciate it with a custom char_traits.
1.816 + * The user will have to call imbue before any I/O operation.
1.817 + */
1.818 template <class _CharT, class _Traits>
1.819 -void basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc)
1.820 -{
1.821 - _M_codecvt = &use_facet<_Codecvt>(__loc) ;
1.822 - int __encoding = _M_codecvt->encoding();
1.823 +void basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc, bool __on_imbue) {
1.824 + if (has_facet<_Codecvt>(__loc)) {
1.825 + _M_codecvt = &use_facet<_Codecvt>(__loc) ;
1.826 + int __encoding = _M_codecvt->encoding();
1.827
1.828 - _M_width = (max)(__encoding, 1);
1.829 - _M_max_width = _M_codecvt->max_length();
1.830 - _M_constant_width = __encoding > 0;
1.831 - _M_always_noconv = _M_codecvt->always_noconv();
1.832 + _M_width = (max)(__encoding, 1);
1.833 + _M_max_width = _M_codecvt->max_length();
1.834 + _M_constant_width = __encoding > 0;
1.835 + _M_always_noconv = _M_codecvt->always_noconv();
1.836 + }
1.837 + else {
1.838 + _M_codecvt = 0;
1.839 + _M_width = _M_max_width = 1;
1.840 + _M_constant_width = _M_always_noconv = false;
1.841 + if (__on_imbue) {
1.842 + //This call will generate an exception reporting the problem.
1.843 + use_facet<_Codecvt>(__loc);
1.844 + }
1.845 + }
1.846 }
1.847
1.848 -
1.849 -
1.850 -template <class _CharT, class _Traits>
1.851 - _STLP_EXP_DECLSPEC basic_fstream<_CharT, _Traits>::basic_fstream()
1.852 - : basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
1.853 - this->init(&_M_buf);
1.854 - }
1.855 -
1.856 -
1.857 -template <class _CharT, class _Traits>
1.858 - _STLP_EXP_DECLSPEC basic_fstream<_CharT, _Traits>::~basic_fstream(){}
1.859 -
1.860 -#ifdef __SYMBIAN32__
1.861 -template <class _CharT, class _Traits>
1.862 -int basic_filebuf<_CharT, _Traits>::save_read_buffer ()
1.863 - {
1.864 - return _M_in_putback_mode ? _M_saved_egptr - _M_saved_gptr : 0;
1.865 - }
1.866 -template <class _CharT, class _Traits>
1.867 -void basic_filebuf<_CharT, _Traits>::_change_input_mode ()
1.868 - {
1.869 - _M_in_input_mode = 1;
1.870 - }
1.871 -
1.872 -#endif
1.873 -
1.874 _STLP_END_NAMESPACE
1.875
1.876 # undef __BF_int_type__
1.877 # undef __BF_pos_type__
1.878 # undef __BF_off_type__
1.879
1.880 -# endif /* defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) */
1.881 -
1.882 #endif /* _STLP_FSTREAM_C */
1.883
1.884 +// Local Variables:
1.885 +// mode:C++
1.886 +// End: