ref: 1018f0d5c592cbe9c2d78b7197369f422ffa26b0
parent: aeff53ae83c1b00f86934d85033d710f8826ba36
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Oct 15 19:52:42 EDT 2018
Fixes to libbio (Thanks, Mike)
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -44,6 +44,11 @@
const Bufsz = 16*std.KiB
const Small = 512
+type skipmode = union
+ `Drop
+ `Read
+ `Keep
+;;
impl disposable file# =
__dispose__ = {f
@@ -134,6 +139,7 @@
var count, cap : std.size
var d : byte[:]
+ std.assert(f.mode & Rd != 0, "File is not in read mode")
/* Clear the error state so we can retry */
if f.lasterr != 0
-> `std.Err geterr(f)
@@ -148,7 +154,6 @@
if dst.len == 0
-> `std.Ok dst
;;
- std.assert(f.mode & Rd != 0, "File is not in read mode")
/*
small reads should try to fill, so we don't have to make a
syscall for every read
@@ -219,6 +224,7 @@
/* writes a single byte to the output stream */
const putb = {f, b
+ std.assert(f.mode & Wr != 0, "File is not in write mode")
match ensurewrite(f, 1)
| `std.Err e: -> `std.Err e
| `std.Ok n:
@@ -231,6 +237,7 @@
const putc = {f, c
var sz
+ std.assert(f.mode & Wr != 0, "File is not in write mode")
sz = std.charlen(c)
match ensurewrite(f, sz)
| `std.Err e: -> `std.Err e
@@ -243,6 +250,7 @@
/* reads a single byte from the input stream */
const getb = {f
+ std.assert(f.mode & Rd != 0, "File is not in read mode")
match ensureread(f, 1)
| `std.Err e: -> `std.Err e
| `std.Ok n:
@@ -254,6 +262,7 @@
const getc = {f
var c
+ std.assert(f.mode & Rd != 0, "File is not in read mode")
match ensurecodepoint(f)
| `std.Err e: -> `std.Err e
| `std.Ok n:
@@ -287,30 +296,6 @@
;;
}
-/*
- writes a single integer-like value to the output stream, in
- little endian format
-*/
-generic putle = {f, v : @a :: numeric,integral @a
- for var i = 0; i < sizeof(@a); i++
- putb(f, (v & 0xff : byte))
- v >>= 8
- ;;
- -> sizeof(@a)
-}
-
-/*
- writes a single integer-like value to the output stream, in
- big endian format
-*/
-generic putbe = {f, v : @a :: numeric,integral @a
- for var i = sizeof(@a); i != 0; i--
- putb(f, ((v >> ((i-1)*8)) & 0xff : byte))
- ;;
- -> sizeof(@a)
-}
-
-
/* peeks a single byte from an input stream */
const peekb = {f
match ensureread(f, 1)
@@ -330,8 +315,8 @@
}
/*
- reads up to a single character delimiter. drops the delimiter
- from the input stream. EOF always counts as a delimiter.
+ Reads up to a delimiter string. Drops the delimiter from
+ the input stream. EOF always counts as a delimiter.
Eg, with the input "foo,bar\n"
@@ -339,14 +324,14 @@
bio.readto(f, ',') -> "bar\n"
*/
const readto = {f, delim
- -> readdelim(f, delim, false)
+ -> readdelim(f, delim, `Read)
}
/* same as readto, but drops the read data. */
const skipto = {f, delim
- match readdelim(f, delim, true)
- | `std.Ok ign: -> true
- | `std.Err _: -> false
+ match readdelim(f, delim, `Drop)
+ | `std.Ok _: -> true
+ | `std.Err _: -> false
;;
}
@@ -408,12 +393,15 @@
;;
}
-const readdelim = {f, delim, drop
+const readdelim = {f, delim, mode
var ret, i, j
var pr
ret = [][:]
pr = false
+ if delim.len == 0
+ -> `std.Ok ret
+ ;;
while true
match ensureread(f, delim.len)
| `std.Err `Eof:
@@ -424,10 +412,10 @@
* delimiter at the end. If we're at 0 bytes even
* then, return an eof.
*/
- if drop
- f.rstart += f.rend - f.rstart
- else
- readinto(f, &ret, f.rend - f.rstart)
+ match mode
+ | `Drop: f.rstart += f.rend - f.rstart
+ | `Read: readinto(f, &ret, f.rend - f.rstart)
+ | `Keep:
;;
match ret.len
| 0: -> `std.Err `Eof
@@ -443,10 +431,10 @@
;;
;;
/* If we found it, return that information */
- if !drop
- readinto(f, &ret, i - f.rstart)
- else
- f.rstart = i
+ match mode
+ | `Drop: f.rstart = i
+ | `Read: readinto(f, &ret, i - f.rstart)
+ | `Keep:
;;
f.rstart += delim.len
-> `std.Ok ret
@@ -453,10 +441,10 @@
:notfound
f.rstart = i
;;
- if !drop
- readinto(f, &ret, f.rend - f.rstart)
- else
- f.rstart = i
+ match mode
+ | `Drop: f.rstart = i
+ | `Read: readinto(f, &ret, f.rend - f.rstart)
+ | `Keep:
;;
;;
std.die("unreachable")