27 Input/output library [input.output]

27.6 Stream buffers [stream.buffers]

27.6.1 Overview [stream.buffers.overview]

Header <streambuf> synopsis

namespace std {
  template <class charT, class traits = char_traits<charT> >
    class basic_streambuf;
  typedef basic_streambuf<char>     streambuf;
  typedef basic_streambuf<wchar_t> wstreambuf;
}

The header <streambuf> defines types that control input from and output to character sequences.

27.6.2 Stream buffer requirements [streambuf.reqts]

Stream buffers can impose various constraints on the sequences they control. Some constraints are:

  • The controlled input sequence can be not readable.

  • The controlled output sequence can be not writable.

  • The controlled sequences can be associated with the contents of other representations for character sequences, such as external files.

  • The controlled sequences can support operations directly to or from associated sequences.

  • The controlled sequences can impose limitations on how the program can read characters from a sequence, write characters to a sequence, put characters back into an input sequence, or alter the stream position.

Each sequence is characterized by three pointers which, if non-null, all point into the same charT array object. The array object represents, at any moment, a (sub)sequence of characters from the sequence. Operations performed on a sequence alter the values stored in these pointers, perform reads and writes directly to or from associated sequences, and alter “the stream position” and conversion state as needed to maintain this subsequence relationship. The three pointers are:

  • the beginning pointer, or lowest element address in the array (called xbeg here);

  • the next pointer, or next element address that is a current candidate for reading or writing (called xnext here);

  • the end pointer, or first element address beyond the end of the array (called xend here).

The following semantic constraints shall always apply for any set of three pointers for a sequence, using the pointer names given immediately above:

  • If xnext is not a null pointer, then xbeg and xend shall also be non-null pointers into the same charT array, as described above; otherwise, xbeg and xend shall also be null.

  • If xnext is not a null pointer and xnext < xend for an output sequence, then a write position is available. In this case, *xnext shall be assignable as the next element to write (to put, or to store a character value, into the sequence).

  • If xnext is not a null pointer and xbeg < xnext for an input sequence, then a putback position is available. In this case, xnext[-1] shall have a defined value and is the next (preceding) element to store a character that is put back into the input sequence.

  • If xnext is not a null pointer and xnext < xend for an input sequence, then a read position is available. In this case, *xnext shall have a defined value and is the next element to read (to get, or to obtain a character value, from the sequence).

27.6.3 Class template basic_streambuf<charT,traits> [streambuf]

namespace std {
  template <class charT, class traits = char_traits<charT> >
  class basic_streambuf {
  public:

    // types:
    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();

    // [streambuf.locales] locales:
    locale   pubimbue(const locale& loc);
    locale   getloc() const;

    // [streambuf.buffer] buffer and positioning:
    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();

    // Get and put areas:
    // [streambuf.pub.get] Get area:
    streamsize in_avail();
    int_type snextc();
    int_type sbumpc();
    int_type sgetc();
    streamsize sgetn(char_type* s, streamsize n);

    // [streambuf.pub.pback] Putback:
    int_type sputbackc(char_type c);
    int_type sungetc();

    // [streambuf.pub.put] Put area:
    int_type   sputc(char_type c);
    streamsize sputn(const char_type* s, streamsize n);

  protected:
    basic_streambuf();
    basic_streambuf(const basic_streambuf& rhs);
    basic_streambuf& operator=(const basic_streambuf& rhs);

    void swap(basic_streambuf& rhs);

    // [streambuf.get.area] Get area:
    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);

    // [streambuf.put.area] Put area:
    char_type* pbase() const;
    char_type* pptr() const;
    char_type* epptr() const;
    void       pbump(int n);
    void       setp(char_type* pbeg, char_type* pend);

    // [streambuf.virtuals] virtual functions:
    // [streambuf.virt.locales] Locales:
    virtual void imbue(const locale& loc);

    // [streambuf.virt.buffer] 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 int      sync();

    // [streambuf.virt.get] Get area:
    virtual streamsize showmanyc();
    virtual streamsize xsgetn(char_type* s, streamsize n);
    virtual int_type   underflow();
    virtual int_type   uflow();

    // [streambuf.virt.pback] Putback:
    virtual int_type   pbackfail(int_type c = traits::eof());

    // [streambuf.virt.put] Put area:
    virtual streamsize xsputn(const char_type* s, streamsize n);
    virtual int_type   overflow (int_type c = traits::eof());
  };
}

The class template basic_streambuf<charT,traits> serves as an abstract base class for deriving various stream buffers whose objects each control two character sequences:

27.6.3.1 basic_streambuf constructors [streambuf.cons]

basic_streambuf();

Effects: Constructs an object of class basic_streambuf<charT,traits> and initializes:306

  • all its pointer member objects to null pointers,

  • the getloc() member to a copy the global locale, locale(), at the time of construction.

Remarks: Once the getloc() member is initialized, results of calling locale member functions, and of members of facets so obtained, can safely be cached until the next time the member imbue is called.

basic_streambuf(const basic_streambuf& rhs);

Effects: Constructs a copy of rhs.

Postconditions:

  • eback() == rhs.eback()

  • gptr() == rhs.gptr()

  • egptr() == rhs.egptr()

  • pbase() == rhs.pbase()

  • pptr() == rhs.pptr()

  • epptr() == rhs.epptr()

  • getloc() == rhs.getloc()

~basic_streambuf();

Effects: None.

The default constructor is protected for class basic_streambuf to assure that only objects for classes derived from this class may be constructed.

27.6.3.2 basic_streambuf public member functions [streambuf.members]

27.6.3.2.1 Locales [streambuf.locales]

locale pubimbue(const locale& loc);

Postcondition: loc == getloc().

Effects: Calls imbue(loc).

Returns: Previous value of getloc().

locale getloc() const;

Returns: If pubimbue() has ever been called, then the last value of loc supplied, otherwise the current global locale, locale(), in effect at the time of construction. If called after pubimbue() has been called but before pubimbue has returned (i.e., from within the call of imbue()) then it returns the previous value.

27.6.3.2.2 Buffer management and positioning [streambuf.buffer]

basic_streambuf<char_type,traits>* pubsetbuf(char_type* s, streamsize n);

Returns: setbuf(s, n).

pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);

Returns: seekoff(off, way, which).

pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);

Returns: seekpos(sp, which).

int pubsync();

Returns: sync().

27.6.3.2.3 Get area [streambuf.pub.get]

streamsize in_avail();

Returns: If a read position is available, returns egptr() - gptr(). Otherwise returns showmanyc() ([streambuf.virt.get]).

int_type snextc();

Effects: Calls sbumpc().

Returns: If that function returns traits::eof(), returns traits::eof(). Otherwise, returns sgetc().

int_type sbumpc();

Returns: If the input sequence read position is not available, returns uflow(). Otherwise, returns traits::to_int_type(*gptr()) and increments the next pointer for the input sequence.

int_type sgetc();

Returns: If the input sequence read position is not available, returns underflow(). Otherwise, returns traits::to_int_type(*gptr()).

streamsize sgetn(char_type* s, streamsize n);

Returns: xsgetn(s, n).

27.6.3.2.4 Putback [streambuf.pub.pback]

int_type sputbackc(char_type c);

Returns: If the input sequence putback position is not available, or if traits::eq(c,gptr()[-1]) is false, returns pbackfail(traits::to_int_type(c)). Otherwise, decrements the next pointer for the input sequence and returns traits::to_int_type(*gptr()).

int_type sungetc();

Returns: If the input sequence putback position is not available, returns pbackfail(). Otherwise, decrements the next pointer for the input sequence and returns traits::to_int_type(*gptr()).

27.6.3.2.5 Put area [streambuf.pub.put]

int_type sputc(char_type c);

Returns: If the output sequence write position is not available, returns overflow(traits::to_int_type(c)). Otherwise, stores c at the next pointer for the output sequence, increments the pointer, and returns traits::to_int_type(c).

streamsize sputn(const char_type* s, streamsize n);

Returns: xsputn(s,n).

27.6.3.3 basic_streambuf protected member functions [streambuf.protected]

27.6.3.3.1 Assignment [streambuf.assign]

basic_streambuf& operator=(const basic_streambuf& rhs);

Effects: Assigns the data members of rhs to *this.

Postconditions:

  • eback() == rhs.eback()

  • gptr() == rhs.gptr()

  • egptr() == rhs.egptr()

  • pbase() == rhs.pbase()

  • pptr() == rhs.pptr()

  • epptr() == rhs.epptr()

  • getloc() == rhs.getloc()

Returns: *this.

void swap(basic_streambuf& rhs);

Effects: Swaps the data members of rhs and *this.

