[Top] [Prev] [Next] [Bottom]
bufio - buffered input/output module
include "sys.m"; # for Sys->OREAD, etc.
include "bufio.m";
Iobuf: import Bufio;
bufio:= load Bufio Bufio->PATH;
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, where: int): int;
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;
ungetb:fn(b: self ref Iobuf): int;
getc: fn(b: self ref Iobuf): int;
ungetc:fn(b: self ref Iobuf): int;
gets: fn(b: self ref Iobuf, sep: int): string;
gett: fn(b: self ref Iobuf, sep: string): string;
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);
}; # end of Iobuf declaration
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;
flush: fn();
Description - Iobuf adt
The Bufio module provides an interface for buffered I/O. A buffer is an adt which is created with open, fopen, or create.
open
open: fn(name: string, mode: int): ref Iobuf;
## returns nil if unsuccessful.
The open function takes two parameters, a filename and a mode. The mode must be one of OREAD, OWRITE, or ORDWR (defined to match the corresponding values in the Sys module). Both open and fopen return a ref Iobuf to be used in subsequent calls.
create
create: fn(name: string, mode, perm: int): ref Iobuf;
## returns nil if unsuccessful.
The create function creates a new file or prepares to rewrite an existing file, and opens it according to mode (as described for open). It returns a ref Iobuf to be used in subsequent calls.
fopen
fopen: fn(fd: ref Sys->FD, mode: int): ref Iobuf;
## returns nil if unsuccessful.
Buffered I/O on an already open file is made possible using fopen, which takes a file descriptor, fd, as its first argument and an open mode as its second argument. The mode of the file descriptor must be compatible with the mode passed to fopen.
flush
flush: fn();
The Bufio module keeps an internal reference to files opened for writing so that they can be flushed before being garbage collected. Flushing all dirty files must be done with an explicit call to flush(), usually just before exiting the program.
seek, read, and write
seek: fn(b: self ref Iobuf, n, where: int): int;
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;
Each function has parameters and return values analogous to its complement in the Sys module (see seek - change file offset and read, write, stream - read, write, or stream file in Chapter 8).
b.getb
getb: fn(b: self ref Iobuf): int;
## returns a single byte (represented as an int); negative
if unsuccessful.
Read a single byte from the buffered stream and return its value as an int.
b.ungetb
ungetb: fn(b: self ref Iobuf): int;
## returns 1 if successful, negative if unsuccessful.
Put the last byte read back into the buffered stream, so that a subsequent getb will read it.
b.getc
getc: fn(b: self ref Iobuf): int;
## returns single character (as int); negative on failure.
Read a single Unicode character, encoded in UTF, and return its value as an int. (See UTF, Unicode, ASCII - character set and format in Appendix A.)
b.ungetc
ungetc: fn(b: self ref Iobuf): int;
## returns 1 if successful, negative on failure.
Put the last Unicode character read, encoded in UTF, back into the buffered stream so that a subsequent getc will read it.
b.gets
gets: fn(b: self ref Iobuf, sep: int): string;
## returns nil if error or EOF.
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.
b.gett
gett: fn(b: self ref Iobuf, sep: string): string;
## returns nil if error or EOF.
Read characters until one of the characters in sepstr. The returned string includes the separator. If none of the separator characters is found, read to the end of the file.
b.putb, b.putc, and b.puts
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;
## returns putb and putc return 0 on success; negative on
failure.
puts returns len s on success; negative on failure.
Each function writes its respective argument: a byte (b), a Unicode character (c), or a string (s). Text is encoded in UTF.
b.flush
flush: fn(b: self ref Iobuf): int;
## returns 0 on success; negative on failure.
Flush remaining data in the buffer; if necessary. It is the programmer's responsibility to explicitly call flush() prior to exiting.
b.close
close: n(b: self ref Iobuf);
Flush remaining data in the buffer; if necessary, close the associated file, and discard buffers associated with the file. After close, no further function calls are allowed on the Iobuf adt.
Diagnostics
Calls that return a ref type (create, 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 functions return EOF upon encountering end of file, and ERROR when encountering other errors.
Caveat
The implementation of Bufio includes flushbufs, a global list that gets updated by each open, fopen, and create. It may be corrupted if multiple threads are doing opens with the same module handle. Similarly, multiple threads should not act on a given Iobuf adt.
Example
The following example uses bufio to read from standard input and write to standard output.
implement bufio_test;
include "sys.m";
include "draw.m";
include "bufio.m";
sys: Sys;
draw: Draw;
bufio: Bufio;
Iobuf: import bufio;
stderr, stdout, stdin: ref Sys->FD;
bufio_test: module
{
init: fn(ctxt: ref Draw->Context, argv: list of
string);
};
init(ctxt: ref Draw->Context, argv: list of string)
{
sys = load Sys Sys->PATH;
bufio = load Bufio Bufio->PATH;
stdin = sys->fildes(0);
stdout = sys->fildes(1);
iobfd_in, iobfd_out: ref Iobuf;
iobfd_in = bufio->fopen(stdin, bufio->OREAD);
if (iobfd_in == nil)
sys->print("iobfd_in: error opening %d: %r\n",
stdin.fd);
else sys->print("iobfd_in: file %d opened
successfully\n", stdin.fd);
iobfd_out = bufio->fopen(stdout, bufio->OWRITE);
if (iobfd_out == nil)
sys->print("iobfd_out: error opening %d: %r\n",
stdout.fd);
else sys->print("iobfd_out: file %d opened
successfully\n", stdout.fd);
sys->print("Enter input; end with \".\" on a line by
itself.\n");
while () {
line := iobfd_in.gets('\n');
if (line == ".\n") break;
iobfd_out.puts(line);
sys->print("%s", line);
}
iobfd_in.flush();
iobfd_out.flush();
}
See Also
-
Introduction to Limbo Modules in Chapter 7
-
open, create - open/create a file for reading or writing in Chapter 8
-
read, write, stream - read, write, or stream file in Chapter 8
-
seek - change file offset in Chapter 8
-
[Top] [Prev] [Next] [Bottom]
infernosupport@lucent.com
Copyright © 1997, Lucent Technologies, Inc.. All rights
reserved.