epoc32/include/stdapis/stlportv5/stl/_fstream.c
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
     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: