19720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* 29720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Copyright (c) 1996,1997 39720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Silicon Graphics Computer Systems, Inc. 49720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * 59720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Copyright (c) 1999 69720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Boris Fomitchev 79720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * 89720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * This material is provided "as is", with absolutely no warranty expressed 99720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * or implied. Any use is at your own risk. 109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * 119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Permission to use or copy this software for any purpose is hereby granted 129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * without fee, provided the above notices are retained on all copies. 139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * Permission to modify the code and to distribute modified code is granted, 149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * provided the above notices are retained, and a notice that the code was 159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * modified is included with the above copyright notice. 169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * 179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */ 189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_FSTREAM_C 199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#define _STLP_FSTREAM_C 209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_INTERNAL_FSTREAM_H 229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# include <stl/_fstream.h> 239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif 249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#ifndef _STLP_INTERNAL_LIMITS 269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# include <stl/_limits.h> 279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif 289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_BEGIN_NAMESPACE 309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# if defined ( _STLP_NESTED_TYPE_PARAM_BUG ) 329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// no wchar_t is supported for this mode 339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_int_type__ int 349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_pos_type__ streampos 359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_off_type__ streamoff 369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# else 379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type 389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::pos_type 399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# define __BF_off_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::off_type 409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# endif 419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------------------------------------- 449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Public basic_filebuf<> member functions 459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::basic_filebuf() 489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block : basic_streambuf<_CharT, _Traits>(), _M_base(), 499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_constant_width(false), _M_always_noconv(false), 509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf_dynamic(false), 519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_input_mode(false), _M_in_output_mode(false), 529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_error_mode(false), _M_in_putback_mode(false), 539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf(0), _M_int_buf_EOS(0), 549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf(0), _M_ext_buf_EOS(0), 559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_converted(0), _M_ext_buf_end(0), 569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), 579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_end_state(_STLP_DEFAULT_CONSTRUCTED(_State_type)), 589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_mmap_base(0), _M_mmap_len(0), 599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_saved_eback(0), _M_saved_gptr(0), _M_saved_egptr(0), 609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_codecvt(0), 619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_width(1), _M_max_width(1) 629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block{ 639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->_M_setup_codecvt(locale(), false); 649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::~basic_filebuf() { 689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->close(); 699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_deallocate_buffers(); 709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_TYPENAME_ON_RETURN_TYPE basic_filebuf<_CharT, _Traits>::int_type 759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::underflow() { 769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _Underflow<_CharT, _Traits>::_M_doit(this); 779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>* 819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::close() { 829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block bool __ok = this->is_open(); 839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_output_mode) { 859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __ok = __ok && !_Traits::eq_int_type(this->overflow(traits_type::eof()), 869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block traits_type::eof()); 874fdc136b5fc12da237caad05c8ccb05e8bb1cd6dEvgeniy Stepanov __ok = __ok && this->_M_unshift(); 889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (_M_in_input_mode) 909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->_M_exit_input_mode(); 919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Note order of arguments. We close the file even if __ok is false. 939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __ok = _M_base._M_close() && __ok; 949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Restore the initial state, except that we don't deallocate the buffer 969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // or mess with the cached codecvt information. 979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_state = _M_end_state = _State_type(); 989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_converted = _M_ext_buf_end = 0; 999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_mmap_base = 0; 1019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_mmap_len = 0; 1029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setg(0, 0, 0); 1049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setp(0, 0); 1059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_saved_eback = _M_saved_gptr = _M_saved_egptr = 0; 1079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_input_mode = _M_in_output_mode = _M_in_error_mode = _M_in_putback_mode 1099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block = false; 1109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __ok ? this : 0; 1129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 1139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called whenever we exit input mode. 1159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It unmaps the memory-mapped file, if any, and sets 1169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// _M_in_input_mode to false. 1179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 1189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid basic_filebuf<_CharT, _Traits>::_M_exit_input_mode() { 119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_M_mmap_base != 0) { 120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_base._M_unmap(_M_mmap_base, _M_mmap_len); 121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_mmap_base = 0; 122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_mmap_len = 0; 123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_in_input_mode = false; 1259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 1269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------------------------------------- 1299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// basic_filebuf<> overridden protected virtual member functions 1309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 1329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockstreamsize basic_filebuf<_CharT, _Traits>::showmanyc() { 1339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Is there any possibility that reads can succeed? 1349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!this->is_open() || _M_in_output_mode || _M_in_error_mode) 1359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return -1; 1369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (_M_in_putback_mode) 1379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return this->egptr() - this->gptr(); 1389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (_M_constant_width) { 1399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamoff __pos = _M_base._M_seek(0, ios_base::cur); 1409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamoff __size = _M_base._M_file_size(); 1419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __pos >= 0 && __size > __pos ? __size - __pos : 0; 1429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 1449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return 0; 1459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 1469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Make a putback position available, if necessary, by switching to a 1499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// special internal buffer used only for putback. The buffer is 1509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// [_M_pback_buf, _M_pback_buf + _S_pback_buf_size), but the base 1519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// class only sees a piece of it at a time. (We want to make sure 1529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// that we don't try to read a character that hasn't been initialized.) 1539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// The end of the putback buffer is always _M_pback_buf + _S_pback_buf_size, 1549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// but the beginning is usually not _M_pback_buf. 1559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 1569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_int_type__ 1579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) { 1589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const int_type __eof = traits_type::eof(); 1599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // If we aren't already in input mode, pushback is impossible. 1619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_in_input_mode) 1629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __eof; 1639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // We can use the ordinary get buffer if there's enough space, and 1659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // if it's a buffer that we're allowed to write to. 1669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (this->gptr() != this->eback() && 1679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (traits_type::eq_int_type(__c, __eof) || 1689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) || 1699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block !_M_mmap_base)) { 1709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->gbump(-1); 1719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (traits_type::eq_int_type(__c, __eof) || 1729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block traits_type::eq(traits_type::to_char_type(__c), *this->gptr())) 1739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::to_int_type(*this->gptr()); 1749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (!traits_type::eq_int_type(__c, __eof)) { 1769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Are we in the putback buffer already? 1779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _CharT* __pback_end = _M_pback_buf + __STATIC_CAST(int,_S_pback_buf_size); 1789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_putback_mode) { 1799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Do we have more room in the putback buffer? 1809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (this->eback() != _M_pback_buf) 1819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setg(this->egptr() - 1, this->egptr() - 1, __pback_end); 1829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 1839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __eof; // No more room in the buffer, so fail. 1849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else { // We're not yet in the putback buffer. 1869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_saved_eback = this->eback(); 1879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_saved_gptr = this->gptr(); 1889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_saved_egptr = this->egptr(); 1899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setg(__pback_end - 1, __pback_end - 1, __pback_end); 1909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_putback_mode = true; 1919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 1939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 1949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __eof; 1959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 1969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // We have made a putback position available. Assign to it, and return. 1979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *this->gptr() = traits_type::to_char_type(__c); 1989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return __c; 1999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 2009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function flushes the put area, and also outputs the 2029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// character __c (unless __c is eof). Invariant: we always leave room 2039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// in the internal buffer for one character more than the base class knows 2049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// about. We see the internal buffer as [_M_int_buf, _M_int_buf_EOS), but 2059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// the base class only sees [_M_int_buf, _M_int_buf_EOS - 1). 2069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 2079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_int_type__ 2089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::overflow(int_type __c) { 2099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Switch to output mode, if necessary. 2109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_in_output_mode) 2119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_switch_to_output_mode()) 2129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::eof(); 2139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _CharT* __ibegin = this->_M_int_buf; 2159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _CharT* __iend = this->pptr(); 2169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setp(_M_int_buf, _M_int_buf_EOS - 1); 2179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Put __c at the end of the internal buffer. 2199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!traits_type::eq_int_type(__c, traits_type::eof())) 2209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block *__iend++ = _Traits::to_char_type(__c); 2219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // For variable-width encodings, output may take more than one pass. 2239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block while (__ibegin != __iend) { 2249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block const _CharT* __inext = __ibegin; 2259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block char* __enext = _M_ext_buf; 2269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block typename _Codecvt::result __status 2279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block = _M_codecvt->out(_M_state, __ibegin, __iend, __inext, 2289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf, _M_ext_buf_EOS, __enext); 2299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__status == _Codecvt::noconv) { 2309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend) 2319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ? traits_type::not_eof(__c) 2329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block : _M_output_error(); 2339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // For a constant-width encoding we know that the external buffer 2369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // is large enough, so failure to consume the entire internal buffer 2379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // or to produce the correct number of external characters, is an error. 2389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // For a variable-width encoding, however, we require only that we 2399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // consume at least one internal character 2409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (__status != _Codecvt::error && 2419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (((__inext == __iend) && 2429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (__enext - _M_ext_buf == _M_width * (__iend - __ibegin))) || 2439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (!_M_constant_width && __inext != __ibegin))) { 2449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // We successfully converted part or all of the internal buffer. 2459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ptrdiff_t __n = __enext - _M_ext_buf; 2469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_write(_M_ext_buf, __n)) 2479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __ibegin += __inext - __ibegin; 2489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 2499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _M_output_error(); 2509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 2529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _M_output_error(); 2539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::not_eof(__c); 2569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 2579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 2589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function must be called before any I/O has been 2599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// performed on the stream, otherwise it has no effect. 2609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// 2619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// __buf == 0 && __n == 0 means to make this stream unbuffered. 2629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// __buf != 0 && __n > 0 means to use __buf as the stream's internal 2639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// buffer, rather than the buffer that would otherwise be allocated 2649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// automatically. __buf must be a pointer to an array of _CharT whose 2659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// size is at least __n. 2669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 2679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_streambuf<_CharT, _Traits>* 2689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::setbuf(_CharT* __buf, streamsize __n) { 2699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode && 2709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf == 0) { 2719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__buf == 0 && __n == 0) 2729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_allocate_buffers(0, 1); 2739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (__buf != 0 && __n > 0) 2749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_allocate_buffers(__buf, __n); 2759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 2769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return this; 2779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 2789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 279e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_ASSERTIONS) 280e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// helper class. 281e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scotttemplate <class _CharT> 282e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct _Filebuf_Tmp_Buf { 283e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _CharT* _M_ptr; 284e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Filebuf_Tmp_Buf(ptrdiff_t __n) : _M_ptr(0) { _M_ptr = new _CharT[__n]; } 285e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ~_Filebuf_Tmp_Buf() { delete[] _M_ptr; } 286e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 287e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 288e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 2899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 2909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_pos_type__ 2919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, 2929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ios_base::seekdir __whence, 2939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ios_base::openmode /* dummy */) { 294e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!this->is_open()) 295e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return pos_type(-1); 2969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 297e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!_M_constant_width && __off != 0) 298e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return pos_type(-1); 299e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 300e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!_M_seek_init(__off != 0 || __whence != ios_base::cur)) 301e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return pos_type(-1); 302e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 303e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Seek to beginning or end, regardless of whether we're in input mode. 304e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__whence == ios_base::beg || __whence == ios_base::end) 305e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), 306e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _State_type()); 307e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 308e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Seek relative to current position. Complicated if we're in input mode. 309e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_ASSERT(__whence == ios_base::cur) 310e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (!_M_in_input_mode) 311e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence), 312e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _State_type()); 313e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 314e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_M_mmap_base != 0) { 315e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // __off is relative to gptr(). We need to do a bit of arithmetic 316e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // to get an offset relative to the external file pointer. 317e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott streamoff __adjust = _M_mmap_len - (this->gptr() - (_CharT*) _M_mmap_base); 318e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 319e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // if __off == 0, we do not need to exit input mode and to shift file pointer 320e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __adjust) 321e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott : _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type()); 322e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 323e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 324e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_M_constant_width) { // Get or set the position. 325e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott streamoff __iadj = _M_width * (this->gptr() - this->eback()); 326e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 327e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Compensate for offset relative to gptr versus offset relative 328e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // to external pointer. For a text-oriented stream, where the 329e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // compensation is more than just pointer arithmetic, we may get 330e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // but not set the current position. 3319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 332e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__iadj <= _M_ext_buf_end - _M_ext_buf) { 333e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott streamoff __eadj = _M_base._M_get_offset(_M_ext_buf + __STATIC_CAST(ptrdiff_t, __iadj), _M_ext_buf_end); 334e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 335e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj) 336e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott : _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type()); 3379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 338e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 339e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott else { // Get the position. Encoding is var width. 340e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Get position in internal buffer. 341e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ptrdiff_t __ipos = this->gptr() - this->eback(); 342e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 343e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Get corresponding position in external buffer. 344e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _State_type __state = _M_state; 345e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott int __epos = _M_codecvt->length(__state, _M_ext_buf, _M_ext_buf_converted, 346e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __ipos); 347e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (_STLP_ASSERTIONS) 348e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Sanity check (expensive): make sure __epos is the right answer. 349e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_ASSERT(__epos >= 0) 350e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _State_type __tmp_state = _M_state; 351e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _Filebuf_Tmp_Buf<_CharT> __buf(__ipos); 352e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _CharT* __ibegin = __buf._M_ptr; 353e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _CharT* __inext = __ibegin; 354e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott const char* __dummy; 355e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott typename _Codecvt::result __status 356e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott = _M_codecvt->in(__tmp_state, 357e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_ext_buf, _M_ext_buf + __epos, __dummy, 358e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott __ibegin, __ibegin + __ipos, __inext); 359e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // The result code is necessarily ok because: 360e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // - noconv: impossible for a variable encoding 361e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // - error: length method is supposed to count until it reach max value or find an error so we cannot have 362e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // an error again when decoding an external buffer up to length return value. 363e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // - partial: idem error, it is also a reason for length to stop counting. 364e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_ASSERT(__status == _Codecvt::ok) 365e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_ASSERT(__inext == __ibegin + __ipos) 366e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _STLP_ASSERT(equal(this->eback(), this->gptr(), __ibegin, _STLP_PRIV _Eq_traits<traits_type>())) 367e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 368e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Get the current position (at the end of the external buffer), 369e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // then adjust it. Again, it might be a text-oriented stream. 370e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott streamoff __cur = _M_base._M_seek(0, ios_base::cur); 371e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott streamoff __adj = _M_base._M_get_offset(_M_ext_buf, _M_ext_buf + __epos) - 372e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_base._M_get_offset(_M_ext_buf, _M_ext_buf_end); 373e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__cur != -1 && __cur + __adj >= 0) 374e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return __off == 0 ? pos_type(__cur + __adj) 375e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott : _M_seek_return(__cur + __adj, __state); 3769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 3779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return pos_type(-1); 3799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 3809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 3839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_pos_type__ 3849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __pos, 3859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ios_base::openmode /* dummy */) { 3869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (this->is_open()) { 3879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_seek_init(true)) 3889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return pos_type(-1); 3899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamoff __off = off_type(__pos); 3919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__off != -1 && _M_base._M_seek(__off, ios_base::beg) != -1) { 3929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_state = __pos.state(); 3939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _M_seek_return(__off, __pos.state()); 3949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 3959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 3969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 3979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return pos_type(-1); 3989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 3999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockint basic_filebuf<_CharT, _Traits>::sync() { 4039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_output_mode) 4049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::eq_int_type(this->overflow(traits_type::eof()), 4059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block traits_type::eof()) ? -1 : 0; 4069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return 0; 4079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 4089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Change the filebuf's locale. This member function has no effect 4119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// unless it is called before any I/O is performed on the stream. 4129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) { 4149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_in_input_mode && !_M_in_output_mode && !_M_in_error_mode) { 4159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->_M_setup_codecvt(__loc); 4169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 4179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 4189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------------------------------------- 4209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// basic_filebuf<> helper functions. 4219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------- 4239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper functions for switching between modes. 4249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called if we're performing the first I/O 4269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// operation on a filebuf, or if we're performing an input operation 4279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// immediately after a seek. 4289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_switch_to_input_mode() { 430e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (this->is_open() && (((int)_M_base.__o_mode() & (int)ios_base::in) !=0) 4319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block && (_M_in_output_mode == 0) && (_M_in_error_mode == 0)) { 4329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_int_buf && !_M_allocate_buffers()) 4339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 4349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_converted = _M_ext_buf; 4369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_end = _M_ext_buf; 4379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_end_state = _M_state; 4399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_input_mode = true; 4419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 4429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 4439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 4459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 4469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called if we're performing the first I/O 4499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// operation on a filebuf, or if we're performing an output operation 4509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// immediately after a seek. 4519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_switch_to_output_mode() { 4539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (this->is_open() && (_M_base.__o_mode() & (int)ios_base::out) && 4549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_input_mode == 0 && _M_in_error_mode == 0) { 4559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_int_buf && !_M_allocate_buffers()) 4579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 4589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // In append mode, every write does an implicit seek to the end 4609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // of the file. Whenever leaving output mode, the end of file 4619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // get put in the initial shift state. 4629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_base.__o_mode() & ios_base::app) 4639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_state = _State_type(); 4649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setp(_M_int_buf, _M_int_buf_EOS - 1); 4669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_output_mode = true; 4679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 4689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 4699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 4719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 4729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------- 4759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper functions for input 4769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called if there is an error during input. 4789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It puts the filebuf in error mode, clear the get area buffer, and 4799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// returns eof. 4809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// returns eof. Error mode is sticky; it is cleared only by close or 4819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// seek. 4829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_int_type__ 4859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::_M_input_error() { 4869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->_M_exit_input_mode(); 4879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_output_mode = false; 4889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_error_mode = true; 4899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setg(0, 0, 0); 4909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::eof(); 4919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 4929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 4939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 4949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_int_type__ 4959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::_M_underflow_aux() { 4969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // We have the state and file position from the end of the internal 4979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // buffer. This round, they become the beginning of the internal buffer. 4989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_state = _M_end_state; 4999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Fill the external buffer. Start with any leftover characters that 5019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // didn't get converted last time. 5029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_ext_buf_end > _M_ext_buf_converted) 5039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 504e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_ext_buf_end = _STLP_STD::copy(_M_ext_buf_converted, _M_ext_buf_end, _M_ext_buf); 5059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // boris : copy_backward did not work 5069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //_M_ext_buf_end = copy_backward(_M_ext_buf_converted, _M_ext_buf_end, 5079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //_M_ext_buf+ (_M_ext_buf_end - _M_ext_buf_converted)); 5089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else 5099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_end = _M_ext_buf; 5109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Now fill the external buffer with characters from the file. This is 5129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // a loop because occasionally we don't get enough external characters 5139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // to make progress. 5149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block for (;;) { 5159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ptrdiff_t __n = _M_base._M_read(_M_ext_buf_end, _M_ext_buf_EOS - _M_ext_buf_end); 516e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__n < 0) { 517e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Read failed, maybe we should set err bit on associated stream... 518e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott this->setg(0, 0, 0); 519e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return traits_type::eof(); 520e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 5219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 522e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott _M_ext_buf_end += __n; 523e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 524e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // If external buffer is empty there is nothing to do. 525e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (_M_ext_buf == _M_ext_buf_end) { 526e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott this->setg(0, 0, 0); 5279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::eof(); 528e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 5299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Convert the external buffer to internal characters. 531e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott const char* __enext; 5329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _CharT* __inext; 5339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block typename _Codecvt::result __status 5359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block = _M_codecvt->in(_M_end_state, 5369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf, _M_ext_buf_end, __enext, 5379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf, _M_int_buf_EOS, __inext); 5389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 539e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* Error conditions: 540e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * (1) Return value of error. 541e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * (2) Producing internal characters without consuming external characters. 542e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * (3) In fixed-width encodings, producing an internal sequence whose length 543e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * is inconsistent with that of the internal sequence. 544e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * (4) Failure to produce any characters if we have enough characters in 545e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * the external buffer, where "enough" means the largest possible width 546e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * of a single character. */ 5479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__status == _Codecvt::noconv) 5489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _Noconv_input<_Traits>::_M_doit(this); 5499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (__status == _Codecvt::error || 550e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott (__inext != _M_int_buf && __enext == _M_ext_buf) || 551e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott (_M_constant_width && (__inext - _M_int_buf) * _M_width != (__enext - _M_ext_buf)) || 552e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott (__inext == _M_int_buf && __enext - _M_ext_buf >= _M_max_width)) 5539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _M_input_error(); 5549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (__inext != _M_int_buf) { 5559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_converted = _M_ext_buf + (__enext - _M_ext_buf); 5569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setg(_M_int_buf, _M_int_buf, __inext); 5579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::to_int_type(*_M_int_buf); 5589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 559e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott /* We need to go around the loop again to get more external characters. 560e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * But if the previous read failed then don't try again for now. 561e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Don't enter error mode for a failed read. Error mode is sticky, 562e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * and we might succeed if we try again. */ 563e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (__n <= 0) { 564e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott this->setg(0, 0, 0); 565e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return traits_type::eof(); 566e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott } 5679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 5689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 5699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------- 5719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper functions for output 5729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called if there is an error during output. 5749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// It puts the filebuf in error mode, clear the put area buffer, and 5759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// returns eof. Error mode is sticky; it is cleared only by close or 5769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// seek. 5779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 5789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block__BF_int_type__ 5799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbasic_filebuf<_CharT, _Traits>::_M_output_error() { 5809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_output_mode = false; 5819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_input_mode = false; 5829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_error_mode = true; 5839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setp(0, 0); 5849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return traits_type::eof(); 5859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 5869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 5889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Write whatever sequence of characters is necessary to get back to 5899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// the initial shift state. This function overwrites the external 5909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// buffer, changes the external file position, and changes the state. 5919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Precondition: the internal buffer is empty. 5929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 5939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_unshift() { 5949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_output_mode && !_M_constant_width) { 5959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block typename _Codecvt::result __status; 5969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block do { 5979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block char* __enext = _M_ext_buf; 5989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __status = _M_codecvt->unshift(_M_state, 5999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf, _M_ext_buf_EOS, __enext); 6009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__status == _Codecvt::noconv || 6019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (__enext == _M_ext_buf && __status == _Codecvt::ok)) 6029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 6039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (__status == _Codecvt::error) 6049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 6059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else if (!_M_write(_M_ext_buf, __enext - _M_ext_buf)) 6069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 6079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } while (__status == _Codecvt::partial); 6089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 6099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 6119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 6129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------- 6159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper functions for buffer allocation and deallocation 6169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// This member function is called when we're initializing a filebuf's 6189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// internal and external buffers. The argument is the size of the 6199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// internal buffer; the external buffer is sized using the character 6209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// width in the current encoding. Preconditions: the buffers are currently 6219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// null. __n >= 1. __buf is either a null pointer or a pointer to an 6229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// array show size is at least __n. 6239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// We need __n >= 1 for two different reasons. For input, the base 6259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// class always needs a buffer because of the semantics of underflow(). 6269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// For output, we want to have an internal buffer that's larger by one 6279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// element than the buffer that the base class knows about. (See 6289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// basic_filebuf<>::overflow() for the reason.) 6299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 6309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers(_CharT* __buf, streamsize __n) { 6319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //The major hypothesis in the following implementation is that size_t is unsigned. 6329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //We also need streamsize byte representation to be larger or equal to the int 6339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //representation to correctly store the encoding information. 6349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _STLP_STATIC_ASSERT(!numeric_limits<size_t>::is_signed && 6359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block sizeof(streamsize) >= sizeof(int)) 6369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__buf == 0) { 6389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamsize __bufsize = __n * sizeof(_CharT); 6399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //We first check that the streamsize representation can't overflow a size_t one. 6409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //If it can, we check that __bufsize is not higher than the size_t max value. 6419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if ((sizeof(streamsize) > sizeof(size_t)) && 6429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (__bufsize > __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) 6439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 6449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf = __STATIC_CAST(_CharT*, malloc(__STATIC_CAST(size_t, __bufsize))); 6459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_int_buf) 6469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 6479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf_dynamic = true; 6489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 6499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else { 6509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf = __buf; 6519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf_dynamic = false; 6529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 6539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamsize __ebufsiz = (max)(__n * __STATIC_CAST(streamsize, _M_width), 6559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __STATIC_CAST(streamsize, _M_codecvt->max_length())); 656e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 6579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf = 0; 6589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if ((sizeof(streamsize) < sizeof(size_t)) || 6599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ((sizeof(streamsize) == sizeof(size_t)) && numeric_limits<streamsize>::is_signed) || 6609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block (__ebufsiz <= __STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()))) { 6619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf = __STATIC_CAST(char*, malloc(__STATIC_CAST(size_t, __ebufsiz))); 6629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 6639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!_M_ext_buf) { 6659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_deallocate_buffers(); 6669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 6679720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 6689720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6699720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf_EOS = _M_int_buf + __STATIC_CAST(ptrdiff_t, __n); 6709720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_EOS = _M_ext_buf + __STATIC_CAST(ptrdiff_t, __ebufsiz); 6719720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 6729720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 6739720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6749720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Abbreviation for the most common case. 6759720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 6769720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_allocate_buffers() { 6779720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Choose a buffer that's at least 4096 characters long and that's a 6789720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // multiple of the page size. 6799720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block streamsize __default_bufsiz = 6809720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block ((_M_base.__page_size() + 4095UL) / _M_base.__page_size()) * _M_base.__page_size(); 6819720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return _M_allocate_buffers(0, __default_bufsiz); 6829720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 6839720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6849720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 6859720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid basic_filebuf<_CharT, _Traits>::_M_deallocate_buffers() { 6869720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_int_buf_dynamic) 6879720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block free(_M_int_buf); 6889720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block free(_M_ext_buf); 6899720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf = 0; 6909720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_int_buf_EOS = 0; 6919720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf = 0; 6929720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_ext_buf_EOS = 0; 6939720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 6949720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6959720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6969720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block//---------------------------------------- 6979720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Helper functiosn for seek and imbue 6989720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 6999720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 7009720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockbool basic_filebuf<_CharT, _Traits>::_M_seek_init(bool __do_unshift) { 7019720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // If we're in error mode, leave it. 7029720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_error_mode = false; 7039720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7049720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Flush the output buffer if we're in output mode, and (conditionally) 7059720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // emit an unshift sequence. 7069720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_output_mode) { 7079720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block bool __ok = !traits_type::eq_int_type(this->overflow(traits_type::eof()), 7089720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block traits_type::eof()); 7099720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__do_unshift) 7109720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block __ok = __ok && this->_M_unshift(); 7119720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (!__ok) { 7129720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_output_mode = false; 7139720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_in_error_mode = true; 7149720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block this->setp(0, 0); 7159720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return false; 7169720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 7179720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 7189720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7199720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block // Discard putback characters, if any. 7209720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (_M_in_input_mode && _M_in_putback_mode) 7219720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_exit_putback_mode(); 7229720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7239720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block return true; 7249720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 7259720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7269720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7279720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block/* Change the filebuf's locale. This member function has no effect 7289720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * unless it is called before any I/O is performed on the stream. 7299720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * This function is called on construction and on an imbue call. In the 7309720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * case of the construction the codecvt facet might be a custom one if 7319720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * the basic_filebuf user has instanciate it with a custom char_traits. 7329720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block * The user will have to call imbue before any I/O operation. 7339720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block */ 7349720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blocktemplate <class _CharT, class _Traits> 7359720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Blockvoid basic_filebuf<_CharT, _Traits>::_M_setup_codecvt(const locale& __loc, bool __on_imbue) { 7369720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (has_facet<_Codecvt>(__loc)) { 7379720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_codecvt = &use_facet<_Codecvt>(__loc) ; 7389720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block int __encoding = _M_codecvt->encoding(); 7399720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7409720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_width = (max)(__encoding, 1); 7419720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_max_width = _M_codecvt->max_length(); 7429720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_constant_width = __encoding > 0; 7439720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_always_noconv = _M_codecvt->always_noconv(); 7449720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 7459720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block else { 7469720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_codecvt = 0; 7479720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_width = _M_max_width = 1; 7489720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block _M_constant_width = _M_always_noconv = false; 7499720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block if (__on_imbue) { 7509720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block //This call will generate an exception reporting the problem. 7519720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block use_facet<_Codecvt>(__loc); 7529720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 7539720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block } 7549720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block} 7559720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7569720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block_STLP_END_NAMESPACE 7579720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7589720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# undef __BF_int_type__ 7599720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# undef __BF_pos_type__ 7609720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block# undef __BF_off_type__ 7619720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7629720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block#endif /* _STLP_FSTREAM_C */ 7639720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block 7649720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// Local Variables: 7659720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// mode:C++ 7669720d5f59b9c1f5d1b9ecbc9173dbcb71bd557beSteve Block// End: 767