BUFIO(2)                                                 BUFIO(2)

     NAME
          bufio, bufiofill - buffered input/output module

     SYNOPSIS
          include "bufio.m";

          bufio := load Bufio Bufio->PATH;
          Iobuf: import bufio;

          SEEKSTART:  con Sys->SEEKSTART;
          SEEKRELA:   con Sys->SEEKRELA;
          SEEKEND:    con Sys->SEEKEND;

          OREAD:      con Sys->OREAD;
          OWRITE:     con Sys->OWRITE;
          ORDWR:      con Sys->ORDWR;

          EOF:        con -1;
          ERROR:      con -2;

          Iobuf: adt {
              seek:   fn(b: self ref Iobuf, n: big, where: int): big;
              offset: fn(b: self ref Iobuf): big;

              read:   fn(b: self ref Iobuf, a: array of byte, n: int): int;
              write:  fn(b: self ref Iobuf, a: array of byte, n: int): int;

              getb:   fn(b: self ref Iobuf): int;
              getc:   fn(b: self ref Iobuf): int;
              gets:   fn(b: self ref Iobuf, sepchar: int): string;
              gett:   fn(b: self ref Iobuf, sepstring: string): string;

              ungetb: fn(b: self ref Iobuf): int;
              ungetc: fn(b: self ref Iobuf): int;

              putb:   fn(b: self ref Iobuf, b: byte): int;
              putc:   fn(b: self ref Iobuf, c: int): int;
              puts:   fn(b: self ref Iobuf, s: string): int;

              flush:  fn(b: self ref Iobuf): int;
              close:  fn(b: self ref Iobuf);

              setfill: fn(b: self ref Iobuf, f: BufioFill);
          };

          open:   fn(name: string, mode: int): ref Iobuf;
          create: fn(name: string, mode, perm: int): ref Iobuf;
          fopen:  fn(fd: ref Sys->FD, mode: int): ref Iobuf;
          aopen: fn(a: array of byte): ref Iobuf;
          sopen:  fn(s: string): ref Iobuf;

     Page 1                       Plan 9            (printed 12/23/24)

     BUFIO(2)                                                 BUFIO(2)

          BufioFill: module
          {
              fill:   fn(b: ref Bufio->Iobuf): int;
          };

     DESCRIPTION
          Bufio provides an interface for buffered I/O.  A buffer is
          an adt which is created with open, fopen, create, aopen and
          sopen.

          Open takes two parameters, a filename and a mode. The mode
          must be one of OREAD, OWRITE, or ORDWR (also defined in the
          Sys module).

          Create is similar, but creates a new file if necessary, with
          file permissions specified by perm (see create in sys-
          open(2)), or truncates an existing file (without changing
          its permissions), before opening it in the given mode, and
          returning a reference to an Iobuf instance.

          Buffered I/O on an already open file is made possible using
          fopen, which takes a file descriptor fd and an open mode,
          which must be compatible with the mode of the file descrip-
          tor.

          The file open functions return a ref Iobuf to be used in
          subsequent calls.  Thus:

               lc := bufio->open("/net/tcp/0/local", bufio->OREAD);
               addr := lc.gets('\n');
               lc = nil;

          will open the file /net/tcp/0/local and read a line (includ-
          ing the terminating newline character) from this file to
          initialize the string variable addr.  The file is closed
          implicitly by discarding (assigning nil to) the only refer-
          ence to its Iobuf.

          The function aopen makes the contents of an array of byte a
          readable through an Iobuf (it may not be written).  The
          function sopen similarly makes the contents of a string s
          readable.

          Processes can share the same instance of Bufio and safely
          open and close different files concurrently, but two pro-
          cesses must not access the same Iobuf concurrently; they
          must coordinate their access using some external mechanism
          (eg, lock(2)).

          Each output file must be flushed or closed individually (see
          flush and close operations below).

     Page 2                       Plan 9            (printed 12/23/24)

     BUFIO(2)                                                 BUFIO(2)

          The calls implemented by Iobuf are:

          seek, read, and write
                   Each has the same parameters as its complement in
                   Sys (see sys-seek(2), sys-read(2)). Note that
                   SEEKSTART etc. are defined by Bufio as well as by
                   Sys, for use by seek.

          offset   Return the current file offset in bytes, taking
                   account of buffered data.

          getb     Read a single byte from the buffered stream and
                   return its value as an int.

          getc     Read a single Unicode character, encoded in UTF
                   (see utf(6)), and return its value as an int.

          gets     Read a line, up to and including a character speci-
                   fied by sepchar, typically a newline.  If none is
                   found, read to the end of the file.  The returned
                   string includes the terminating character.

          gett     Read characters until one of the characters in
                   sepstring. The returned string includes the separa-
                   tor.  If none of the separator characters is found,
                   read to the end of the file.

          ungetb, ungetc
                   Undoes the effect of the last getb or getc, so that
                   a subsequent read will reread the byte (ungetb), or
                   reread the byte(s) of a UTF-encoded character
                   (ungetc)

          putb, putc, and puts
                   Each writes its argument, a byte, a character, or a
                   string, respectively.  Text is encoded in UTF.

          setfill  Associates a BufioFill module instance f with Iobuf
                   b; discussed below.

          flush    Flush remaining data in the buffer, if necessary.
                   For files opened for writing, data is flushed to
                   the file.  For files opened for reading, any inter-
                   nally buffered data is discarded, and the next read
                   will read from the file.

          close    Flush remaining data in the buffer, if necessary,
                   close the associated file, and discard buffers
                   associated with the file.  After close, no further
                   method calls are allowed on the iobuf adt.

          The BufioFill module interface can be ignored by most

     Page 3                       Plan 9            (printed 12/23/24)

     BUFIO(2)                                                 BUFIO(2)

          applications.  It allows an Iobuf to be used to read data
          from an arbitrary source.  There is no `standard' implemen-
          tation to load.  Instead, an application using this inter-
          face uses a separate BufioFill module instance such as
          bufio-chanfill(2), or provides one itself using sys-self(2).
          The resulting module reference is associated, using setfill,
          with an Iobuf previously obtained by sopen (the string
          parameter limits the buffer space allocated).  It is up to
          the BufioFill module's implementation how its fill function
          replenishes the buffer; it should return the number of bytes
          now in the buffer, or Bufio->EOF.

     SOURCE
          /appl/lib/bufio.b

     SEE ALSO
          bufio-chanfill(2), intro(2), sys-open(2), sys-read(2), sys-
          seek(2)

     DIAGNOSTICS
          Calls that return a ref type (eg.  open, fopen, gets, and
          gett) return nil when encountering end of file or errors.
          When an error occurs, the error string, printable with the
          %r format, will usually be set as a consequence of an error
          in the underlying Sys module.  The other calls return EOF
          upon encountering end of file, and ERROR when encountering
          other errors.

     BUGS
          A given Iobuf instance may not be accessed concurrently.

          An Iobuf instance must be manipulated by the same module
          instance that created it.

          The BufioFill interface is subject to change.

     Page 4                       Plan 9            (printed 12/23/24)