1 // File based streams -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
32 // ISO C++ 14882: 27.8 File-based streams
40 basic_filebuf<char>::int_type
41 basic_filebuf<char>::_M_underflow_common(bool __bump)
43 int_type __ret = traits_type::eof();
44 bool __testin = _M_mode & ios_base::in;
45 bool __testout = _M_mode & ios_base::out;
49 // Check for pback madness, and if so swich back to the
50 // normal buffers and jet outta here before expensive
55 if (_M_in_cur && _M_in_cur < _M_in_end)
57 __ret = traits_type::to_int_type(*_M_in_cur);
63 // Sync internal and external buffers.
64 // NB: __testget -> __testput as _M_buf_unified here.
65 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
66 bool __testinit = _M_is_indeterminate();
71 else if (_M_in_cur != _M_filepos)
72 _M_file.seekoff(_M_in_cur - _M_filepos,
73 ios_base::cur, ios_base::in);
76 if (__testinit || __testget)
78 streamsize __elen = 0;
79 streamsize __ilen = 0;
80 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
86 _M_set_determinate(__ilen);
88 _M_out_cur = _M_in_cur;
89 __ret = traits_type::to_int_type(*_M_in_cur);
92 else if (_M_buf_size == 1)
94 // If we are synced with stdio, we have to unget the
95 // character we just read so that the file pointer
97 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
98 _M_set_indeterminate();
103 _M_last_overflowed = false;
107 #ifdef _GLIBCPP_USE_WCHAR_T
109 basic_filebuf<wchar_t>::int_type
110 basic_filebuf<wchar_t>::_M_underflow_common(bool __bump)
112 int_type __ret = traits_type::eof();
113 bool __testin = _M_mode & ios_base::in;
114 bool __testout = _M_mode & ios_base::out;
118 // Check for pback madness, and if so swich back to the
119 // normal buffers and jet outta here before expensive
124 if (_M_in_cur && _M_in_cur < _M_in_end)
126 __ret = traits_type::to_int_type(*_M_in_cur);
132 // Sync internal and external buffers.
133 // NB: __testget -> __testput as _M_buf_unified here.
134 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
135 bool __testinit = _M_is_indeterminate();
139 _M_really_overflow();
140 else if (_M_in_cur != _M_filepos)
141 _M_file.seekoff(_M_in_cur - _M_filepos,
142 ios_base::cur, ios_base::in);
145 if (__testinit || __testget)
147 const locale __loc = this->getloc();
148 const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
150 streamsize __elen = 0;
151 streamsize __ilen = 0;
152 if (__cvt.always_noconv())
154 __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
160 char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
161 __elen = _M_file.xsgetn(__buf, _M_buf_size);
165 codecvt_base::result __r;
166 __r = __cvt.in(_M_state_cur, __buf,
167 __buf + __elen, __eend, _M_in_beg,
168 _M_in_beg + _M_buf_size, __iend);
169 if (__r == codecvt_base::ok)
170 __ilen = __iend - _M_in_beg;
175 _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
181 _M_set_determinate(__ilen);
183 _M_out_cur = _M_in_cur;
184 __ret = traits_type::to_int_type(*_M_in_cur);
187 else if (_M_buf_size == 1)
189 // If we are synced with stdio, we have to unget the
190 // character we just read so that the file pointer
192 _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
193 _M_set_indeterminate();
198 _M_last_overflowed = false;