111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1996,1997 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Silicon Graphics Computer Systems, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 1999 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Boris Fomitchev 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This material is provided "as is", with absolutely no warranty expressed 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * or implied. Any use is at your own risk. 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to use or copy this software for any purpose is hereby granted 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * without fee, provided the above notices are retained on all copies. 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Permission to modify the code and to distribute modified code is granted, 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * provided the above notices are retained, and a notice that the code was 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * modified is included with the above copyright notice. 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_FSTREAM_C 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _STLP_FSTREAM_C 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_FSTREAM_H 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <stl/_fstream.h> 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _STLP_INTERNAL_LIMITS 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <stl/_limits.h> 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_BEGIN_NAMESPACE 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// no wchar_t is supported for this mode 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_int_type__ int 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_pos_type__ streampos 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_off_type__ streamoff 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# else 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::pos_type 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# define __BF_off_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::off_type 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------------------------------------- 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Public basic_filebuf<> member functions 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::basic_filebuf() 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : basic_streambuf<_CharT, _Traits>(), _M_base(), 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_constant_width(false), _M_always_noconv(false), 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf_dynamic(false), 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode(false), _M_in_output_mode(false), 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_error_mode(false), _M_in_putback_mode(false), 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf(0), _M_int_buf_EOS(0), 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf(0), _M_ext_buf_EOS(0), 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_converted(0), _M_ext_buf_end(0), 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_end_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mmap_base(0), _M_mmap_len(0), 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_saved_eback(0), _M_saved_gptr(0), _M_saved_egptr(0), 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_codecvt(0), 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_width(1), _M_max_width(1) 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_M_setup_codecvt(locale(), false); 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::~basic_filebuf() { 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->close(); 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_deallocate_buffers(); 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::underflow() { 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _Underflow<_CharT, _Traits>::_M_doit(this); 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>* 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::close() { 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool __ok = this->is_open(); 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_output_mode) { 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ok = __ok && !_Traits::eq_int_type(this->overflow(traits_type::eof()), 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::eof()); 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ok = __ok && this->_M_unshift(); 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (_M_in_input_mode) 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_M_exit_input_mode(); 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Note order of arguments. We close the file even if __ok is false. 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ok = _M_base._M_close() && __ok; 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Restore the initial state, except that we don't deallocate the buffer 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // or mess with the cached codecvt information. 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_state = _M_end_state = _State_type(); 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_converted = _M_ext_buf_end = 0; 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mmap_base = 0; 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mmap_len = 0; 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(0, 0, 0); 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setp(0, 0); 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_saved_eback = _M_saved_gptr = _M_saved_egptr = 0; 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode = _M_in_output_mode = _M_in_error_mode = _M_in_putback_mode 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert = false; 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __ok ? this : 0; 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called whenever we exit input mode. 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It unmaps the memory-mapped file, if any, and sets 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// _M_in_input_mode to false. 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid basic_filebuf<_CharT, _Traits>::_M_exit_input_mode() { 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_mmap_base != 0) { 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_base._M_unmap(_M_mmap_base, _M_mmap_len); 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mmap_base = 0; 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mmap_len = 0; 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode = false; 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------------------------------------- 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// basic_filebuf<> overridden protected virtual member functions 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstreamsize basic_filebuf<_CharT, _Traits>::showmanyc() { 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Is there any possibility that reads can succeed? 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!this->is_open() || _M_in_output_mode || _M_in_error_mode) 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return -1; 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (_M_in_putback_mode) 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return this->egptr() - this->gptr(); 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (_M_constant_width) { 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __pos = _M_base._M_seek(0, ios_base::cur); 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __size = _M_base._M_file_size(); 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __pos >= 0 && __size > __pos ? __size - __pos : 0; 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Make a putback position available, if necessary, by switching to a 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// special internal buffer used only for putback. The buffer is 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// [_M_pback_buf, _M_pback_buf + _S_pback_buf_size), but the base 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// class only sees a piece of it at a time. (We want to make sure 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// that we don't try to read a character that hasn't been initialized.) 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The end of the putback buffer is always _M_pback_buf + _S_pback_buf_size, 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but the beginning is usually not _M_pback_buf. 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_int_type__ 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) { 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const int_type __eof = traits_type::eof(); 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If we aren't already in input mode, pushback is impossible. 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_in_input_mode) 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __eof; 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // We can use the ordinary get buffer if there's enough space, and 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // if it's a buffer that we're allowed to write to. 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (this->gptr() != this->eback() && 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (traits_type::eq_int_type(__c, __eof) || 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) || 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert !_M_mmap_base)) { 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->gbump(-1); 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (traits_type::eq_int_type(__c, __eof) || 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::eq(traits_type::to_char_type(__c), *this->gptr())) 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::to_int_type(*this->gptr()); 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (!traits_type::eq_int_type(__c, __eof)) { 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Are we in the putback buffer already? 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __pback_end = _M_pback_buf + __STATIC_CAST(int,_S_pback_buf_size); 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_putback_mode) { 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Do we have more room in the putback buffer? 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (this->eback() != _M_pback_buf) 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(this->egptr() - 1, this->egptr() - 1, __pback_end); 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __eof; // No more room in the buffer, so fail. 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else { // We're not yet in the putback buffer. 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_saved_eback = this->eback(); 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_saved_gptr = this->gptr(); 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_saved_egptr = this->egptr(); 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(__pback_end - 1, __pback_end - 1, __pback_end); 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_putback_mode = true; 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __eof; 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // We have made a putback position available. Assign to it, and return. 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *this->gptr() = traits_type::to_char_type(__c); 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __c; 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function flushes the put area, and also outputs the 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// character __c (unless __c is eof). Invariant: we always leave room 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// in the internal buffer for one character more than the base class knows 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// about. We see the internal buffer as [_M_int_buf, _M_int_buf_EOS), but 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the base class only sees [_M_int_buf, _M_int_buf_EOS - 1). 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_int_type__ 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::overflow(int_type __c) { 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Switch to output mode, if necessary. 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_in_output_mode) 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_switch_to_output_mode()) 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __ibegin = this->_M_int_buf; 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __iend = this->pptr(); 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setp(_M_int_buf, _M_int_buf_EOS - 1); 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Put __c at the end of the internal buffer. 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!traits_type::eq_int_type(__c, traits_type::eof())) 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *__iend++ = _Traits::to_char_type(__c); 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For variable-width encodings, output may take more than one pass. 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (__ibegin != __iend) { 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _CharT* __inext = __ibegin; 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char* __enext = _M_ext_buf; 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Codecvt::result __status 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert = _M_codecvt->out(_M_state, __ibegin, __iend, __inext, 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf, _M_ext_buf_EOS, __enext); 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__status == _Codecvt::noconv) { 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend) 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ? traits_type::not_eof(__c) 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_output_error(); 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For a constant-width encoding we know that the external buffer 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // is large enough, so failure to consume the entire internal buffer 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // or to produce the correct number of external characters, is an error. 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For a variable-width encoding, however, we require only that we 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // consume at least one internal character 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__status != _Codecvt::error && 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (((__inext == __iend) && 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__enext - _M_ext_buf == _M_width * (__iend - __ibegin))) || 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (!_M_constant_width && __inext != __ibegin))) { 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // We successfully converted part or all of the internal buffer. 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptrdiff_t __n = __enext - _M_ext_buf; 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_write(_M_ext_buf, __n)) 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ibegin += __inext - __ibegin; 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_output_error(); 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_output_error(); 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::not_eof(__c); 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function must be called before any I/O has been 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// performed on the stream, otherwise it has no effect. 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// __buf == 0 && __n == 0 means to make this stream unbuffered. 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// __buf != 0 && __n > 0 means to use __buf as the stream's internal 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// buffer, rather than the buffer that would otherwise be allocated 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// automatically. __buf must be a pointer to an array of _CharT whose 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// size is at least __n. 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_streambuf<_CharT, _Traits>* 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n) { 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode && 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf == 0) { 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__buf == 0 && __n == 0) 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_allocate_buffers(0, 1); 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__buf != 0 && __n > 0) 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_allocate_buffers(__buf, __n); 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return this; 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_ASSERTIONS) 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// helper class. 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT> 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct _Filebuf_Tmp_Buf { 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* _M_ptr; 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Filebuf_Tmp_Buf(ptrdiff_t __n) : _M_ptr(0) { _M_ptr = new _CharT[__n]; } 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~_Filebuf_Tmp_Buf() { delete[] _M_ptr; } 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}; 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_pos_type__ 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ios_base::seekdir __whence, 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ios_base::openmode /* dummy */) { 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!this->is_open()) 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_constant_width && __off != 0) 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_seek_init(__off != 0 || __whence != ios_base::cur)) 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Seek to beginning or end, regardless of whether we're in input mode. 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__whence == ios_base::beg || __whence == ios_base::end) 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _State_type()); 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Seek relative to current position. Complicated if we're in input mode. 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_ASSERT(__whence == ios_base::cur) 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_in_input_mode) 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _State_type()); 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_mmap_base != 0) { 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __off is relative to gptr(). We need to do a bit of arithmetic 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // to get an offset relative to the external file pointer. 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __adjust = _M_mmap_len - (this->gptr() - (_CharT*) _M_mmap_base); 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // if __off == 0, we do not need to exit input mode and to shift file pointer 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __adjust) 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type()); 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_constant_width) { // Get or set the position. 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __iadj = _M_width * (this->gptr() - this->eback()); 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Compensate for offset relative to gptr versus offset relative 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // to external pointer. For a text-oriented stream, where the 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // compensation is more than just pointer arithmetic, we may get 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // but not set the current position. 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__iadj <= _M_ext_buf_end - _M_ext_buf) { 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __eadj = _M_base._M_get_offset(_M_ext_buf + __STATIC_CAST(ptrdiff_t, __iadj), _M_ext_buf_end); 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj) 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type()); 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else { // Get the position. Encoding is var width. 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Get position in internal buffer. 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptrdiff_t __ipos = this->gptr() - this->eback(); 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Get corresponding position in external buffer. 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _State_type __state = _M_state; 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int __epos = _M_codecvt->length(__state, _M_ext_buf, _M_ext_buf_converted, 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ipos); 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined (_STLP_ASSERTIONS) 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Sanity check (expensive): make sure __epos is the right answer. 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_ASSERT(__epos >= 0) 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _State_type __tmp_state = _M_state; 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Filebuf_Tmp_Buf<_CharT> __buf(__ipos); 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __ibegin = __buf._M_ptr; 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __inext = __ibegin; 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char* __dummy; 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Codecvt::result __status 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert = _M_codecvt->in(__tmp_state, 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf, _M_ext_buf + __epos, __dummy, 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ibegin, __ibegin + __ipos, __inext); 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The result code is necessarily ok because: 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - noconv: impossible for a variable encoding 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - error: length method is supposed to count until it reach max value or find an error so we cannot have 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // an error again when decoding an external buffer up to length return value. 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // - partial: idem error, it is also a reason for length to stop counting. 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_ASSERT(__status == _Codecvt::ok) 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_ASSERT(__inext == __ibegin + __ipos) 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_ASSERT(equal(this->eback(), this->gptr(), __ibegin, _STLP_PRIV _Eq_traits<traits_type>())) 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Get the current position (at the end of the external buffer), 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // then adjust it. Again, it might be a text-oriented stream. 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __cur = _M_base._M_seek(0, ios_base::cur); 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __adj = _M_base._M_get_offset(_M_ext_buf, _M_ext_buf + __epos) - 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_base._M_get_offset(_M_ext_buf, _M_ext_buf_end); 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__cur != -1 && __cur + __adj >= 0) 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __off == 0 ? pos_type(__cur + __adj) 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_seek_return(__cur + __adj, __state); 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_pos_type__ 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __pos, 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ios_base::openmode /* dummy */) { 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (this->is_open()) { 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_seek_init(true)) 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamoff __off = off_type(__pos); 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__off != -1 && _M_base._M_seek(__off, ios_base::beg) != -1) { 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_state = __pos.state(); 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_seek_return(__off, __pos.state()); 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return pos_type(-1); 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint basic_filebuf<_CharT, _Traits>::sync() { 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_output_mode) 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eq_int_type(this->overflow(traits_type::eof()), 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::eof()) ? -1 : 0; 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return 0; 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Change the filebuf's locale. This member function has no effect 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// unless it is called before any I/O is performed on the stream. 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) { 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_in_input_mode && !_M_in_output_mode && !_M_in_error_mode) { 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_M_setup_codecvt(__loc); 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------------------------------------- 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// basic_filebuf<> helper functions. 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------- 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper functions for switching between modes. 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called if we're performing the first I/O 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// operation on a filebuf, or if we're performing an input operation 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// immediately after a seek. 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode() { 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) !=0) 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert && (_M_in_output_mode == 0) && (_M_in_error_mode == 0)) { 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_int_buf && !_M_allocate_buffers()) 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_converted = _M_ext_buf; 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_end = _M_ext_buf; 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_end_state = _M_state; 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode = true; 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called if we're performing the first I/O 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// operation on a filebuf, or if we're performing an output operation 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// immediately after a seek. 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode() { 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (this->is_open() && (_M_base.__o_mode() & (int)ios_base::out) && 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode == 0 && _M_in_error_mode == 0) { 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_int_buf && !_M_allocate_buffers()) 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // In append mode, every write does an implicit seek to the end 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // of the file. Whenever leaving output mode, the end of file 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // get put in the initial shift state. 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_base.__o_mode() & ios_base::app) 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_state = _State_type(); 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setp(_M_int_buf, _M_int_buf_EOS - 1); 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_output_mode = true; 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------- 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper functions for input 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called if there is an error during input. 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It puts the filebuf in error mode, clear the get area buffer, and 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// returns eof. 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// returns eof. Error mode is sticky; it is cleared only by close or 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// seek. 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_int_type__ 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::_M_input_error() { 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_M_exit_input_mode(); 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_output_mode = false; 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_error_mode = true; 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(0, 0, 0); 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_int_type__ 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::_M_underflow_aux() { 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // We have the state and file position from the end of the internal 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // buffer. This round, they become the beginning of the internal buffer. 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_state = _M_end_state; 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Fill the external buffer. Start with any leftover characters that 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // didn't get converted last time. 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_ext_buf_end > _M_ext_buf_converted) 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_end = _STLP_STD::copy(_M_ext_buf_converted, _M_ext_buf_end, _M_ext_buf); 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // boris : copy_backward did not work 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //_M_ext_buf_end = copy_backward(_M_ext_buf_converted, _M_ext_buf_end, 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //_M_ext_buf+ (_M_ext_buf_end - _M_ext_buf_converted)); 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_end = _M_ext_buf; 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Now fill the external buffer with characters from the file. This is 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // a loop because occasionally we don't get enough external characters 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // to make progress. 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert for (;;) { 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ptrdiff_t __n = _M_base._M_read(_M_ext_buf_end, _M_ext_buf_EOS - _M_ext_buf_end); 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__n < 0) { 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Read failed, maybe we should set err bit on associated stream... 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(0, 0, 0); 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_end += __n; 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If external buffer is empty there is nothing to do. 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_ext_buf == _M_ext_buf_end) { 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(0, 0, 0); 52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Convert the external buffer to internal characters. 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const char* __enext; 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __inext; 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Codecvt::result __status 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert = _M_codecvt->in(_M_end_state, 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf, _M_ext_buf_end, __enext, 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf, _M_int_buf_EOS, __inext); 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* Error conditions: 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * (1) Return value of error. 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * (2) Producing internal characters without consuming external characters. 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * (3) In fixed-width encodings, producing an internal sequence whose length 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * is inconsistent with that of the internal sequence. 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * (4) Failure to produce any characters if we have enough characters in 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the external buffer, where "enough" means the largest possible width 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * of a single character. */ 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__status == _Codecvt::noconv) 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _Noconv_input<_Traits>::_M_doit(this); 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__status == _Codecvt::error || 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__inext != _M_int_buf && __enext == _M_ext_buf) || 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (_M_constant_width && (__inext - _M_int_buf) * _M_width != (__enext - _M_ext_buf)) || 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__inext == _M_int_buf && __enext - _M_ext_buf >= _M_max_width)) 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_input_error(); 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__inext != _M_int_buf) { 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_converted = _M_ext_buf + (__enext - _M_ext_buf); 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(_M_int_buf, _M_int_buf, __inext); 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::to_int_type(*_M_int_buf); 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* We need to go around the loop again to get more external characters. 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * But if the previous read failed then don't try again for now. 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Don't enter error mode for a failed read. Error mode is sticky, 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * and we might succeed if we try again. */ 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__n <= 0) { 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setg(0, 0, 0); 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------- 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper functions for output 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called if there is an error during output. 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// It puts the filebuf in error mode, clear the put area buffer, and 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// returns eof. Error mode is sticky; it is cleared only by close or 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// seek. 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert__BF_int_type__ 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbasic_filebuf<_CharT, _Traits>::_M_output_error() { 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_output_mode = false; 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_input_mode = false; 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_error_mode = true; 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setp(0, 0); 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return traits_type::eof(); 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Write whatever sequence of characters is necessary to get back to 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the initial shift state. This function overwrites the external 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// buffer, changes the external file position, and changes the state. 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Precondition: the internal buffer is empty. 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_unshift() { 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_output_mode && !_M_constant_width) { 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Codecvt::result __status; 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert do { 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert char* __enext = _M_ext_buf; 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __status = _M_codecvt->unshift(_M_state, 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf, _M_ext_buf_EOS, __enext); 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__status == _Codecvt::noconv || 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__enext == _M_ext_buf && __status == _Codecvt::ok)) 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__status == _Codecvt::error) 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (!_M_write(_M_ext_buf, __enext - _M_ext_buf)) 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } while (__status == _Codecvt::partial); 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------- 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper functions for buffer allocation and deallocation 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This member function is called when we're initializing a filebuf's 61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// internal and external buffers. The argument is the size of the 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// internal buffer; the external buffer is sized using the character 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// width in the current encoding. Preconditions: the buffers are currently 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// null. __n >= 1. __buf is either a null pointer or a pointer to an 62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// array show size is at least __n. 62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// We need __n >= 1 for two different reasons. For input, the base 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// class always needs a buffer because of the semantics of underflow(). 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// For output, we want to have an internal buffer that's larger by one 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// element than the buffer that the base class knows about. (See 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// basic_filebuf<>::overflow() for the reason.) 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers(_CharT* __buf, streamsize __n) { 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //The major hypothesis in the following implementation is that size_t is unsigned. 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //We also need streamsize byte representation to be larger or equal to the int 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //representation to correctly store the encoding information. 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _STLP_STATIC_ASSERT(!numeric_limits<size_t>::is_signed && 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert sizeof(streamsize) >= sizeof(int)) 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__buf == 0) { 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamsize __bufsize = __n * sizeof(_CharT); 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //We first check that the streamsize representation can't overflow a size_t one. 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //If it can, we check that __bufsize is not higher than the size_t max value. 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((sizeof(streamsize) > sizeof(size_t)) && 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__bufsize > __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf = __STATIC_CAST(_CharT*, malloc(__STATIC_CAST(size_t, __bufsize))); 64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_int_buf) 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf_dynamic = true; 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else { 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf = __buf; 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf_dynamic = false; 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamsize __ebufsiz = (max)(__n * __STATIC_CAST(streamsize, _M_width), 65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __STATIC_CAST(streamsize, _M_codecvt->max_length())); 65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf = 0; 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if ((sizeof(streamsize) < sizeof(size_t)) || 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((sizeof(streamsize) == sizeof(size_t)) && numeric_limits<streamsize>::is_signed) || 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert (__ebufsiz <= __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) { 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf = __STATIC_CAST(char*, malloc(__STATIC_CAST(size_t, __ebufsiz))); 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_ext_buf) { 66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_deallocate_buffers(); 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf_EOS = _M_int_buf + __STATIC_CAST(ptrdiff_t, __n); 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_EOS = _M_ext_buf + __STATIC_CAST(ptrdiff_t, __ebufsiz); 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Abbreviation for the most common case. 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers() { 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Choose a buffer that's at least 4096 characters long and that's a 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // multiple of the page size. 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert streamsize __default_bufsiz = 68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ((_M_base.__page_size() + 4095UL) / _M_base.__page_size()) * _M_base.__page_size(); 68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_allocate_buffers(0, __default_bufsiz); 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid basic_filebuf<_CharT, _Traits>::_M_deallocate_buffers() { 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_int_buf_dynamic) 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert free(_M_int_buf); 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert free(_M_ext_buf); 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf = 0; 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_int_buf_EOS = 0; 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf = 0; 69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ext_buf_EOS = 0; 69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//---------------------------------------- 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper functiosn for seek and imbue 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool basic_filebuf<_CharT, _Traits>::_M_seek_init(bool __do_unshift) { 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If we're in error mode, leave it. 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_error_mode = false; 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Flush the output buffer if we're in output mode, and (conditionally) 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // emit an unshift sequence. 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_output_mode) { 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool __ok = !traits_type::eq_int_type(this->overflow(traits_type::eof()), 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::eof()); 70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__do_unshift) 71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ok = __ok && this->_M_unshift(); 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!__ok) { 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_output_mode = false; 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_in_error_mode = true; 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->setp(0, 0); 71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Discard putback characters, if any. 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_in_input_mode && _M_in_putback_mode) 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_exit_putback_mode(); 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Change the filebuf's locale. This member function has no effect 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * unless it is called before any I/O is performed on the stream. 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This function is called on construction and on an imbue call. In the 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * case of the construction the codecvt facet might be a custom one if 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the basic_filebuf user has instanciate it with a custom char_traits. 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The user will have to call imbue before any I/O operation. 73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 73411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttemplate <class _CharT, class _Traits> 73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc, bool __on_imbue) { 73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (has_facet<_Codecvt>(__loc)) { 73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_codecvt = &use_facet<_Codecvt>(__loc) ; 73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert int __encoding = _M_codecvt->encoding(); 73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_width = (max)(__encoding, 1); 74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_max_width = _M_codecvt->max_length(); 74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_constant_width = __encoding > 0; 74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_always_noconv = _M_codecvt->always_noconv(); 74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else { 74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_codecvt = 0; 74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_width = _M_max_width = 1; 74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_constant_width = _M_always_noconv = false; 74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__on_imbue) { 75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert //This call will generate an exception reporting the problem. 75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert use_facet<_Codecvt>(__loc); 75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} 75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_STLP_END_NAMESPACE 75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __BF_int_type__ 75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __BF_pos_type__ 76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# undef __BF_off_type__ 76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _STLP_FSTREAM_C */ 76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Local Variables: 76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// mode:C++ 76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// End: 767