streambuf.tcc (basic_streambuf::sputbackc): Prefix "this->" to call to pbackfail.
[official-gcc.git] / libstdc++-v3 / include / bits / streambuf.tcc
blob5f57df583a7b6bc680f4d94b8abcbf097c5b712a
1 // Stream buffer classes -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
4 // Free Software Foundation, Inc.
5 //
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)
10 // any later version.
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,
20 // USA.
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.5  Stream buffers
35 #ifndef _CPP_BITS_STREAMBUF_TCC
36 #define _CPP_BITS_STREAMBUF_TCC 1
38 #pragma GCC system_header
40 namespace std 
42   template<typename _CharT, typename _Traits>
43     const size_t
44     basic_streambuf<_CharT, _Traits>::_S_pback_size;
46   template<typename _CharT, typename _Traits>
47     typename basic_streambuf<_CharT, _Traits>::int_type
48     basic_streambuf<_CharT, _Traits>::
49     sbumpc()
50     {
51       int_type __ret;
52       if (_M_in_cur && _M_in_cur < _M_in_end)
53         {
54           char_type __c = *(this->gptr());
55           _M_in_cur_move(1);
56           __ret = traits_type::to_int_type(__c);
57         }
58       else 
59         __ret = this->uflow();
60       return __ret;
61     }
63   template<typename _CharT, typename _Traits>
64     typename basic_streambuf<_CharT, _Traits>::int_type
65     basic_streambuf<_CharT, _Traits>::
66     sputbackc(char_type __c) 
67     {
68       int_type __ret;
69       bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
70       bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
71       if (!__testpos || __testne)
72         __ret = this->pbackfail(traits_type::to_int_type(__c));
73       else 
74         {
75           _M_in_cur_move(-1);
76           __ret = traits_type::to_int_type(*this->gptr());
77         }
78       return __ret;
79     }
80   
81   template<typename _CharT, typename _Traits>
82     typename basic_streambuf<_CharT, _Traits>::int_type
83     basic_streambuf<_CharT, _Traits>::
84     sungetc()
85     {
86       int_type __ret;
87       if (_M_in_cur && _M_in_beg < _M_in_cur)
88         {
89           _M_in_cur_move(-1);
90           __ret = traits_type::to_int_type(*_M_in_cur);
91         }
92       else 
93         __ret = this->pbackfail();
94       return __ret;
95     }
97   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
98   // allocated space, and on certain (rare but entirely legal)
99   // situations, there will be no allocated space yet the internal
100   // buffers will still be valid. (This happens if setp is used to set
101   // the internal buffer to say some externally-allocated sequence.)
102   template<typename _CharT, typename _Traits>
103     typename basic_streambuf<_CharT, _Traits>::int_type
104     basic_streambuf<_CharT, _Traits>::
105     sputc(char_type __c)
106     {
107       int_type __ret;
108       if (_M_out_buf_size())
109         {
110           *_M_out_cur = __c;
111           _M_out_cur_move(1);
112           __ret = traits_type::to_int_type(__c);
113         }
114       else
115         __ret = this->overflow(traits_type::to_int_type(__c));
116       return __ret;
117     }
119   template<typename _CharT, typename _Traits>
120     streamsize
121     basic_streambuf<_CharT, _Traits>::
122     xsgetn(char_type* __s, streamsize __n)
123     {
124       streamsize __ret = 0;
125       while (__ret < __n)
126         {
127           size_t __buf_len = _M_in_end - _M_in_cur;
128           if (__buf_len > 0)
129             {
130               size_t __remaining = __n - __ret;
131               size_t __len = min(__buf_len, __remaining);
132               traits_type::copy(__s, _M_in_cur, __len);
133               __ret += __len;
134               __s += __len;
135               _M_in_cur_move(__len);
136             }
137           
138           if (__ret < __n)
139             {
140               int_type __c = this->uflow();  
141               if (!traits_type::eq_int_type(__c, traits_type::eof()))
142                 {
143                   traits_type::assign(*__s++, traits_type::to_char_type(__c));
144                   ++__ret;
145                 }
146               else
147                 break;
148             }
149         }
150       return __ret;
151     }
153   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
154   // allocated space, and on certain (rare but entirely legal)
155   // situations, there will be no allocated space yet the internal
156   // buffers will still be valid. (This happens if setp is used to set
157   // the internal buffer to say some externally-allocated sequence.)
158   template<typename _CharT, typename _Traits>
159     streamsize
160     basic_streambuf<_CharT, _Traits>::
161     xsputn(const char_type* __s, streamsize __n)
162     {
163       streamsize __ret = 0;
164       while (__ret < __n)
165         {
166           off_type __buf_len = _M_out_buf_size();
167           if (__buf_len > 0)
168             {
169               off_type __remaining = __n - __ret;
170               off_type __len = min(__buf_len, __remaining);
171               traits_type::copy(_M_out_cur, __s, __len);
172               __ret += __len;
173               __s += __len;
174               _M_out_cur_move(__len);
175             }
177           if (__ret < __n)
178             {
179               int_type __c = this->overflow(traits_type::to_int_type(*__s));
180               if (!traits_type::eq_int_type(__c, traits_type::eof()))
181                 {
182                   ++__ret;
183                   ++__s;
184                 }
185               else
186                 break;
187             }
188         }
189       return __ret;
190     }
192   // Conceivably, this could be used to implement buffer-to-buffer
193   // copies, if this was ever desired in an un-ambiguous way by the
194   // standard. If so, then checks for __ios being zero would be
195   // necessary.
196   template<typename _CharT, typename _Traits>
197     streamsize
198     __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
199                       basic_streambuf<_CharT, _Traits>* __sbin,
200                       basic_streambuf<_CharT, _Traits>* __sbout) 
201   {
202       typedef typename _Traits::int_type        int_type;
204       streamsize __ret = 0;
205       streamsize __bufsize = __sbin->in_avail();
206       streamsize __xtrct;
207       bool __testput = __sbout->_M_mode & ios_base::out;
208       try 
209         {
210           while (__testput && __bufsize != -1)
211             {
212               if (__bufsize != 0 && __sbin->gptr() != NULL
213                   && __sbin->gptr() + __bufsize <= __sbin->egptr()) 
214                 {
215                   __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
216                   __ret += __xtrct;
217                   __sbin->_M_in_cur_move(__xtrct);
218                   if (__xtrct != __bufsize)
219                     break;
220                 }
221               else 
222                 {
223                   size_t __size =
224                     __sbin->_M_buf_size_opt > 0 ? __sbin->_M_buf_size_opt : 1;
225                   _CharT* __buf =
226                     static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __size));
227                   streamsize __charsread = __sbin->sgetn(__buf, __size);
228                   __xtrct = __sbout->sputn(__buf, __charsread);
229                   __ret += __xtrct;
230                   if (__xtrct != __charsread)
231                     break;
232                 }
233               if (_Traits::eq_int_type(__sbin->sgetc(), _Traits::eof()))
234                 break;
235               __bufsize = __sbin->in_avail();
236             }
237         }
238       catch(exception& __fail) 
239         {
240           __ios.setstate(ios_base::failbit);
241           if ((__ios.exceptions() & ios_base::failbit) != 0)
242             __throw_exception_again;
243         }
244       return __ret;
245     }
247   // Inhibit implicit instantiations for required instantiations,
248   // which are defined via explicit instantiations elsewhere.  
249   // NB:  This syntax is a GNU extension.
250   extern template class basic_streambuf<char>;
251   extern template
252     streamsize
253     __copy_streambufs(basic_ios<char>&, basic_streambuf<char>*,
254                       basic_streambuf<char>*); 
256 #ifdef _GLIBCPP_USE_WCHAR_T
257   extern template class basic_streambuf<wchar_t>;
258   extern template
259     streamsize
260     __copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
261                       basic_streambuf<wchar_t>*); 
262 #endif
263 } // namespace std
265 #endif