188 lines · 6.6 KB · Text
RawDownload
= bufio, bufiofill: buffered input/output module     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;        BufioFill: module    {        fill:   fn(b: ref Bufio->Iobuf): int;    };    Bufio provides an interface for buffered I/O.  A buffer is anadt which is created with  open,  fopen,  create,  aopen  andsopen. Open  takes  two parameters, a filename and a mode.  The modemust be one of OREAD, OWRITE, or ORDWR (also defined  in  theSys module). Create  is similar, but creates a new file if necessary, withfile permissions  specified  by  perm  (see  create  in  sys-open(2)), or truncates an existing file (without changing itspermissions), before  opening  it  in  the  given  mode,  andreturning a reference to an Iobuf instance. Buffered  I/O  on an already open file is made possible usingfopen, 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 sub‐sequent 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 ini‐tialize the string variable addr.  The file is closed implic‐itly by discarding (assigning nil to) the only  reference  toits Iobuf. The  function  aopen makes the contents of an array of byte areadable through an Iobuf (it may not be written).  The func‐tion  sopen  similarly makes the contents of a string s read‐able. Processes can share the same instance  of  Bufio  and  safelyopen  and  close  different  files concurrently, but two pro‐cesses must not access the same Iobuf concurrently; they mustcoordinate  their  access  using some external mechanism (eg,lock(2)). Each output file must be flushed or closed individually  (seeflush and close operations below). 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 specified       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  sep‐       string.   The  returned string includes the separator.       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 internally 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 associ‐       ated  with  the  file.  After close, no further method       calls are allowed on the iobuf adt. The BufioFill module interface can be ignored by most  appli‐cations.   It allows an Iobuf to be used to read data from anarbitrary source.  There is no `standard'  implementation  toload.   Instead,  an  application using this interface uses aseparate BufioFill module instance such as bufio-chanfill(2),or provides one itself using sys-self(2).  The resulting mod‐ule reference is associated, using  setfill,  with  an  Iobufpreviously obtained by sopen (the string parameter limits thebuffer space allocated).  It is up to the BufioFill  module'simplementation  how its fill function replenishes the buffer;it should return the number of bytes now in  the  buffer,  orBufio->EOF. == source/appl/lib/bufio.b == see ALSObufio-chanfill(2),  intro(2),  sys-open(2), sys-read(2), sys-seek(2) == diagnosticsCalls that return a ref type (eg.   open,  fopen,  gets,  andgett)  return  nil  when  encountering end of file or errors.When an error occurs, the error string, printable with the %rformat,  will  usually be set as a consequence of an error inthe underlying Sys module.  The other calls return  EOF  uponencountering  end  of file, and ERROR when encountering othererrors. == bugsA given Iobuf instance may not be accessed concurrently. An Iobuf instance must be  manipulated  by  the  same  moduleinstance that created it. The BufioFill interface is subject to change.