diff options
Diffstat (limited to 'doc/api/libbio/index.txt')
-rw-r--r-- | doc/api/libbio/index.txt | 416 |
1 files changed, 0 insertions, 416 deletions
diff --git a/doc/api/libbio/index.txt b/doc/api/libbio/index.txt deleted file mode 100644 index c0099b4..0000000 --- a/doc/api/libbio/index.txt +++ /dev/null @@ -1,416 +0,0 @@ -{ - title: libbio - description: BIO library description -} - -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. - -The concepts in libbio should be familiar to anyone that has used a buffered -IO library in most languages. The usual concepts are supported: Files, -formatted output, binary and ascii reads, and so on. There are also some -utility functions to deal with reading integers in a known endianness. - -One thing to keep in mind with libbio that it does not attempt to flush -buffers on program exit, which means that any unwritten, unflushed data -will be lost. Closing the bio files will prevent this issue. - -Summary -------- - - pkg bio = - type mode - const Rd : mode - const Wr : mode - const Rw : mode - - type file = struct - ;; - - type lineiter - - type status(@a) = union - `Eof - `Ok @a - `Err ioerr - ;; - - type ioerr = union - `Ebadfile - `Ebadbuf - `Ebadfd - `Eioerr - ;; - - impl iterable lineiter - - /* creation */ - const mkfile : (fd : std.fd, mode : mode -> file#) - const open : (path : byte[:], mode : mode -> std.result(file#, byte[:])) - const dial : (srv : byte[:], mode : mode -> std.result(file#, byte[:])) - const create : (path : byte[:], mode : mode, perm : int -> std.result(file#, byte[:])) - const close : (f : file# -> bool) - const free : (f : file# -> void) - - /* basic i/o. Returns sub-buffer when applicable. */ - const write : (f : file#, src : byte[:] -> status(std.size)) - const read : (f : file#, dst : byte[:] -> status(byte[:])) - const flush : (f : file# -> bool) - - /* seeking */ - const seek : (f : file#, std.off -> std.result(std.off, ioerr)) - - /* single unit operations */ - const putb : (f : file#, b : byte -> status(std.size)) - const putc : (f : file#, c : char -> status(std.size)) - const getb : (f : file# -> status(byte)) - const getc : (f : file# -> status(char)) - - /* peeking */ - const peekb : (f : file# -> status(byte)) - const peekc : (f : file# -> status(char)) - - /* delimited read; returns freshly allocated buffer. */ - const readln : (f : file# -> status(byte[:])) - const readto : (f : file#, delim : byte[:] -> status(byte[:])) - const skipto : (f : file#, delim : byte[:] -> bool) - const skipspace : (f : file# -> bool) - - /* iterators */ - const lineiter : (f : file# -> lineiter) - - /* formatted i/o */ - const put : (f : file#, fmt : byte[:], args : ... -> status(std.size)) - - /* unsigned big endian reads */ - generic getbe8 : (f : file# -> status(@a::(numeric,integral))) - generic getbe16 : (f : file# -> status(@a::(numeric,integral))) - generic getbe32 : (f : file# -> status(@a::(numeric,integral))) - generic getbe64 : (f : file# -> status(@a::(numeric,integral))) - - /* signed big endian reads */ - generic getle8 : (f : file# -> status(@a::(numeric,integral))) - generic getle16 : (f : file# -> status(@a::(numeric,integral))) - generic getle32 : (f : file# -> status(@a::(numeric,integral))) - generic getle64 : (f : file# -> status(@a::(numeric,integral))) - - /* unsigned big endian */ - generic putbe8 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe16 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe32 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe64 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - - /* unsigned little endian */ - generic putle8 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle16 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle32 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle64 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - ;; - -The Data Structures -------------------- - - type file = struct - fd : std.fd - ;; - -The `bio.file` type contains the state required to implement buffered files. -All of the state is internal, except for the file descriptor, which is exposed -for the purposes of poll() and friends. Reading from it directly may lead to -inconsistent buffer state, and is strongly not recommended. - - type ioerr = union - `Ebadfile - `Ebadbuf - `Ebadfd - `Eioerr - ;; - - type status(@a) = union - `Eof - `Ok @a - `Err ioerr - ;; - -The `bio.status(@a)` union returns the result of the read operation, which -is going to either be a result of type '@a', an error-free end of file, or -an error of type `ioerr`. All of these conditions are transient, and are -retried on subsequent calls to the IO operations. For example, if reading -a file returns `Eof, but data is appended to a file, then a subsequent read -will return data again. - -In general, errors will be queued up, so if there is a buffered read or -write that partly succeeds but is interrupted halfway, the error will be -reported on the next operation. This way, partial operations are not lost. - -File Creation and Opening -------------------------- - - const Rd : mode - const Wr : mode - const Rw : mode - -When opening a file, one of the above flags must be passed to set the mode -of the file. `Rd` indicates that the bio file should be read only, `Wr` -indicates that it should be write only, and `Rw` indicates that it should be -both readable and writable. - -Bio file creation -------------- - - const mkfile : (fd : std.fd, mode : mode -> file#) - -This function creates a bio file from a file descriptor and mode, returning a -`bio.file#` which will buffer reads and/or writes from the fd. This function -assumes that you are passing it a correctly initialized fd, and will always -succeed. If the FD is incorrectly configured, uses of it will error out. - -Returns: A buffered file wrapping the file descriptor `fd` - - const open : (path : byte[:], mode : mode -> std.result(file#, byte[:])) - -This function attempts to open the path passed in with the mode, returning -a result which is either a file, or a string representing the error that -prevented the file from being opened. - -Returns: A buffered file representing `path` opened with the requested -permissions. - - const dial : (srv : byte[:], mode : mode -> std.result(file#, byte[:])) - -This function is similar to open, however, this function will open a -connection via a dialstring (as in `std.dial`), and buffer the fd returned -from that. - -Returns: A buffered file representing `dialstr` opened with the requested -permissions. - - const create : (path : byte[:], mode : mode, perm : int -> std.result(file#, byte[:])) - -This function is similar to open, however, this function will attempt to -atomically create and open the file descriptor. - -Returns: A buffered file representing `path` opened with the requested -permissions. - - const close : (f : file# -> bool) - -Closes the file descriptor that the bio file is wrapping, and frees any -resources used for buffering it. Any data that has not yet been written is -flushed. - -Returns: `true` if flushing the file succeeded, `false` if it failed. - - const free : (f : file# -> void) - -Frees any resources used for the file descriptor, but leaves it open. This is -useful if the file descriptor has been 'stolen' using bio.mkfile, and is not -owned by the bio file. - - const flush : (f : file# -> bool) - -Clears any data that has not been sent to the backing file descriptor. - -Returns: `true` if flushing the file succeeded, `false` if it failed. - -Binary I/O ------------ - - const write : (f : file#, src : byte[:] -> result(std.size, byte[:])) - -Writes bytes from the buffer `src` to a bio file, returning the number of -bytes written in the case of success. This number may be smaller than the size -of the buffer, but will never be larger. - - const read : (f : file#, dst : byte[:] -> result(byte[:])) - -Reads from a bio file, into the buffer 'dst', returning the section of the -buffer that was read in the result. - - const seek : (f : file#, std.off -> std.result(std.off, ioerr)) - -Seeks the bio file to the given absolute offset. - - const flush : (f : file# -> bool) - -Flush attempts to clear the buffers within `f`, writing everything within -the buffers and discarding them. If writing fails, `false` is returned. - - -Single Unit Operations ----------------------- - - /* single unit operations */ - const putb : (f : file#, b : byte -> status(std.size)) - -Writes a single byte out to the file 'f', returning a status. If -it is successful, the return value represents the number of bytes written. -For single byte writes, this value is unsurprisingly always 1. - - const putc : (f : file#, c : char -> status(std.size)) - -Writes a single unicode character out to the file 'f', returning a status. -This character is encoded in utf-8. If it is successful, the return value -represents the number of bytes written, varying between 1 and 4. - - const getb : (f : file# -> status(byte)) - -Reads a single byte from the file `f`, returning a status. If this read -succeeds, the next byte in the file is returned. - - const getc : (f : file# -> status(char)) - -Reads a unicode character from the file `f`, returning a status. If this read -was successful, the next character is returned from the file. The file is -assumed to be encoded in utf-8. - - /* peeking */ - const peekb : (f : file# -> status(byte)) - const peekc : (f : file# -> status(char)) - -Both peekb and peekc are similar to getb and getc respectively, although -they return the value without advancing the position within the buffer. - - -Delimited Operations --------------------- - - /* delimited read; returns freshly allocated buffer. */ - const readln : (f : file# -> status(byte[:])) - -Readln reads a single line of input from the file 'f', returning the line -with the line ending characters removed. '\n', '\r', and '\r\n' are all -accepted as valid line endings, and are treated interchangably when reading. - -The buffer is heap allocated, and must be freed with std.slfree - - const readto : (f : file#, delim : byte[:] -> status(byte[:])) - -Readto is similar to readln, but instead of reading to a line ending, it will -read up to the point where it finds the requested delimiter. The delimiter is -an arbitrary sequence of bytes. If an end of file is reached, then the buffer -up to the Eof is returned. - -The buffer is heap allocated, and must be freed with std.slfree - - const skipto : (f : file#, delim : byte[:] -> bool) - -Skipto is identical to readto, but instead of allocating a buffer and reading -into it, skipto will ignore the values and drop them. It returns true for -any successful reads, and false if an error was encountered. - - const skipspace : (f : file# -> bool) - -Skipspace will consume any space tokens from the start of the input stream, It -returns true for any successful reads, and false if an error was encountered. - -Iteration ---------- - - const lineiter : (f : file# -> lineiter) - -Lineiter will return an interable type that will iterate through each line -in a file. These lines are allocated on the heap, and are automatically freed -at the end of the iteration. - -The returned iterator object is a value type, and does not need to be freed. - -Formatted IO -------------- - - const put : (f : file#, fmt : byte[:], args : ... -> status(std.size)) - -This formats the output using the std.fmt api, and writes it to the file `f`. -All custom formatters installed for `std.fmt` are used for this formatting. -This call returns the number of bytes written on success. - -Endian Aware Reads ------------------- - - generic getbe8 : (f : file# -> status(@a::(numeric,integral))) - generic getbe16 : (f : file# -> status(@a::(numeric,integral))) - generic getbe32 : (f : file# -> status(@a::(numeric,integral))) - generic getbe64 : (f : file# -> status(@a::(numeric,integral))) - - generic getle8 : (f : file# -> status(@a::(numeric,integral))) - generic getle16 : (f : file# -> status(@a::(numeric,integral))) - generic getle32 : (f : file# -> status(@a::(numeric,integral))) - generic getle64 : (f : file# -> status(@a::(numeric,integral))) - -The functions above all read from a bio file, and return the value read on -success. The 'be' variants read big endian values, and the `le' variants -read little endian values. They final result is converted to whatever -numeric, integral type is desired. If the value does not fit within the bounds -of the type, it is truncated. - -The number of bytes read is determined by the number at the end of the -function call. For eample, `getbe8()` will read 8 bits, or one byte from the -stream. `getle64` will get a 64 bit, or 8 byte, value. The number of bytes -consumed is independent of the size of the type being assigned to. - - generic putbe8 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe16 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe32 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putbe64 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - - generic putle8 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle16 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle32 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - generic putle64 : (f : file#, v : @a::(numeric,integral) -> status(std.size)) - -The functions above all write to a bio file, and return the number of bytes -written on success. The number of bytes written will always be the size of the -type. The 'be' variants write the value in a big endian representation, and -the 'le' variants write it in a little endian representation. - -The number of bytes written is determined by the number at the end of the -function call. For eample, `putbe8()` will write 8 bits, or one byte. -`putbe64` will write 64 bits, or 8 bytes. The number of -bytes consumed is independent of the size of the type being assigned to. - -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. - - use std - use bio - - const main = { - var f - - match bio.create("create-example", bio.Wr, 0o644) - | `std.Some bio: f = bio - | `std.None: std.fatal(1, "Failed to open file\n") - ;; - bio.write(f, "Hello user\n") - bio.close(f) - } - -The next example shows reading from a file called "lines", line by line. It -should echo the lines, numbering them as it prints them: - - use std - use bio - - const main = { - var f - var i - - match bio.open("lines", bio.Rd) - | `std.Some bio: f = bio - | `std.None: std.fatal(1, "Unable to open data file\n") - ;; - - while true - match bio.readlin(f) - | `std.Some ln: - std.put("line %i: %s\n", i, ln) - | `std.None: - break; - ;; - ;; - } |