\input texinfo  @c -*-texinfo-*-

@settitle Reference manual to the GNU C++ Iostream Facility
@setfilename iostream.info

@ifinfo
@format
START-INFO-DIR-ENTRY
* iostream: (iostream).             The C++ input/output facility.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@titlepage
@title Reference manual
@title to the GNU C++ Iostream Facility
@sp 3
@subtitle (Very much a work in progress)
@author Per Bothner (bothner@@cygnus.com)
@end titlepage

@ifinfo
@node Top, Introduction, (DIR), (DIR)
@end ifinfo

@menu
* Introduction::
* Using the iostream layer::
* Using the streambuf layer::
* Streambuf internals::

Indices:
* Function and Variable Index::
* Concept Index::
@end menu

@node Introduction, Using the iostream layer, Top, Top
@chapter Introduction

The @code{iostream} library was written by Per Bothner.

Various people have found bugs or come with suggestions.
Hongjiu Lu has worked hard to use the library as the default
stdio implementation for Linux, and has provided much
stress-testing of the library.

Some code was derived from parts of BSD 4.4, which is
copyright University of California at Berkeley.

@node Using the iostream layer, Using the streambuf layer, Introduction, Top
@chapter Using the iostream layer

@node Using the streambuf layer, Streambuf internals, Using the iostream layer, Top
@chapter Using the streambuf layer

@menu
* Backing up::
@end menu

@node Backing up, , , Using the streambuf layer
@section Backing up

The GNU iostream library allows you to ask streambuf to remember
the current position, and then later after you've read further
be able to go back to it.  Your're guaranteed to be able to backup
arbitrary amounts, even on unbuffered files or multiple
buffers worth, as long as you tell the library advance.
This unbounded backup is very useful for scanning and
parsing applications.  This example shows a typical scenario:

@example
// Read either "dog", "hound", or "hounddog".
// If "dog" is found, return 1.
// If "hound" is found, return 2.
// If "hounddog" is found, return 3.
// If non of these are found, return -1.
int my_scan(streambuf* sb)
@{
    streammarker fence(sb);
    char buffer[20];
    // Try reading "hounddog":
    if (sb->sgetn(buffer, 8) == 8 && strncmp(buffer, "hounddog", 8) == 0)
      return 3;
    // No, no "hounddog":  Backup to 'fence' ...
    sb->seekmark(fence); // 
    // ... and try reading "dog":
    if (sb->sgetn(buffer, 3) == 3 && strncmp(buffer, "dog", 3) == 0)
      return 1;
    // No, no "dog" either:  Backup to 'fence' ...
    sb->seekmark(fence); // 
    // ... and try reading "hound":
    if (sb->sgetn(buffer, 5) == 5 && strncmp(buffer, "hound", 5) == 0)
      return 2;
    // No, no "hound" either:  Backup to 'fence' and signal failure.
    sb->seekmark(fence); // Backup to 'fence'..
    return -1;
@}
@end example

@deftypefn Constructor {} streammarker::streammarker (streambuf* @var{sbuf})
Create a @code{streammarker} associated with @var{sbuf}
that remembers the current postion of the get pointer.
@end deftypefn

@deftypefn Method int streammarker::delta (streammarker& @var{mark2})
Return the difference between the get positions corresponding
to @code{*this} and @var{mark2} (which must point into the same
@code{streambuffer} as @code{this}).
@end deftypefn

@deftypefn Method int streammarker::delta ()
Return the position relative to the streambuffer's current get position.
@end deftypefn

@deftypefn Method int streambuffer::seekmark (streammarker& @var{mark})
Move the get pointer to where it (logicly) was when @var{mark}
was constructed.
@end deftypefn

@node Streambuf internals, Function and Variable Index, Using the streambuf layer, Top
@chapter Streambuf internals

@menu
* Buffer management::
* Filebuf internals::
@end menu

@node Buffer management, Filebuf internals, , Streambuf internals
@section Buffer management

@subsection Areas

Streambuf buffer management is fairly sophisticated (this is a
nice way to say "complicated").  The standard protocol
has the following "areas":

@itemize @bullet
@cindex put area
@item
The @dfn{put area} contains characters waiting for output.
@cindex get area
@item
The @dfn{get area} contains characters available for reading.
@cindex reserve area
@item
The @dfn{reserve area} is available to virtual methods.
Usually, the get and/or put areas are part of the reserve area.
@end itemize

The GNU streambuf design extends this by supporting two
get areas:
@itemize @bullet
@cindex main get area
@item
The @dfn{main get area} contains characters that have
been read in from the character source, but not yet
read by the application.
@cindex backup area
@item
The @dfn{backup area} contains previously read data that is being
saved because of a user request, or that have been "unread" (putback).
@end itemize

The backup and the main get area are logically contiguous:  That is,
the first character of the main get area follows the last character
of the backup area.

The @dfn{current get area} is whichever one of the backup or
main get areas that is currently being read from.
The other of the two is the @dfn{non-current get area}.

@subsection Pointers

The following @code{char*} pointers define the various areas.
(Note that if a pointer points to the 'end' of an area,
it means that it points to the character after the area.)

@deftypefn Method char* streambuffer::base ()
The start of the reserve area.
@end deftypefn

@deftypefn Method char* streambuffer::ebuf ()
The end of the reserve area.
@end deftypefn

@deftypefn Method char* streambuffer::pbase ()
The start of the put area.
@end deftypefn

@deftypefn Method char* streambuffer::pptr ()
The current put position.
If @code{pptr() < epptr()}, then the next write will
overwrite @code{*pptr()}, and increment @code{pptr()}.
@end deftypefn

@deftypefn Method char* streambuffer::epptr ()
The end of the put area.
@end deftypefn

@deftypefn Method char* streambuffer::eback ()
The start of the current get area.
@end deftypefn

@deftypefn Method char* streambuffer::gptr ()
The current get position.
If @code{gptr() < egptr()}, then the next read will
read @code{*gptr()}, and increment @code{gptr()}.
@end deftypefn

@deftypefn Method char* streambuffer::egptr ()
The end of the current get area.
@end deftypefn

@deftypefn Method char* streambuffer::Gbase ()
The start of the main get area.
@end deftypefn

@deftypefn Method char* streambuffer::eGptr ()
The end of the main get area.
@end deftypefn

@deftypefn Method char* streambuffer::Bbase ()
The start of the backup area.
@end deftypefn

@deftypefn Method char* streambuffer::Bptr ()
The start of the used part of the backup area.
The area (@code{Bptr()} .. @code{eBptr()}) contains data that has been
pushed back, while (@code{Bbase()} .. @code{eBptr()}) contains unused
space available for future putbacks.
@end deftypefn

@deftypefn Method char* streambuffer::eBptr ()
The end of the backup area.
@end deftypefn

@deftypefn Method char* streambuffer::Nbase ()
The start of the non-current get area (either @code{main_gbase} or @code{backup_gbase}).
@end deftypefn

@deftypefn Method char* streambuffer::eNptr ()
The end of the non-current get area.
@end deftypefn


@node Filebuf internals, , Buffer management, Streambuf internals
@section Filebuf internals

The @code{filebuf} is used a lot, so it is importamt that it be
efficient.  It is also supports rather complex semantics.
so let us examine its implementation.

@subsection Tied read and write pointers

The streambuf model allows completely independent read and write pointers.
However, a @code{filebuf} has only a single logical pointer used
for both reads and writes.  Since the @code{streambuf} protocol
uses @code{gptr()} for reading and @code{pptr()} for writing,
we map the logical file pointer into either @code{gptr()} or @code{pptr()}
at different times.

@itemize @bullet
@item
Reading is allowed when @code{gptr() < egptr()}, which we call get mode.
@item
Writing is allowed when @code{pptr() < epptr()}, which we call put mode.
@end itemize
A @code{filebuf} cannot be in put get mode and put mode at the same time.

We have upto two buffers:
@itemize @bullet
@item
The backeup area, defined by @code{Bbase()}, @code{Bptr()}, and @code{eBptr()}.
This can be empty.
@item
The reserve area, which also contains the main get area.
For an unbuffered file, the (@code{shortbuf()}..@code{shortbuf()+1}) is used,
where @code{shortbuf()} points to a 1-byte buffer that is part of
the @code{filebuf}.
@end itemize

The file system's idea of the current position is @code{eGptr()}.

Character that have been written into a buffer but not yet written
out (flushed) to the file systems are those between @code{pbase()}
and @code{pptr()}.

The end of the valid data bytes is:
@code{pptr() > eGptr() && pptr() < ebuf() ? pptr() : eGptr()}.

If the @code{filebuf} is unbuffered or line buffered,
the @code{eptr()} is @code{pbase()}.  This forces a call
to @code{overflow()} on each put of a character.
The logical @code{epptr()} is @code{epptr() ? ebuf() : NULL}.
(If the buffer is read-only, set @code{pbase()}, @code{pptr()},
and @code{epptr()} to @code{NULL}.)

@node Function and Variable Index, Concept Index, Streambuf internals, Top
@appendix Function and Variable Index,Concept Index,,Top
@printindex fn

@node Concept Index,  , Function and Variable Index, Top
@appendix Concept Index,,Function and Variable Index,Top
@printindex cp

@contents
@bye