27.6.3.3.2 Get area access [streambuf.get.area]

char_type* eback() const;

Returns: The beginning pointer for the input sequence.

char_type* gptr() const;

Returns: The next pointer for the input sequence.

char_type* egptr() const;

Returns: The end pointer for the input sequence.

void gbump(int n);

Effects: Adds n to the next pointer for the input sequence.

void setg(char_type* gbeg, char_type* gnext, char_type* gend);

Postconditions: gbeg == eback(), gnext == gptr(), and gend == egptr().

27.6.3.3.3 Put area access [streambuf.put.area]

char_type* pbase() const;

Returns: The beginning pointer for the output sequence.

char_type* pptr() const;

Returns: The next pointer for the output sequence.

char_type* epptr() const;

Returns: The end pointer for the output sequence.

void pbump(int n);

Effects: Adds n to the next pointer for the output sequence.

void setp(char_type* pbeg, char_type* pend);

Postconditions: pbeg == pbase(), pbeg == pptr(), and pend == epptr().

27.6.3.4 basic_streambuf virtual functions [streambuf.virtuals]

27.6.3.4.1 Locales [streambuf.virt.locales]

void imbue(const locale&)

Effects: Change any translations based on locale.

Remarks: Allows the derived class to be informed of changes in locale at the time they occur. Between invocations of this function a class derived from streambuf can safely cache results of calls to locale functions and to members of facets so obtained.

Default behavior: Does nothing.

27.6.3.4.2 Buffer management and positioning [streambuf.virt.buffer]

basic_streambuf* setbuf(char_type* s, streamsize n);

Effects: Influences stream buffering in a way that is defined separately for each class derived from basic_streambuf in this Clause ([stringbuf.virtuals], [filebuf.virtuals]).

Default behavior: Does nothing. Returns this.

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);

Effects: Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_streambuf in this Clause ([stringbuf.virtuals], [filebuf.virtuals]).

Default behavior: Returns pos_type(off_type(-1)).

pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);

Effects: Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_streambuf in this Clause ([stringbuf], [filebuf]).

Default behavior: Returns pos_type(off_type(-1)).

int sync();

Effects: Synchronizes the controlled sequences with the arrays. That is, if pbase() is non-null the characters between pbase() and pptr() are written to the controlled sequence. The pointers may then be reset as appropriate.

Returns: -1 on failure. What constitutes failure is determined by each derived class ([filebuf.virtuals]).

Default behavior: Returns zero.

27.6.3.4.3 Get area [streambuf.virt.get]

streamsize showmanyc();307

Returns: An estimate of the number of characters available in the sequence, or -1. If it returns a positive value, then successive calls to underflow() will not return traits::eof() until at least that number of characters have been extracted from the stream. If showmanyc() returns -1, then calls to underflow() or uflow() will fail.308

Default behavior: Returns zero.

Remarks: Uses traits::eof().

streamsize xsgetn(char_type* s, streamsize n);

Effects: Assigns up to n characters to successive elements of the array whose first element is designated by s. The characters assigned are read from the input sequence as if by repeated calls to sbumpc(). Assigning stops when either n characters have been assigned or a call to sbumpc() would return traits::eof().

Returns: The number of characters assigned.309

Remarks: Uses traits::eof().

int_type underflow();

Remarks: The public members of basic_streambuf call this virtual function only if gptr() is null or gptr() >= egptr()

Returns: traits::to_int_type(c), where c is the first character of the pending sequence, without moving the input sequence position past it. If the pending sequence is null then the function returns traits::eof() to indicate failure.

The pending sequence of characters is defined as the concatenation of:

  1. If gptr() is non- NULL, then the egptr() - gptr() characters starting at gptr(), otherwise the empty sequence.

  2. Some sequence (possibly empty) of characters read from the input sequence.

The result character is

  1. If the pending sequence is non-empty, the first character of the sequence.

  2. If the pending sequence is empty then the next character that would be read from the input sequence.

The backup sequence is defined as the concatenation of:

  1. If eback() is null then empty,

  2. Otherwise the gptr() - eback() characters beginning at eback().

Effects: The function sets up the gptr() and egptr() satisfying one of:

  1. If the pending sequence is non-empty, egptr() is non-null and egptr() - gptr() characters starting at gptr() are the characters in the pending sequence

  2. If the pending sequence is empty, either gptr() is null or gptr() and egptr() are set to the same non-NULL pointer.

