summaryrefslogtreecommitdiff
path: root/lib/bio
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-02-06 19:01:04 -0800
committerOri Bernstein <ori@eigenstate.org>2016-02-06 19:01:04 -0800
commit1adef91a41d208f395953fec4c335d1580c0814b (patch)
treebf21b5f6ba9ad3b1aa7e7b2281906a7577cc0c61 /lib/bio
parent2d46e781f5fe750468e4ff9300a7fe2c81c855f5 (diff)
downloadmc-1adef91a41d208f395953fec4c335d1580c0814b.tar.gz
Fix bio bug.
Shift the start of the buffer down when filling if needed.
Diffstat (limited to 'lib/bio')
-rw-r--r--lib/bio/bio.myr29
1 files changed, 15 insertions, 14 deletions
diff --git a/lib/bio/bio.myr b/lib/bio/bio.myr
index e63be54..14cfd7d 100644
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -185,7 +185,7 @@ reads as much into 'dst' as possible, up to the size of 'dst',
returning the number of bytes read.
*/
const read = {f, dst
- var count : std.size
+ var count, cap : std.size
var d : byte[:]
/* Clear the error state so we can retry */
@@ -204,10 +204,11 @@ const read = {f, 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
- */
- if dst.len < Small
+ small reads should try to fill, so we don't have to make a
+ syscall for every read
+ */
+ cap = f.rend - f.rstart
+ if dst.len < Small && cap < dst.len
fill(f, dst.len)
;;
/* Read as much as we can from the buffer */
@@ -562,18 +563,10 @@ in buffering n bytes, false if we fail.
*/
const ensureread = {f, n
var held
- var cap
std.assert(n < f.rbuf.len, "ensured read capacity > buffer size")
held = f.rend - f.rstart
if n > held
- /* if we need to shift the slice down to the start, do it */
- cap = f.rend - f.rstart
- if n > (cap + held)
- std.slcp(f.rbuf[:cap], f.rbuf[f.rstart:f.rend])
- f.rstart = 0
- f.rend = cap
- ;;
match fill(f, n)
| `Eof: -> `Eof
| `Err e: -> `Err e
@@ -616,13 +609,21 @@ Reads as many bytes as possible from the file into
the read buffer.
*/
const fill = {f, min
- var count
+ var count, cap
count = 0
/* Clear the error state so we can retry */
if f.lasterr != 0
-> `Err geterr(f)
;;
+
+ /* if we need to shift the slice down to the start, do it */
+ cap = f.rend - f.rstart
+ if min > cap
+ std.slcp(f.rbuf[:cap], f.rbuf[f.rstart:f.rend])
+ f.rstart = 0
+ f.rend = cap
+ ;;
while count < min
/*
If we've already read data, we don't want to