Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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 <cb@xxxxxxxxxxx>
Date: Sat, 16 Mar 2019 10:20:23 +1300
Subject: [PATCH] Add bio.readtoinc - read to including delimiter

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
---
 lib/bio/bio.myr                          | 21 ++++++++++++-----
 lib/bio/test/bio-readtoinc.myr           | 30 ++++++++++++++++++++++++
 lib/bio/test/data/bio-readtoinc          |  2 ++
 lib/bio/test/data/bio-readtoinc-expected |  9 +++++++
 lib/bio/test/tests                       |  1 +
 5 files changed, 57 insertions(+), 6 deletions(-)
 create mode 100644 lib/bio/test/bio-readtoinc.myr
 create mode 100644 lib/bio/test/data/bio-readtoinc
 create mode 100644 lib/bio/test/data/bio-readtoinc-expected

diff --git a/lib/bio/bio.myr b/lib/bio/bio.myr
index 2b4d5b18..58f6a929 100644
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -28,6 +28,7 @@ pkg bio =
 	/* 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 @@ const readto = {f, delim
 	-> 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 @@ const readdelim = {f, delim, mode
 			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,18 +438,21 @@ const readdelim = {f, delim, mode
 			;;
 			/* 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
 		;;
 		match mode
 		| `Drop:	f.rstart = i
 		| `Read:	readinto(f, &ret, i - f.rstart)
-		| `Keep:
+		| `Keep:	readinto(f, &ret, i - f.rstart)
 		;;
 	;;
 	std.die("unreachable")
diff --git a/lib/bio/test/bio-readtoinc.myr b/lib/bio/test/bio-readtoinc.myr
new file mode 100644
index 00000000..a856a925
--- /dev/null
+++ b/lib/bio/test/bio-readtoinc.myr
@@ -0,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")
+	;;
+}
diff --git a/lib/bio/test/data/bio-readtoinc b/lib/bio/test/data/bio-readtoinc
new file mode 100644
index 00000000..b0a2d25d
--- /dev/null
+++ b/lib/bio/test/data/bio-readtoinc
@@ -0,0 +1,2 @@
+data with semicolon;multiple delims]]]a new line
+data separated,with commas until,no more
diff --git a/lib/bio/test/data/bio-readtoinc-expected b/lib/bio/test/data/bio-readtoinc-expected
new file mode 100644
index 00000000..ce637804
--- /dev/null
+++ b/lib/bio/test/data/bio-readtoinc-expected
@@ -0,0 +1,9 @@
+data with semicolon;
+multiple delims]]]
+a new line
+
+data separated,
+with commas until,
+no more
+
+eof
diff --git a/lib/bio/test/tests b/lib/bio/test/tests
index 81c10876..659e3a7f 100644
--- a/lib/bio/test/tests
+++ b/lib/bio/test/tests
@@ -24,6 +24,7 @@ B bio-create    F	tmpout/test-create
 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
-- 
2.20.1


Follow-Ups:
Re: bio.readto and EOFOri Bernstein <ori@xxxxxxxxxxxxxx>