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; };
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 descriptor.
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 (including 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 reference 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 processes 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).
The calls implemented by Iobuf are:
The BufioFill module interface can be ignored by most applications. It allows an Iobuf to be used to read data from an arbitrary source. There is no `standard' implementation to load. Instead, an application using this interface 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.
An Iobuf instance must be manipulated by the same module instance that created it.
The BufioFill interface is subject to change.
BUFIO(2 ) | Rev: Tue Mar 31 02:42:39 GMT 2015 |