hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

handle.ha (2286B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 // TODO: Examine the ABI constraints of [[handle]]. Would it be better to make
      5 // stream an integer representing an internal handle into a stream table? This
      6 // would reduce performance for streams somewhat via the indirect lookup, but
      7 // improve the ABI performance for files.
      8 
      9 // An I/O handle is a resource which I/O operations may be performed on. It is
     10 // either a [[stream]], which is a userspace I/O abstraction, or a [[file]],
     11 // which is backed by a resource on the host OS, such as a file descriptor.
     12 export type handle = (file | *stream);
     13 
     14 // Reads up to len(buf) bytes from a [[handle]] into the given buffer, returning
     15 // the number of bytes read.
     16 export fn read(h: handle, buf: []u8) (size | EOF | error) = {
     17 	match (h) {
     18 	case let fd: file =>
     19 		return fd_read(fd, buf);
     20 	case let st: *stream =>
     21 		return st_read(st, buf);
     22 	};
     23 };
     24 
     25 // Writes up to len(buf) bytes to the [[handle]] from the given buffer,
     26 // returning the number of bytes written.
     27 export fn write(h: handle, buf: const []u8) (size | error) = {
     28 	match (h) {
     29 	case let fd: file =>
     30 		return fd_write(fd, buf);
     31 	case let st: *stream =>
     32 		return st_write(st, buf);
     33 	case =>
     34 		abort();
     35 	};
     36 };
     37 
     38 // Closes a [[handle]]. No further operations against this handle are permitted
     39 // after calling this function. Closing a file handle can fail only under
     40 // certain conditions (for example, closing a file twice, or an interrupted
     41 // syscall). However, the user should not attempt to close the file again on
     42 // failure - at best the user should print a diagnostic message and move on. See
     43 // close(2) for details.
     44 export fn close(h: handle) (void | error) = {
     45 	match (h) {
     46 	case let fd: file =>
     47 		fd_close(fd)?;
     48 	case let st: *stream =>
     49 		st_close(st)?;
     50 	};
     51 };
     52 
     53 // Sets the offset within a [[handle]], returning the new offset. The new offset
     54 // is obtained by adding [[off]] to the position specified by [[whence]].
     55 export fn seek(h: handle, off: off, w: whence) (off | error) = {
     56 	match (h) {
     57 	case let fd: file =>
     58 		return fd_seek(fd, off, w);
     59 	case let st: *stream =>
     60 		return st_seek(st, off, w);
     61 	};
     62 };
     63 
     64 // Returns the current offset within a [[handle]].
     65 export fn tell(h: handle) (off | error) = {
     66 	return seek(h, 0, whence::CUR);
     67 };