ref: 770c90d4a5b16a5d598072b6983e50969151b166
parent: 5197866beb5ead9160183b6ada7a76244686f9f8
author: Carlin Bingham <[email protected]>
date: Sat Mar 16 06:58:26 EDT 2019
bio.readto and EOF Hi, When using bio.readto I often want to be able to tell if the delimeter was found, or if the file was truncated, but there doesn't appear to be a way to tell if readto stopped searching because it found what it was looking for or if it reached EOF, other than to do another read. A simple solution to this would be a new function that reads to and includes the delimeter in the returned slice if it was found, which can be used intead when you care. I've tentatively included a patch for this. Is this something that would be wanted? Is there a better solution? Or a better name? -- Carlin NB. I've stolen the `Keep tag that was already there but apparently never used. Not sure if it was intended for a higher purpose. >From c230b380fbf0e7ba2c24aae332e4ce8016843d66 Mon Sep 17 00:00:00 2001 From: Carlin Bingham <[email protected]> Date: Sat, 16 Mar 2019 10:20:23 +1300 Subject: [PATCH] Add bio.readtoinc - read to including delimiter X-Spam-Status: No, hits=0.000000 required=0.900000 Similar to bio.readto except it includes the delimeter in the returned slice if it was found, making the absence of the delimiter indicate EOF
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -28,6 +28,7 @@
/* delimited read; returns freshly allocated buffer. */
const readln : (f : file# -> std.result(byte[:], err))
const readto : (f : file#, delim : byte[:] -> std.result(byte[:], err))
+ const readtoinc : (f: file#, delim : byte[:] -> std.result(byte[:], err))
const skipto : (f : file#, delim : byte[:] -> bool)
const skipspace : (f : file# -> bool)
@@ -327,6 +328,11 @@
-> readdelim(f, delim, `Read)
}
+/* same as readto, but includes the delimiter if it was found */
+const readtoinc = {f, delim
+ -> readdelim(f, delim, `Keep)
+}
+
/* same as readto, but drops the read data. */
const skipto = {f, delim
match readdelim(f, delim, `Drop)
@@ -413,7 +419,7 @@
match mode
| `Drop: f.rstart += f.rend - f.rstart
| `Read: readinto(f, &ret, f.rend - f.rstart)
- | `Keep:
+ | `Keep: readinto(f, &ret, f.rend - f.rstart)
;;
match ret.len
| 0: -> `std.Err `Eof
@@ -432,11 +438,14 @@
;;
/* If we found it, return that information */
match mode
- | `Drop: f.rstart = i
- | `Read: readinto(f, &ret, i - f.rstart)
- | `Keep:
+ | `Drop:
+ f.rstart = i + delim.len
+ | `Read:
+ readinto(f, &ret, i - f.rstart)
+ f.rstart += delim.len
+ | `Keep:
+ readinto(f, &ret, i + delim.len - f.rstart)
;;
- f.rstart += delim.len
-> `std.Ok ret
:nextiter
;;
@@ -443,7 +452,7 @@
match mode
| `Drop: f.rstart = i
| `Read: readinto(f, &ret, i - f.rstart)
- | `Keep:
+ | `Keep: readinto(f, &ret, i - f.rstart)
;;
;;
std.die("unreachable")
--- /dev/null
+++ b/lib/bio/test/bio-readtoinc.myr
@@ -1,0 +1,30 @@
+use std
+use bio
+
+const main = {
+ var f
+
+ f = std.try(bio.open("data/bio-readtoinc", bio.Rd))
+
+ readtoinc(f, ";")
+ readtoinc(f, "]]]")
+ readtoinc(f, "\n")
+ readtoinc(f, ",")
+ readtoinc(f, ",")
+ readtoinc(f, ",")
+ readtoinc(f, "the end")
+
+ bio.close(f)
+}
+
+const readtoinc = {f, d
+ match bio.readtoinc(f, d)
+ | `std.Ok s:
+ std.put("{}\n", s)
+ std.slfree(s)
+ | `std.Err `bio.Eof:
+ std.put("eof\n")
+ | `std.Err _:
+ std.put("err\n")
+ ;;
+}
--- /dev/null
+++ b/lib/bio/test/data/bio-readtoinc
@@ -1,0 +1,2 @@
+data with semicolon;multiple delims]]]a new line
+data separated,with commas until,no more
--- /dev/null
+++ b/lib/bio/test/data/bio-readtoinc-expected
@@ -1,0 +1,9 @@
+data with semicolon;
+multiple delims]]]
+a new line
+
+data separated,
+with commas until,
+no more
+
+eof
--- a/lib/bio/test/tests
+++ b/lib/bio/test/tests
@@ -24,6 +24,7 @@
B bio-read C
B bio-write F tmpout/test-write
B bio-delim C
+B bio-readtoinc C
B bio-endianwr F tmpout/test-endianwr
B bio-endianrd C
B bio-unitwr F tmpout/test-unitwr