Abstraction for External Representations
Synopsis
#include <streambuf>
namespace std {
template <typename cT, typename traits = char_traits<cT> >
class basic_streambuf
{
public:
typedef cT char_type;
typedef traits traits_type;
typedef typename traits::int_type int_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
virtual ~basic_streambuf();
// locale access:
locale pubimbue(locale const& loc);
locale getloc() const;
// buffer and position handling:
basic_streambuf* pubsetbuf(char_type* buf, streamsize n);
pos_type pubseekoff(off_type off, ios_base::seekdir dir, ios_base::openmode which);
pos_type pubseekpos(pos_type pos, ios_base::openmode which);
int pubsync();
// get area:
streamsize in_avail();
int_type snextc();
int_type sbumpc();
int_type sgetc();
streamsize sgetn(char_type* buf, streamsize n);
int_type sputbackc(char_type c);
int_type sungetc();
// put area:
int_type sputc(char_type c);
streamsize sputn(char_type const* buf, streamsize n);
protected:
basic_streambuf]();
// locale, buffer, and position handling:
virtual void imbue(locale const& loc);
virtual basic_streambuf* setbuf(char_type* buf, streamsize n);
virtual pos_type seekoff(off_type offset, ios_base::seekdir dir, ios_base::openmode which);
virtual pos_type seekpos(pos_type position, ios_base::openmode which);
virtual int sync();
// get area:
char_type* eback() const;
char_type* gptr() const;
char_type* egptr() const;
void gbump(streamsize n);
void setg(char_type* beg, char_type* cur, char_type* end);
virtual int showmanyc();
virtual streamsize xsgetn(char_type* buf, streamsize n);
virtual int_type underflow();
virtual int_type uflow();
virtual int_type pbackfail(int_type c = traits_type::eof());
// put area:
char_type* pbase() const;
char_type* pptr() const;
char_type* epptr() const;
void pbump(streamsize n);
void setp(char_type* beg, char_type* end);
virtual streamsize xsputn(char_type const* buf, streamsize n);
virtual int_type overflow(int_type c);
};
typedef basic_streambuf<char> streambuf;
typedef basic_streambuf<wchar_t> wstreambuf;
} // namespace std
Description
The template class basic_streambuf is the workhorse of the
IOStream library: This class provides the interface to read characters
from and write characters to some sequence. Although the actual reading
and writing is done in derived classes, basic_streambuf still
provides the functionality necessary for buffering. However, whether
the stream buffer in use actually buffers input and/or output is
transparent to the user of the class. There are two functions which
aid in buffer maintainance, namely pubsync()
and pubsetbuf(), but the effect, if any,
is dependent on the concrete stream buffer type. The public interface
of basic_streambuf provides mainly functions for reading and
writing of characters and for manipulation of the read and write
positions within the stream.
The protected interface provides the overrideable function and all
necessary functions for buffer manipulation. Using these functions it
is fairly easy to create a stream buffer accessing a new external
representation like a GUI window, a compressed file, a socket,
you name it. When creating a new stream buffer, it can be decided
whether the stream is buffered or not. However, there is a fair
chance that buffered I/O is faster, at least when using the standard
specializations for basic_streambuf, because in this case the
public interface can be bypassed, effectively hoisting certain tests
out of the inner loop. On the other hand, especially for filtering
stream buffers (i.e. stream buffers using another stream buffer
doing the actual I/O but processing the read or written characters e.g. to
compress/uncompress them), buffering can introduce synchronization
problems when the sequence underlying a stream buffer is used using
multiple stream buffers or even multiple programs.
Public Interface
The public interface of basic_streambuf is fairly simple but
still rarely used directly: Normally, it is sufficient to have
basic_istream read characters from and
basic_ostream write characters to the
the stream buffer underlying the corresponding stream. ... and even
if the stream buffer is used directly, it is often accessed using
istreambuf_iterator or
ostreambuf_iterator.
Unless you have specific needs, this is probably sufficient but in
some situations it may be more convenient or more efficient to use
the stream buffer directly.
In the following sections, an error might be indicated by an
exception being thrown. This is not always explicitly mentioned.
Instead, only the error reporting mechanism not using exceptions
is described but it should be kept in mind that all of these
functions might throw an exception to indicate an error.
The stream buffer functions often use traits::eof() to
indicate an error or an invalid character. To represent either a
character value of the value traits::eof(), the type
int_type (which is a typedef for
typename traits::int_type) is used. It is thus often
necessary to convert between the character type (char_type)
and the integer type int_type. The conversions are done using
traits::to_char_type() and traits::to_int_type().
Writing Characters
Writing characters to a stream buffer is extremely simple: Using
sputc() you can send individual characters and
with sputn() you can send character sequences.
sputc() returns traits::eof() if an
error occured and sputn() returns the number of
characters written which can be used if writing of all characters
was successful. Note, that due to buffering character do not
necessarily appear immediately in the underlying sequence. To let
them appear you might have to call pubsync()
to flush the buffer.
Reading Characters
Input can be as simple as output: sbumpc()
reads a single character or returns traits::eof() if it
fails to do so. The function sgetn() can be used to read
a sequence of characters. This function returns the number of
characters for error checking. However, the needs when reading
characters are often more complex. For example, during parsing
of input, it is often necessary to first have a look at the
character without extracting it from the sequence. The function
sgetc() can be used for this. If the inspected
character matches the expected format, it can be normally be
extracted and the next character is to be inspected. This is
what the function snextc() is for: It is
basically a sbumpc() followed by a
sgetc().
See Also
Copyright © 1999 Dietmar Kühl (dietmar.kuehl@claas-solutions.de)
Claas Solutions GmbH