ref: 60c4147b74bfe21062e6663dfc7bf1ec306e5601
parent: 287133959e79176c450af23efe31f0ac3b695679
author: Ori Bernstein <[email protected]>
date: Mon Jan 13 19:36:24 EST 2014
Use the right capacity when shifting rbuf.
--- a/bio.myr
+++ b/bio.myr
@@ -51,6 +51,7 @@
/* 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)
@@ -358,7 +359,7 @@
bio.readto(f, ',') -> "bar\n"
*/
const readto = {f, delim
- var ret : byte[:]
+ var ret
var i, j
ret = [][:]
@@ -375,7 +376,7 @@
if f.rbuf[i] == delim[0]
for j = 0; j < delim.len; j++
if f.rbuf[i + j] != delim[j]
- goto nextiter
+ goto nextiter1
;;
;;
ret = readinto(f, ret, i - f.rstart)
@@ -382,7 +383,8 @@
f.rstart += delim.len
-> `std.Some ret
;;
-:nextiter
+/* compiler bug: labels are global */
+:nextiter1
;;
ret = readinto(f, ret, i - f.rstart)
;;
@@ -389,6 +391,32 @@
std.die("unreachable")
}
+const skipto = {f, delim
+ var i, j
+
+ while true
+ /* clear the buffer and signal EOF */
+ if !ensureread(f, delim.len)
+ f.rstart = 0
+ f.rend = 0
+ -> false
+ ;;
+ for i = f.rstart; i < f.rend; i++
+ if f.rbuf[i] == delim[0]
+ for j = 0; j < delim.len; j++
+ if f.rbuf[i + j] != delim[j]
+ goto nextiter2
+ ;;
+ ;;
+ ;;
+ f.rstart += delim.len
+ -> false
+ ;;
+/* compiler bug: labels are global */
+:nextiter2
+ ;;
+}
+
/* Same as readto, but the delimiter is always a '\n' */
const readln = {f
-> readto(f, "\n")
@@ -441,7 +469,7 @@
held = f.rend - f.rstart
if n > held
/* if we need to shift the slice down to the start, do it */
- cap = f.rbuf.len - f.rend
+ cap = f.rend - f.rstart
if n > (cap + held)
std.slcp(f.rbuf[:cap], f.rbuf[f.rstart:f.rend])
f.rstart = 0