If eback() and gptr() are non-null then the function is not constrained as to their contents, but the “usual backup condition” is that either:

  1. If the backup sequence contains at least gptr() - eback() characters, then the gptr() - eback() characters starting at eback() agree with the last gptr() - eback() characters of the backup sequence.

  2. Or the n characters starting at gptr() - n agree with the backup sequence (where n is the length of the backup sequence)

Default behavior: Returns traits::eof().

int_type uflow();

Requires: The constraints are the same as for underflow(), except that the result character shall be transferred from the pending sequence to the backup sequence, and the pending sequence shall not be empty before the transfer.

Default behavior: Calls underflow(). If underflow() returns traits::eof(), returns traits::eof(). Otherwise, returns the value of traits::to_int_type(*gptr()) and increment the value of the next pointer for the input sequence.

Returns: traits::eof() to indicate failure.

The morphemes of showmanyc are “es-how-many-see”, not “show-manic”.

underflow or uflow might fail by throwing an exception prematurely. The intention is not only that the calls will not return eof() but that they will return “immediately.”

Classes derived from basic_streambuf can provide more efficient ways to implement xsgetn() and xsputn() by overriding these definitions from the base class.

27.6.3.4.4 Putback [streambuf.virt.pback]

int_type pbackfail(int_type c = traits::eof());

Remarks: The public functions of basic_streambuf call this virtual function only when gptr() is null, gptr() == eback(), or traits::eq(traits::to_char_type(c),gptr()[-1]) returns false. Other calls shall also satisfy that constraint.

The pending sequence is defined as for underflow(), with the modifications that

  • If traits::eq_int_type(c,traits::eof()) returns true, then the input sequence is backed up one character before the pending sequence is determined.

  • If traits::eq_int_type(c,traits::eof()) return false, then c is prepended. Whether the input sequence is backed up or modified in any other way is unspecified.

Postcondition: On return, the constraints of gptr(), eback(), and pptr() are the same as for underflow().

Returns: traits::eof() to indicate failure. Failure may occur because the input sequence could not be backed up, or if for some other reason the pointers could not be set consistent with the constraints. pbackfail() is called only when put back has really failed.

Returns some value other than traits::eof() to indicate success.

Default behavior: Returns traits::eof().

27.6.3.4.5 Put area [streambuf.virt.put]

streamsize xsputn(const char_type* s, streamsize n);

Effects: Writes up to n characters to the output sequence as if by repeated calls to sputc(c). The characters written are obtained from successive elements of the array whose first element is designated by s. Writing stops when either n characters have been written or a call to sputc(c) would return traits::eof(). Is is unspecified whether the function calls overflow() when pptr() == epptr() becomes true or whether it achieves the same effects by other means.

Returns: The number of characters written.

int_type overflow(int_type c = traits::eof());

Effects: Consumes some initial subsequence of the characters of the pending sequence. The pending sequence is defined as the concatenation of

  1. if pbase() is NULL then the empty sequence otherwise, pptr() - pbase() characters beginning at pbase().

  2. if traits::eq_int_type(c,traits::eof()) returns true, then the empty sequence otherwise, the sequence consisting of c.

Remarks: The member functions sputc() and sputn() call this function in case that no room can be found in the put buffer enough to accommodate the argument character sequence.

Requires: Every overriding definition of this virtual function shall obey the following constraints:

  1. The effect of consuming a character on the associated output sequence is specified310

  2. Let r be the number of characters in the pending sequence not consumed. If r is non-zero then pbase() and pptr() shall be set so that: pptr() - pbase() == r and the r characters starting at pbase() are the associated output stream. In case r is zero (all characters of the pending sequence have been consumed) then either pbase() is set to NULL, or pbase() and pptr() are both set to the same NULL non-value.

  3. The function may fail if either appending some character to the associated output stream fails or if it is unable to establish pbase() and pptr() according to the above rules.

Returns: traits::eof() or throws an exception if the function fails.

Otherwise, returns some value other than traits::eof() to indicate success.311

Default behavior: Returns traits::eof().

That is, for each class derived from an instance of basic_streambuf in this Clause ([stringbuf], [filebuf]), a specification of how consuming a character effects the associated output sequence is given. There is no requirement on a program-defined class.

Typically, overflow returns c to indicate success, except when traits::eq_int_type(c,traits::eof()) returns true, in which case it returns traits::not_eof(c).