[Top] [Prev] [Next] [Bottom]


[Contents] [Index]

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.