• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// -*- C++ -*-
2//===------------------------- streambuf ----------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_STEAMBUF
12#define _LIBCPP_STEAMBUF
13
14/*
15    streambuf synopsis
16
17namespace std
18{
19
20template <class charT, class traits = char_traits<charT> >
21class basic_streambuf
22{
23public:
24    // types:
25    typedef charT char_type;
26    typedef traits traits_type;
27    typedef typename traits_type::int_type int_type;
28    typedef typename traits_type::pos_type pos_type;
29    typedef typename traits_type::off_type off_type;
30
31    virtual ~basic_streambuf();
32
33    // 27.6.2.2.1 locales:
34    locale pubimbue(const locale& loc);
35    locale getloc() const;
36
37    // 27.6.2.2.2 buffer and positioning:
38    basic_streambuf* pubsetbuf(char_type* s, streamsize n);
39    pos_type pubseekoff(off_type off, ios_base::seekdir way,
40                        ios_base::openmode which = ios_base::in | ios_base::out);
41    pos_type pubseekpos(pos_type sp,
42                        ios_base::openmode which = ios_base::in | ios_base::out);
43    int pubsync();
44
45    // Get and put areas:
46    // 27.6.2.2.3 Get area:
47    streamsize in_avail();
48    int_type snextc();
49    int_type sbumpc();
50    int_type sgetc();
51    streamsize sgetn(char_type* s, streamsize n);
52
53    // 27.6.2.2.4 Putback:
54    int_type sputbackc(char_type c);
55    int_type sungetc();
56
57    // 27.6.2.2.5 Put area:
58    int_type sputc(char_type c);
59    streamsize sputn(const char_type* s, streamsize n);
60
61protected:
62    basic_streambuf();
63    basic_streambuf(const basic_streambuf& rhs);
64    basic_streambuf& operator=(const basic_streambuf& rhs);
65    void swap(basic_streambuf& rhs);
66
67    // 27.6.2.3.2 Get area:
68    char_type* eback() const;
69    char_type* gptr() const;
70    char_type* egptr() const;
71    void gbump(int n);
72    void setg(char_type* gbeg, char_type* gnext, char_type* gend);
73
74    // 27.6.2.3.3 Put area:
75    char_type* pbase() const;
76    char_type* pptr() const;
77    char_type* epptr() const;
78    void pbump(int n);
79    void setp(char_type* pbeg, char_type* pend);
80
81    // 27.6.2.4 virtual functions:
82    // 27.6.2.4.1 Locales:
83    virtual void imbue(const locale& loc);
84
85    // 27.6.2.4.2 Buffer management and positioning:
86    virtual basic_streambuf* setbuf(char_type* s, streamsize n);
87    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
88                             ios_base::openmode which = ios_base::in | ios_base::out);
89    virtual pos_type seekpos(pos_type sp,
90                             ios_base::openmode which = ios_base::in | ios_base::out);
91    virtual int sync();
92
93    // 27.6.2.4.3 Get area:
94    virtual streamsize showmanyc();
95    virtual streamsize xsgetn(char_type* s, streamsize n);
96    virtual int_type underflow();
97    virtual int_type uflow();
98
99    // 27.6.2.4.4 Putback:
100    virtual int_type pbackfail(int_type c = traits_type::eof());
101
102    // 27.6.2.4.5 Put area:
103    virtual streamsize xsputn(const char_type* s, streamsize n);
104    virtual int_type overflow (int_type c = traits_type::eof());
105};
106
107}  // std
108
109*/
110
111#include <__config>
112#include <iosfwd>
113#include <ios>
114
115#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
116#pragma GCC system_header
117#endif
118
119_LIBCPP_BEGIN_NAMESPACE_STD
120
121template <class _CharT, class _Traits>
122class _LIBCPP_TEMPLATE_VIS basic_streambuf
123{
124public:
125    // types:
126    typedef _CharT                         char_type;
127    typedef _Traits                        traits_type;
128    typedef typename traits_type::int_type int_type;
129    typedef typename traits_type::pos_type pos_type;
130    typedef typename traits_type::off_type off_type;
131
132    virtual ~basic_streambuf();
133
134    // 27.6.2.2.1 locales:
135    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
136    locale pubimbue(const locale& __loc) {
137        imbue(__loc);
138        locale __r = __loc_;
139        __loc_ = __loc;
140        return __r;
141    }
142
143    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
144    locale getloc() const { return __loc_; }
145
146    // 27.6.2.2.2 buffer and positioning:
147    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
148    basic_streambuf* pubsetbuf(char_type* __s, streamsize __n)
149    { return setbuf(__s, __n); }
150
151    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
152    pos_type pubseekoff(off_type __off, ios_base::seekdir __way,
153                        ios_base::openmode __which = ios_base::in | ios_base::out)
154    { return seekoff(__off, __way, __which); }
155
156    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
157    pos_type pubseekpos(pos_type __sp,
158                        ios_base::openmode __which = ios_base::in | ios_base::out)
159    { return seekpos(__sp, __which); }
160
161    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
162    int pubsync() { return sync(); }
163
164    // Get and put areas:
165    // 27.6.2.2.3 Get area:
166    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
167    streamsize in_avail() {
168        if (__ninp_ < __einp_)
169            return static_cast<streamsize>(__einp_ - __ninp_);
170        return showmanyc();
171    }
172
173    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
174    int_type snextc() {
175        if (sbumpc() == traits_type::eof())
176            return traits_type::eof();
177        return sgetc();
178    }
179
180    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
181    int_type sbumpc() {
182        if (__ninp_ == __einp_)
183            return uflow();
184        return traits_type::to_int_type(*__ninp_++);
185    }
186
187    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
188    int_type sgetc() {
189        if (__ninp_ == __einp_)
190            return underflow();
191        return traits_type::to_int_type(*__ninp_);
192    }
193
194    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
195    streamsize sgetn(char_type* __s, streamsize __n)
196    { return xsgetn(__s, __n); }
197
198    // 27.6.2.2.4 Putback:
199    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
200    int_type sputbackc(char_type __c) {
201        if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
202            return pbackfail(traits_type::to_int_type(__c));
203        return traits_type::to_int_type(*--__ninp_);
204    }
205
206    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
207    int_type sungetc() {
208        if (__binp_ == __ninp_)
209          return pbackfail();
210        return traits_type::to_int_type(*--__ninp_);
211    }
212
213    // 27.6.2.2.5 Put area:
214    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
215    int_type sputc(char_type __c) {
216        if (__nout_ == __eout_)
217            return overflow(traits_type::to_int_type(__c));
218        *__nout_++ = __c;
219        return traits_type::to_int_type(__c);
220    }
221
222    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
223    streamsize sputn(const char_type* __s, streamsize __n)
224    { return xsputn(__s, __n); }
225
226protected:
227    basic_streambuf();
228    basic_streambuf(const basic_streambuf& __rhs);
229    basic_streambuf& operator=(const basic_streambuf& __rhs);
230    void swap(basic_streambuf& __rhs);
231
232    // 27.6.2.3.2 Get area:
233    _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;}
234    _LIBCPP_ALWAYS_INLINE char_type* gptr()  const {return __ninp_;}
235    _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;}
236
237    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
238    void gbump(int __n) { __ninp_ += __n; }
239
240    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
241    void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
242        __binp_ = __gbeg;
243        __ninp_ = __gnext;
244        __einp_ = __gend;
245    }
246
247    // 27.6.2.3.3 Put area:
248    _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;}
249    _LIBCPP_ALWAYS_INLINE char_type* pptr()  const {return __nout_;}
250    _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;}
251
252    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
253    void pbump(int __n) { __nout_ += __n; }
254
255    inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY
256    void setp(char_type* __pbeg, char_type* __pend) {
257        __bout_ = __nout_ = __pbeg;
258        __eout_ = __pend;
259    }
260
261    // 27.6.2.4 virtual functions:
262    // 27.6.2.4.1 Locales:
263    virtual void imbue(const locale& __loc);
264
265    // 27.6.2.4.2 Buffer management and positioning:
266    virtual basic_streambuf* setbuf(char_type* __s, streamsize __n);
267    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
268                             ios_base::openmode __which = ios_base::in | ios_base::out);
269    virtual pos_type seekpos(pos_type __sp,
270                             ios_base::openmode __which = ios_base::in | ios_base::out);
271    virtual int sync();
272
273    // 27.6.2.4.3 Get area:
274    virtual streamsize showmanyc();
275    virtual streamsize xsgetn(char_type* __s, streamsize __n);
276    virtual int_type underflow();
277    virtual int_type uflow();
278
279    // 27.6.2.4.4 Putback:
280    virtual int_type pbackfail(int_type __c = traits_type::eof());
281
282    // 27.6.2.4.5 Put area:
283    virtual streamsize xsputn(const char_type* __s, streamsize __n);
284    virtual int_type overflow(int_type __c = traits_type::eof());
285
286private:
287    locale __loc_;
288    char_type* __binp_;
289    char_type* __ninp_;
290    char_type* __einp_;
291    char_type* __bout_;
292    char_type* __nout_;
293    char_type* __eout_;
294};
295
296template <class _CharT, class _Traits>
297basic_streambuf<_CharT, _Traits>::~basic_streambuf()
298{
299}
300
301template <class _CharT, class _Traits>
302basic_streambuf<_CharT, _Traits>::basic_streambuf()
303    : __binp_(0),
304      __ninp_(0),
305      __einp_(0),
306      __bout_(0),
307      __nout_(0),
308      __eout_(0)
309{
310}
311
312template <class _CharT, class _Traits>
313basic_streambuf<_CharT, _Traits>::basic_streambuf(const basic_streambuf& __sb)
314    : __loc_(__sb.__loc_),
315      __binp_(__sb.__binp_),
316      __ninp_(__sb.__ninp_),
317      __einp_(__sb.__einp_),
318      __bout_(__sb.__bout_),
319      __nout_(__sb.__nout_),
320      __eout_(__sb.__eout_)
321{
322}
323
324template <class _CharT, class _Traits>
325basic_streambuf<_CharT, _Traits>&
326basic_streambuf<_CharT, _Traits>::operator=(const basic_streambuf& __sb)
327{
328    __loc_ = __sb.__loc_;
329    __binp_ = __sb.__binp_;
330    __ninp_ = __sb.__ninp_;
331    __einp_ = __sb.__einp_;
332    __bout_ = __sb.__bout_;
333    __nout_ = __sb.__nout_;
334    __eout_ = __sb.__eout_;
335    return *this;
336}
337
338template <class _CharT, class _Traits>
339void
340basic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb)
341{
342    _VSTD::swap(__loc_, __sb.__loc_);
343    _VSTD::swap(__binp_, __sb.__binp_);
344    _VSTD::swap(__ninp_, __sb.__ninp_);
345    _VSTD::swap(__einp_, __sb.__einp_);
346    _VSTD::swap(__bout_, __sb.__bout_);
347    _VSTD::swap(__nout_, __sb.__nout_);
348    _VSTD::swap(__eout_, __sb.__eout_);
349}
350
351template <class _CharT, class _Traits>
352void
353basic_streambuf<_CharT, _Traits>::imbue(const locale&)
354{
355}
356
357template <class _CharT, class _Traits>
358basic_streambuf<_CharT, _Traits>*
359basic_streambuf<_CharT, _Traits>::setbuf(char_type*, streamsize)
360{
361    return this;
362}
363
364template <class _CharT, class _Traits>
365typename basic_streambuf<_CharT, _Traits>::pos_type
366basic_streambuf<_CharT, _Traits>::seekoff(off_type, ios_base::seekdir,
367                                          ios_base::openmode)
368{
369    return pos_type(off_type(-1));
370}
371
372template <class _CharT, class _Traits>
373typename basic_streambuf<_CharT, _Traits>::pos_type
374basic_streambuf<_CharT, _Traits>::seekpos(pos_type, ios_base::openmode)
375{
376    return pos_type(off_type(-1));
377}
378
379template <class _CharT, class _Traits>
380int
381basic_streambuf<_CharT, _Traits>::sync()
382{
383    return 0;
384}
385
386template <class _CharT, class _Traits>
387streamsize
388basic_streambuf<_CharT, _Traits>::showmanyc()
389{
390    return 0;
391}
392
393template <class _CharT, class _Traits>
394streamsize
395basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n)
396{
397    const int_type __eof = traits_type::eof();
398    int_type __c;
399    streamsize __i = 0;
400    while(__i < __n)
401    {
402        if (__ninp_ < __einp_)
403        {
404            const streamsize __len = _VSTD::min(__einp_ - __ninp_, __n - __i);
405            traits_type::copy(__s, __ninp_, __len);
406            __s +=  __len;
407            __i +=  __len;
408            this->gbump(__len);
409        }
410        else if ((__c = uflow()) != __eof)
411        {
412            *__s = traits_type::to_char_type(__c);
413            ++__s;
414            ++__i;
415        }
416        else
417            break;
418    }
419    return __i;
420}
421
422template <class _CharT, class _Traits>
423typename basic_streambuf<_CharT, _Traits>::int_type
424basic_streambuf<_CharT, _Traits>::underflow()
425{
426    return traits_type::eof();
427}
428
429template <class _CharT, class _Traits>
430typename basic_streambuf<_CharT, _Traits>::int_type
431basic_streambuf<_CharT, _Traits>::uflow()
432{
433    if (underflow() == traits_type::eof())
434        return traits_type::eof();
435    return traits_type::to_int_type(*__ninp_++);
436}
437
438template <class _CharT, class _Traits>
439typename basic_streambuf<_CharT, _Traits>::int_type
440basic_streambuf<_CharT, _Traits>::pbackfail(int_type)
441{
442    return traits_type::eof();
443}
444
445template <class _CharT, class _Traits>
446streamsize
447basic_streambuf<_CharT, _Traits>::xsputn(const char_type* __s, streamsize __n)
448{
449    streamsize __i = 0;
450    int_type __eof = traits_type::eof();
451    while( __i < __n)
452    {
453        if (__nout_ >= __eout_)
454        {
455            if (overflow(traits_type::to_int_type(*__s)) == __eof)
456                break;
457            ++__s;
458            ++__i;
459        }
460        else
461        {
462            streamsize __chunk_size = _VSTD::min(__eout_ - __nout_, __n - __i);
463            traits_type::copy(__nout_, __s, __chunk_size);
464            __nout_ += __chunk_size;
465            __s     += __chunk_size;
466            __i     += __chunk_size;
467        }
468    }
469    return __i;
470}
471
472template <class _CharT, class _Traits>
473typename basic_streambuf<_CharT, _Traits>::int_type
474basic_streambuf<_CharT, _Traits>::overflow(int_type)
475{
476    return traits_type::eof();
477}
478
479_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>)
480_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>)
481
482_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>)
483_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>)
484
485_LIBCPP_END_NAMESPACE_STD
486
487#endif  // _LIBCPP_STEAMBUF
488