The <streambuf>
header declares the basic_streambuf
class template and its two specializations: streambuf
and wstreambuf
. A stream buffer object manages low-level access to a sequence of characters. The characters might be stored in an external file or they might reside entirely in memory. See the <fstream>
and <sstream>
headers for examples of different kinds of stream buffers that are derived from basic_streambuf
.
Most programs do not use stream buffers directly, but use stream classes instead because they provide a higher-level interface. Each stream object has an associated stream buffer object.
Stream buffer
template <class charT, class traits = char_traits<charT> > class basic_streambuf { public: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; virtual ~basic_streambuf(); locale pubimbue(const locale &loc); locale getloc() const; basic_streambuf<char_type,traits>* pubsetbuf(char_type* s, streamsize n); pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); int pubsync(); // Input: streamsize in_avail(); int_type snextc(); int_type sbumpc(); int_type sgetc(); streamsize sgetn(char_type* s, streamsize n); // Putback: int_type sputbackc(char_type c); int_type sungetc(); // Output: int_type sputc(char_type c); streamsize sputn(const char_type* s, streamsize n); protected: basic_streambuf(); // Input: char_type* eback() const; char_type* gptr() const; char_type* egptr() const; void gbump(int n); void setg(char_type* gbeg, char_type* gnext, char_type* gend); // Output: char_type* pbase() const; char_type* pptr() const; char_type* epptr() const; void pbump(int n); void setp(char_type* pbeg, char_type* pend); // Locales: virtual void imbue(const locale &loc); // Buffer management and positioning: virtual basic_streambuf<char_type,traits>* setbuf(char_type* s, streamsize n); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); virtual streamsize showmanyc(); virtual int sync(); virtual int_type underflow(); virtual int_type uflow(); virtual streamsize xsgetn(char_type* s, streamsize n); // Putback: virtual int_type pbackfail(int_type c = traits::eof()); // Output: virtual int_type overflow(int_type c = traits::eof()); virtual streamsize xsputn(const char_type* s, streamsize n); };
The basic_streambuf
class template manages an input buffer and an output buffer, where each buffer is an array of characters. The base character type is a template parameter, charT
. A buffer has three pointers into the array (the names below are not part of the standard, but are used for informational purposes only):
The pointers can all be null pointers, which makes the stream "buffer" unbuffered. If the pointers are not null, the following rules apply:
*
next.[-1]
.*
next.Figure 13-25 depicts an input buffer, where the characters "Hello, world." have been fetched from the input source. So far, the first six characters have been read from the input buffer, and the next character to read is the space between "Hello," and "world."
Figure 13-25: Input stream buffer
Figure 13-26 depicts an output buffer, which has room for twelve characters. So far, the buffer contains the five characters, "Hello".
Figure 13-26: Output stream buffer
Several functions have a split personality: a public function is the public interface. The public function calls a protected, virtual function to do the actual work. (The public function name sometimes starts with pub
, or the protected function has a name that starts with x
.) When using a stream buffer object, say, to implement a stream class, you should call the public function. When implementing a stream buffer class, you should override the protected, virtual function. See base_filebuf
in <fstream>
and base_stringbuf
in <sstream>
for examples of derived classes.
Following are the member functions of basic_streambuf
.
basic_streambuf
()
getloc()
) is initialized to the current global locale.char_type*
eback
() const
char_type*
egptr
() const
char_type*
epptr
() const
void
gbump
(int n)
n
characters.locale
getloc
() const
pubimbue
.char_type*
gptr
() const
virtual void
imbue
(const locale &loc)
imbue
function to take whatever action is needed when the stream buffer's locale is changed. For example, the stream buffer might cache information about the new locale.pubimbue
function calls imbue
before storing the new locale; thus within the call to imbue
, the getloc
function returns the old locale, and the loc
parameter is the new locale.imbue
is to do nothing.streamsize
in_avail
()
egptr()
-
gptr()
if the stream buffer has a read position, or the result of calling showmanyc()
if not.virtual int_type
overflow
(int_type c = traits::eof())
overflow
to flush the output buffer when it is full. The overflow
function handles the sequence of characters stored in the buffer array, or an empty string if the begin and other pointers are null. If c
is not traits::eof()
, c
is appended to the output sequence. For example, a file stream buffer might write the array to the file. If an output error occurs, an exception can be raised or traits::eof()
is returned. For success, any value other than traits::eof()
is returned.virtual int_type
pbackfail
(int_type c = traits::eof())
sungetc
or sputbackc
function try to push back a character, they first attempt to adjust the current input next pointer. This can fail for one of three reasons:gptr()
==
0
).gptr()
==
eback()
)c
, is not the same character that was most recently read, that is, traits::eq(traits::to_char_type(c),
gptr()[-1])
is false)pbackfail
mediates with the external input source, if any, to try to complete the push back operation. For example, a file stream buffer might adjust the external file position so the next character read from the input array will retrieve the pushed back character.c
is traits::eof()
, the input sequence is moved back one position to reread the character at that position. If c
is not traits::eof()
, pbackfail
tries to ensure that the next character read will be c
; the derived class is free to modify the input source, change the stream position, or take another action to push back c
.traits::eof()
for failure or any other value for success. The default behavior of pbackfail
is to do nothing exception return traits::eof()
.char_type*
pbase
() const
void
pbump
(int n)
n
characters.char_type*
pptr
() const
locale
pubimbue
(const locale &loc)
loc
, to the stream buffer. Subsequent calls to getloc
return a copy of loc
. The basic_streambuf
class does not use the locale, but a derived class can use the locale for interpreting multibyte characters.pos_type
pubseekoff
(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out)
seekoff(off,
way,
which)
, which changes the stream position.pos_type
pubseekpos
(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out)
seekpos(off,
way,
which)
, which changes the stream position.basic_streambuf<char_type,traits>*
pubsetbuf
(char_type* s, streamsize n)
setbuf(s,
n)
, which typically sets the begin, next, and end array pointers.int
pubsync
()
sync()
, which synchronizes the internal arrays with the external I/O source, if any. It returns -1 for a failure and any other value for success. The default is to do nothing and return zero.int_type
snextc
()
sbumpc
, and if sbumpc
returns traits::eof()
, snextc
returns traits::eof()
; otherwise it returns sgetc()
.int_type
sbumpc
()
uflow()
; otherwise it returns traits::to_int_type(*gptr())
.virtual pos_type
seekoff
(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out)
static_cast<pos_type>(static_cast<off_type>(-1))
.virtual pos_type
seekpos
(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out)
static_cast<pos_type>(static_cast<off_type>(-1))
.virtual basic_streambuf<char_type,traits>*
setbuf
(char_type* s, streamsize n)
this
.void
setg
(char_type* gbegin, char_type* gnext, char_type* gend)
gbegin
, next = gnext
, and end = gend
.void
setp
(char_type* pbegin, char_type* pend)
pbegin
and end = pend
.int_type
sgetc
()
sgetc
returns underflow; otherwise it returns traits::to_int_type(*gptr())
.streamsize
sgetn
(char_type* s, streamsize n)
xsgetn(s,
n)
.virtual streamsize
showmanyc
()
traits::eof()
. It is returns -1, calls to underflow()
or uflow()
will fail. If the return value is zero, input might be available, but there is no guarantee.int_type
sputbackc
(char_type c)
c
so the next read will return c
. If there is a push back position (gptr()
>
ebase()
), and the most recently read character is c
(traits::eq(c,
gptr()[-1])
), the input next pointer is decremented, and traits::to_int_type(*gptr())
is returned. Otherwise, pbackfile(traits::to_int_type(c))
is returned.int_type
sputc
(char_type c)
c
to the output array and returns traits::to_int_type(c)
, if an output position is available. Otherwise, it returns overflow(traits::to_int_type(c))
.streamsize
sputn
(const char_type* s, streamsize n);
xsputn(s,
n)
to write a string s
of length n
.int_type
sungetc
()
traits::to_int_type(*gptr())
; otherwise it returns pbackfail()
.virtual int
sync
()
virtual int_type
uflow
()
sbumpc
when the input is not buffered (gptr()
==
0
) or the input buffer is empty (gptr()
>=
egptr()
). Input is obtained from the external source and the input pointers are reset.uflow
and underflow
is that uflow
advanced the input next pointer after returning the first character in the buffer, but underflow
does not.traits::to_int_type(*gptr())
if there is a read position or traits::eof()
if there is no more input or for other failure. The default is to do nothing and return traits::eof()
.virtual int_type
underflow
()
sgetc
when the input is not buffered(gptr()
==
0
) or the input buffer is empty (gptr()
>=
egptr()
). Input is obtained from the external source and the input pointers are reset.uflow
and underflow
is that uflow
advanced the input next pointer after returning the first character in the buffer, but underflow
does not.traits::to_int_type(*gptr())
if there is a read position or traits::eof()
if there is no more input or for other failure. The default is to do nothing and return traits::eof()
.virtual streamsize
xsgetn
(char_type* s, streamsize n)
n
characters from the input stream into the character array that s
points to. No null character is appended to s
. It is equivalent to calling sbumpc
up to n
times or until it returns traits::eof()
. The number of characters actually read and stored in s is returned. Derived classes can override this function to provide a more efficient implementation.virtual streamsize
xsputn
(const char_type* s, streamsize n)
n
characters from s
to the output stream. It is equivalent to calling sputc
up to n
times or until it returns traits::eof()
. The number of characters actually written is returned. Derived classes can override this function to provide a more efficient implementation.basic_filebuf in <fstream>, basic_stringbuf in <sstream>
Stream buffer specialization
typedef basic_streambuf<char> streambuf;
The streambuf
class specializes basic_streambuf
for the char
type.
char_traits<char> in <string>
Stream buffer wide character specialization
typedef basic_streambuf<wchar_t> wstreambuf;
The wstreambuf
class specializes basic_streambuf
for the wchar_t
type.
char_traits<wchar_t> in <string>