Myrddin's BIO library is used for buffered input and output. It is a fairly simple library that handles reading and writing from file descriptors. Support for reading and writing from any abstract source as a byte stream is planned, but not yet implemented.
API reference.
pkg bio =
type mode
const Rd
const Wr
const Rw
type file
/* creation */
const mkfile : (fd : std.fd, mode : mode -> file#)
const open : (path : byte[:], mode : mode -> std.option(file#))
const create : (path : byte[:], mode : mode, perm : int -> std.option(file#))
const close : (f : file# -> bool)
/* basic i/o. Returns sub-buffer when applicable. */
const write : (f : file#, src : byte[:] -> std.size)
const read : (f : file#, dst : byte[:] -> std.option(byte[:]))
const flush : (f : file# -> bool)
/* seeking */
/* single unit operations */
const putb : (f : file#, b : byte -> std.size)
const putc : (f : file#, c : char -> std.size)
const getb : (f : file# -> std.option(byte))
const getc : (f : file# -> std.option(char))
/* typed binary reads */
generic putbe : (f : file#, v : @a::(numeric,integral) -> std.size)
generic putle : (f : file#, v : @a::(numeric,integral) -> std.size)
generic getbe : (f : file# -> std.option(@a::(numeric,integral)))
generic getle : (f : file# -> std.option(@a::(numeric,integral)))
/* peeking */
const peekb : (f : file# -> std.option(byte))
const peekc : (f : file# -> std.option(char))
/* delimited read; returns freshly allocated buffer. */
const readln : (f : file# -> std.option(byte[:]))
const readto : (f : file#, delim : byte[:] -> std.option(byte[:]))
const skipto : (f : file#, delim : byte[:] -> bool)
/* formatted i/o */
const put : (f : file#, fmt : byte[:], args : ... -> std.size)
;;
For all of these functions, the output buffer is not automatically flushed, and might not touch the output stream until the file is either explicitly closed or flushed. The output buffers are not automatically flushed on program exit.
The mode
type describes the input/output mode of the file. Rd
means that
the file is in read only mode. Wr
means that it is in write only mode. Rw
means that the file can be both read and write, and is equivalent to Rd|Wr
.
mkfile
creates a file from any FD, with the given mode requested. It does
not check the mode, but assumes that it was correct.
open
opens the file, returning an error if it does not yet exist. create
is identical to open, however, it will create the file if it does not exist.
It does not create the directory path.
close
flushes the file, closes the file descriptor, and frees any resources
associated with the FD.
write
writes from the buffer src
to a file descriptor, returning the
number of bytes written. It will try to write all the bytes to the FD in one
go, if it can.
read
will read from the file f
into the provided buffer dst
, returning
the slice of the buffer that was actually written to.
flush
clears any output that has accumulated in the output buffer but has
not yet been written. It is a no-op on read-only streams.
putb
and getb
will read and write a single byte to a buffered file
returning the number of bytes written, or \
std.Some byte` , respectively.
putc
and getc
are similar to putc
and getc
, however they will encode
or decode the byte on I/O.
putbe
and putle
will write a single integer like value to the output file
in big or little endian format. getbe
and getle
will do the converse
operation.
peekb
will return the next byte that will be read from the input buffer,
reading from the file to get it if needed. It will not consume the byte.
peekc
will do the same thing for a single utf8 character.
readto
will read to the next instance of the provided delimiter, allocating
a buffer to return the line in with std.slalloc
. The buffer must be freed
after use with std.slfree
. The delimiter is not included in the returned
value, but it is consumed. skipto
is similar, however, the input is
discarded instead of being returned. readln
is identical to readto
,
however, the delimiter is hard coded to \n
.
put
outputs formatted text similar to std.put
, and sharing the same format
specifiers.
Examples
The example below is the simplest program that creates and opens a file, and
writes to it. It creates it with 0o644 permissions (ie, rw-r--r--), and then
immediately closes it. The result of this program should be a file called
create-example
containing the words.
The next example shows reading from a file called "lines", line by line. It should echo the lines, numbering them as it prints them: