1/*
2 * Copyright (c) 1999
3 * Silicon Graphics Computer Systems, Inc.
4 *
5 * Copyright (c) 1999
6 * Boris Fomitchev
7 *
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
10 *
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
16 *
17 */
18#ifndef _STLP_INTERNAL_STREAMBUF
19#define _STLP_INTERNAL_STREAMBUF
20
21#ifndef _STLP_IOS_BASE_H
22#  include <stl/_ios_base.h>      // Needed for ios_base bitfield members.
23#endif                            // <ios_base> includes <iosfwd>.
24
25_STLP_BEGIN_NAMESPACE
26
27//----------------------------------------------------------------------
28// Class basic_streambuf<>, the base class of the streambuf hierarchy.
29
30// A basic_streambuf<> manages an input (get) area and an output (put)
31// area.  Each is described by three pointers: a beginning, an end, and a
32// current position.  basic_streambuf<> contains some very simple member
33// functions that manipulate those six pointers, but almost all of the real
34// functionality gets delegated to protected virtual member functions.
35// All of the public member functions are inline, and most of the protected
36// member functions are virtual.
37
38// Although basic_streambuf<> is not abstract, it is useful only as a base
39// class.  Its virtual member functions have default definitions such that
40// reading from a basic_streambuf<> will always yield EOF, and writing to a
41// basic_streambuf<> will always fail.
42
43// The second template parameter, _Traits, defaults to char_traits<_CharT>.
44// The default is declared in header <iosfwd>, and it isn't declared here
45// because C++ language rules do not allow it to be declared twice.
46
47template <class _CharT, class _Traits>
48class basic_streambuf {
49  friend class basic_istream<_CharT, _Traits>;
50  friend class basic_ostream<_CharT, _Traits>;
51
52public:                         // Typedefs.
53  typedef _CharT                     char_type;
54  typedef typename _Traits::int_type int_type;
55  typedef typename _Traits::pos_type pos_type;
56  typedef typename _Traits::off_type off_type;
57  typedef _Traits                    traits_type;
58
59private:                        // Data members.
60
61  char_type* _M_gbegin;         // Beginning of get area
62  char_type* _M_gnext;          // Current position within the get area
63  char_type* _M_gend;           // End of get area
64
65  char_type* _M_pbegin;         // Beginning of put area
66  char_type* _M_pnext;          // Current position within the put area
67  char_type* _M_pend;           // End of put area
68
69  locale _M_locale;             // The streambuf's locale object
70
71public:                         // Destructor.
72  virtual ~basic_streambuf();
73
74protected:                      // The default constructor.
75  basic_streambuf()
76#if defined (_STLP_MSVC) && (_STLP_MSVC < 1300) && defined (_STLP_USE_STATIC_LIB)
77    //We make it inline to avoid unresolved symbol.
78    : _M_gbegin(0), _M_gnext(0), _M_gend(0),
79      _M_pbegin(0), _M_pnext(0), _M_pend(0),
80      _M_locale()
81  {}
82#else
83  ;
84#endif
85
86protected:                      // Protected interface to the get area.
87  char_type* eback() const { return _M_gbegin; } // Beginning
88  char_type* gptr()  const { return _M_gnext; }  // Current position
89  char_type* egptr() const { return _M_gend; }   // End
90
91  void gbump(int __n) { _M_gnext += __n; }
92  void setg(char_type* __gbegin, char_type* __gnext, char_type* __gend) {
93    _M_gbegin = __gbegin;
94    _M_gnext  = __gnext;
95    _M_gend   = __gend;
96  }
97
98public:
99  // An alternate public interface to the above functions
100  // which allows us to avoid using templated friends which
101  // are not supported on some compilers.
102  char_type* _M_eback() const { return eback(); }
103  char_type* _M_gptr()  const { return gptr(); }
104  char_type* _M_egptr() const { return egptr(); }
105  void _M_gbump(int __n)      { gbump(__n); }
106  void _M_setg(char_type* __gbegin, char_type* __gnext, char_type* __gend)
107  { this->setg(__gbegin, __gnext, __gend); }
108
109protected:                      // Protected interface to the put area
110
111  char_type* pbase() const { return _M_pbegin; } // Beginning
112  char_type* pptr()  const { return _M_pnext; }  // Current position
113  char_type* epptr() const { return _M_pend; }   // End
114
115  void pbump(int __n) { _M_pnext += __n; }
116  void setp(char_type* __pbegin, char_type* __pend) {
117    _M_pbegin = __pbegin;
118    _M_pnext  = __pbegin;
119    _M_pend   = __pend;
120  }
121
122protected:                      // Virtual buffer management functions.
123
124  virtual basic_streambuf<_CharT, _Traits>* setbuf(char_type*, streamsize);
125
126  // Alters the stream position, using an integer offset.  In this
127  // class seekoff does nothing; subclasses are expected to override it.
128  virtual pos_type seekoff(off_type, ios_base::seekdir,
129                           ios_base::openmode = ios_base::in | ios_base::out);
130
131  // Alters the stream position, using a previously obtained streampos.  In
132  // this class seekpos does nothing; subclasses are expected to override it.
133  virtual pos_type
134  seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out);
135
136  // Synchronizes (i.e. flushes) the buffer.  All subclasses are expected to
137  // override this virtual member function.
138  virtual int sync();
139
140
141public:                         // Buffer management.
142  basic_streambuf<_CharT, _Traits>* pubsetbuf(char_type* __s, streamsize __n)
143  { return this->setbuf(__s, __n); }
144
145  pos_type pubseekoff(off_type __offset, ios_base::seekdir __way,
146                      ios_base::openmode __mod = ios_base::in | ios_base::out)
147  { return this->seekoff(__offset, __way, __mod); }
148
149  pos_type pubseekpos(pos_type __sp,
150                      ios_base::openmode __mod = ios_base::in | ios_base::out)
151  { return this->seekpos(__sp, __mod); }
152
153  int pubsync() { return this->sync(); }
154
155protected:                      // Virtual get area functions, as defined in
156                                // 17.5.2.4.3 and 17.5.2.4.4 of the standard.
157  // Returns a lower bound on the number of characters that we can read,
158  // with underflow, before reaching end of file.  (-1 is a special value:
159  // it means that underflow will fail.)  Most subclasses should probably
160  // override this virtual member function.
161  virtual streamsize showmanyc();
162
163  // Reads up to __n characters.  Return value is the number of
164  // characters read.
165  virtual streamsize xsgetn(char_type* __s, streamsize __n);
166
167  // Called when there is no read position, i.e. when gptr() is null
168  // or when gptr() >= egptr().  Subclasses are expected to override
169  // this virtual member function.
170  virtual int_type underflow();
171
172  // Similar to underflow(), but used for unbuffered input.  Most
173  // subclasses should probably override this virtual member function.
174  virtual int_type uflow();
175
176  // Called when there is no putback position, i.e. when gptr() is null
177  // or when gptr() == eback().  All subclasses are expected to override
178  // this virtual member function.
179  virtual int_type pbackfail(int_type = traits_type::eof());
180
181protected:                      // Virtual put area functions, as defined in
182                                // 27.5.2.4.5 of the standard.
183
184  // Writes up to __n characters.  Return value is the number of characters
185  // written.
186  virtual streamsize xsputn(const char_type* __s, streamsize __n);
187
188  // Extension: writes up to __n copies of __c.  Return value is the number
189  // of characters written.
190  virtual streamsize _M_xsputnc(char_type __c, streamsize __n);
191
192  // Called when there is no write position.  All subclasses are expected to
193  // override this virtual member function.
194  virtual int_type overflow(int_type = traits_type::eof());
195
196public:                         // Public members for writing characters.
197  // Write a single character.
198  int_type sputc(char_type __c) {
199    return ((_M_pnext < _M_pend) ? _Traits::to_int_type(*_M_pnext++ = __c)
200      : this->overflow(_Traits::to_int_type(__c)));
201  }
202
203  // Write __n characters.
204  streamsize sputn(const char_type* __s, streamsize __n)
205  { return this->xsputn(__s, __n); }
206
207  // Extension: write __n copies of __c.
208  streamsize _M_sputnc(char_type __c, streamsize __n)
209  { return this->_M_xsputnc(__c, __n); }
210
211private:                        // Helper functions.
212  int_type _M_snextc_aux();
213
214public:                         // Public members for reading characters.
215  streamsize in_avail() {
216    return (_M_gnext < _M_gend) ? (_M_gend - _M_gnext) : this->showmanyc();
217  }
218
219  // Advance to the next character and return it.
220  int_type snextc() {
221  return ( _M_gend - _M_gnext > 1 ?
222             _Traits::to_int_type(*++_M_gnext) :
223             this->_M_snextc_aux());
224  }
225
226  // Return the current character and advance to the next.
227  int_type sbumpc() {
228    return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext++)
229      : this->uflow();
230  }
231
232  // Return the current character without advancing to the next.
233  int_type sgetc() {
234    return _M_gnext < _M_gend ? _Traits::to_int_type(*_M_gnext)
235      : this->underflow();
236  }
237
238  streamsize sgetn(char_type* __s, streamsize __n)
239  { return this->xsgetn(__s, __n); }
240
241  int_type sputbackc(char_type __c) {
242    return ((_M_gbegin < _M_gnext) && _Traits::eq(__c, *(_M_gnext - 1)))
243      ? _Traits::to_int_type(*--_M_gnext)
244      : this->pbackfail(_Traits::to_int_type(__c));
245  }
246
247  int_type sungetc() {
248    return (_M_gbegin < _M_gnext)
249      ? _Traits::to_int_type(*--_M_gnext)
250      : this->pbackfail();
251  }
252
253protected:                      // Virtual locale functions.
254
255  // This is a hook, called by pubimbue() just before pubimbue()
256  // sets the streambuf's locale to __loc.  Note that imbue should
257  // not (and cannot, since it has no access to streambuf's private
258  // members) set the streambuf's locale itself.
259  virtual void imbue(const locale&);
260
261public:                         // Locale-related functions.
262  locale pubimbue(const locale&);
263  locale getloc() const { return _M_locale; }
264
265#if !defined (_STLP_NO_ANACHRONISMS)
266  void stossc() { this->sbumpc(); }
267#endif
268};
269
270#if defined (_STLP_USE_TEMPLATE_EXPORT)
271_STLP_EXPORT_TEMPLATE_CLASS basic_streambuf<char, char_traits<char> >;
272#  if !defined (_STLP_NO_WCHAR_T)
273_STLP_EXPORT_TEMPLATE_CLASS basic_streambuf<wchar_t, char_traits<wchar_t> >;
274#  endif // _STLP_NO_WCHAR_T
275#endif // _STLP_USE_TEMPLATE_EXPORT
276
277_STLP_END_NAMESPACE
278
279#if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
280#  include <stl/_streambuf.c>
281#endif
282
283#endif
284
285// Local Variables:
286// mode:C++
287// End:
288