1 // Stream buffer classes -*- C++ -*-
3 // Copyright (C) 1997-1999 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
31 // ISO C++ 14882: 27.5 Stream buffers
34 #ifndef _CPP_STREAMBUF
35 #define _CPP_STREAMBUF 1
37 #include <bits/c++config.h>
38 #include <bits/std_iosfwd.h>
39 #include <bits/std_cstdio.h> // For SEEK_SET, SEEK_CUR, SEEK_END
40 #include <bits/localefwd.h>
41 #include <bits/ios_base.h>
45 template<typename _CharT, typename _Traits>
47 _S_copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
48 basic_streambuf<_CharT, _Traits>* __sbin,
49 basic_streambuf<_CharT, _Traits>* __sbout);
51 // 27.5.2 Template class basic_streambuf<_CharT, _Traits>
52 template<typename _CharT, typename _Traits>
57 typedef _CharT char_type;
58 typedef typename _Traits::int_type int_type;
59 typedef typename _Traits::pos_type pos_type;
60 typedef typename _Traits::off_type off_type;
61 typedef _Traits traits_type;
63 // Non-standard Types:
64 typedef ctype<_CharT> __ctype_type;
65 typedef basic_streambuf<_CharT, _Traits> __streambuf_type;
67 friend class basic_ios<char_type, traits_type>;
68 friend class basic_istream<char_type, traits_type>;
69 friend class basic_ostream<char_type, traits_type>;
70 friend class istreambuf_iterator<char_type, traits_type>;
71 friend class ostreambuf_iterator<char_type, traits_type>;
74 _S_copy_streambufs<>(basic_ios<_CharT, _Traits>& __ios,
75 basic_streambuf<_CharT, _Traits>* __sbin,
76 basic_streambuf<_CharT, _Traits>* __sbout);
80 // Pointer to the beginning of internally-allocated
81 // space. Filebuf manually allocates/deallocates this, whereas
82 // stringstreams attempt to use the built-in intelligence of the
83 // string class. If you are managing memory, set this. If not,
87 // Size of internal buffer, in bytes.
90 // True iff _M_in_* and _M_out_* buffers should always point to
91 // the same place. True for fstreams, false for sstreams.
94 // This is based on _IO_FILE, just reordered to be more
95 // consistent, and is intended to be the most minimal abstraction
96 // for an internal buffer.
97 // get == input == read
98 // put == output == write
99 char_type* _M_in_cur; // Current read area.
100 char_type* _M_in_beg; // Start of get area.
101 char_type* _M_in_end; // End of get area.
102 char_type* _M_out_cur; // Current put area.
103 char_type* _M_out_beg; // Start of put area.
104 char_type* _M_out_end; // End of put area.
106 // Place to stash in || out || in | out settings for current streambuf.
107 ios_base::openmode _M_mode;
109 // Current locale setting.
110 locale _M_locale_buf;
112 // True iff locale is initialized.
115 // Cached use_facet<ctype>, which is based on the current locale info.
116 const __ctype_type* _M_fctype_buf;
118 // Correctly sets the _M_out_cur pointer, and bumps the
119 // appropriate _M_*_end pointers as well. Necessary for the
120 // un-tied stringbufs, in in|out mode.
122 // __n + _M_out_[cur, end] <= _M_buf + _M_buf_size
123 // Assuming all _M_*_[beg, cur, end] pointers are operating on
125 // _M_buf <= _M_*_ <= _M_buf + _M_buf_size
127 _M_buf_bump(off_type __n) // argument needs to be +-
129 bool __testin = _M_mode & ios_base::in;
130 bool __testout = _M_mode & ios_base::out;
132 if (_M_buf_unified && __testin)
133 _M_in_cur = _M_out_cur;
134 if (_M_out_cur > _M_out_end)
136 _M_out_end = _M_out_cur;
137 if (__testin && __testout && _M_out_end > _M_in_end)
138 _M_in_end = _M_out_cur;
142 // These three functions are used to clarify internal buffer
143 // maintance. After an overflow, or after a seekoff call that
144 // started at beg or end, or possibly when the stream becomes
145 // unbuffered, and a myrid other obscure corner cases, the
146 // internal buffer does not truly reflect the contents of the
147 // external buffer. At this point, for whatever reason, it is in
148 // an indeterminate state.
150 _M_set_indeterminate(void)
152 if (_M_mode & ios_base::in)
153 this->setg(_M_buf, _M_buf, _M_buf);
154 if (_M_mode & ios_base::out)
155 this->setp(_M_buf, _M_buf);
159 _M_set_determinate(off_type __off)
161 bool __testin = _M_mode & ios_base::in;
162 bool __testout = _M_mode & ios_base::out;
165 this->setg(_M_buf, _M_buf, _M_buf + __off);
167 _M_buf_size = static_cast<int_type>(__off);
170 this->setp(_M_buf, _M_buf + __off);
175 _M_is_indeterminate(void)
177 bool __retval = false;
178 if (_M_mode & ios_base::in)
179 __retval = _M_in_beg == _M_in_cur && _M_in_cur == _M_in_end;
180 if (_M_mode & ios_base::out)
181 __retval = _M_out_beg == _M_out_cur && _M_out_cur == _M_out_end;
189 _M_buf_unified = false;
191 _M_mode = ios_base::openmode(0);
192 _M_fctype_buf = NULL;
193 _M_locale_set = false;
198 pubimbue(const locale &__loc)
200 locale __tmp(this->getloc());
209 return _M_locale_buf;
214 // Buffer and positioning:
216 pubsetbuf(char_type* __s, streamsize __n)
217 { return this->setbuf(__s, __n); }
220 pubseekoff(off_type __off, ios_base::seekdir __way,
221 ios_base::openmode __mode = ios_base::in | ios_base::out)
222 { return this->seekoff(__off, __way, __mode); }
225 pubseekpos(pos_type __sp,
226 ios_base::openmode __mode = ios_base::in | ios_base::out)
227 { return this->seekpos(__sp, __mode); }
230 pubsync() { return this->sync(); }
232 // Get and put areas:
238 if (_M_in_cur && _M_in_cur < _M_in_end)
239 __retval = this->egptr() - this->gptr();
241 __retval = this->showmanyc();
248 int_type __eof = traits_type::eof();
249 return (this->sbumpc() == __eof ? __eof : this->sgetc());
259 if (_M_in_cur && _M_in_cur < _M_in_end)
260 __retval = traits_type::to_int_type(*gptr());
262 __retval = this->underflow();
267 sgetn(char_type* __s, streamsize __n)
268 { return this->xsgetn(__s, __n); }
272 sputbackc(char_type __c);
279 sputc(char_type __c);
282 sputn(const char_type* __s, streamsize __n)
283 { return this->xsputn(__s, __n); }
287 : _M_buf(NULL), _M_buf_size(0), _M_buf_unified(false),
288 _M_in_cur(0), _M_in_beg(0), _M_in_end(0), _M_out_cur(0), _M_out_beg(0),
289 _M_out_end(0), _M_mode(ios_base::openmode(0)),
290 _M_locale_buf(locale()), _M_locale_set(false)
291 { _M_fctype_buf = &use_facet<__ctype_type>(this->getloc()); }
295 eback() const { return _M_in_beg; }
298 gptr() const { return _M_in_cur; }
301 egptr() const { return _M_in_end; }
304 gbump(int __n) { _M_in_cur += __n; }
307 setg(char_type* __gbeg, char_type* __gnext, char_type* __gend)
312 if (!(_M_mode & ios_base::in) && __gbeg && __gnext && __gend)
313 _M_mode = _M_mode | ios_base::in;
318 pbase() const { return _M_out_beg; }
321 pptr() const { return _M_out_cur; }
324 epptr() const { return _M_out_end; }
327 pbump(int __n) { _M_out_cur += __n; }
330 setp(char_type* __pbeg, char_type* __pend)
332 _M_out_beg = _M_out_cur = __pbeg;
334 if (!(_M_mode & ios_base::out) && __pbeg && __pend)
335 _M_mode = _M_mode | ios_base::out;
336 // The output sequence is highly tied to _M_buf and
337 // _M_buf_size in addition to the actual pointers into the
338 // buffer. Because of this, (re)set _M_buf_size here, as
339 // sputc/xsputn need _M_buf_size to be accurate. (The
340 // corresponding input functions rely instead on _M_in_end.)
341 _M_buf_size = max(_M_buf_size, static_cast<int_type>(__pend - __pbeg));
344 // Virtual functions:
347 imbue(const locale& __loc)
349 _M_locale_set = true;
350 if (_M_locale_buf != __loc)
352 _M_locale_buf = __loc;
353 _M_fctype_buf = &use_facet<__ctype_type>(_M_locale_buf);
357 // Buffer management and positioning:
358 virtual basic_streambuf<char_type,_Traits>*
359 setbuf(char_type*, streamsize)
363 seekoff(off_type, ios_base::seekdir,
364 ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out)
365 { return pos_type(off_type(-1)); }
369 ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out)
370 { return pos_type(off_type(-1)); }
377 showmanyc() { return 0; }
380 xsgetn(char_type* __s, streamsize __n);
384 { return traits_type::eof(); }
389 int_type __retval = traits_type::eof();
390 bool __testeof = this->underflow() == __retval;
391 bool __testpending = _M_in_cur && _M_in_cur < _M_in_end;
393 if (!__testeof && __testpending)
395 __retval = traits_type::to_int_type(*_M_in_cur);
397 if (_M_buf_unified && _M_mode & ios_base::out)
405 pbackfail(int_type /* __c */ = traits_type::eof())
406 { return traits_type::eof(); }
410 xsputn(const char_type* __s, streamsize __n);
413 overflow(int_type /* __c */ = traits_type::eof())
414 { return traits_type::eof(); }
416 #ifdef _GLIBCPP_DEPRICATED
421 if (_M_in_cur < _M_in_end)
428 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
430 basic_streambuf(const __streambuf_type&);
433 operator=(const __streambuf_type&);
437 typedef basic_streambuf<char> streambuf;
438 typedef basic_streambuf<wchar_t> wstreambuf;
442 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
444 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS
445 #include <bits/streambuf.tcc>
449 #endif /* _CPP_STREAMBUF */