ref: 34ce6323c60f83f3eba916f1198b86d36c395f52
parent: 3668e19263f2c0a17055eb6fc31c97b16617f32d
author: Ori Bernstein <[email protected]>
date: Wed Dec 25 16:16:02 EST 2013
Handle EOF correctly for get[bl]e()
--- a/bio.myr
+++ b/bio.myr
@@ -41,8 +41,8 @@
/* typed binary reads */
generic putbe : (f : file#, v : @a::(tctest,tcnum,tcint) -> std.size)
generic putle : (f : file#, v : @a::(tctest,tcnum,tcint) -> std.size)
- generic getbe : (f : file# -> @a::(tctest,tcnum,tcint))
- generic getle : (f : file# -> @a::(tctest,tcnum,tcint))
+ generic getbe : (f : file# -> std.option(@a::(tctest,tcnum,tcint)))
+ generic getle : (f : file# -> std.option(@a::(tctest,tcnum,tcint)))
/* peeking */
const peekb : (f : file# -> byte)
@@ -292,17 +292,19 @@
reads a single integer-like value to the output stream, in
big endian format
*/
-generic getbe = {f -> @a::(tcnum,tcint,tctest)
+generic getbe = {f
var ret
var i
ret = 0
- ensureread(f, sizeof(@a))
+ if !ensureread(f, sizeof(@a))
+ -> `std.None
+ ;;
for i = 0; i < sizeof(@a); i++
ret <<= 8
ret |= (getb(f) castto(@a::(tcnum,tcint,tctest)))
;;
- -> ret
+ -> `std.Some ret
}
/*
@@ -309,18 +311,20 @@
reads a single integer-like value to the output stream, in
little endian format
*/
-generic getle = {f -> @a::(tcnum,tcint,tctest)
+generic getle = {f
var ret
var b
var i
ret = 0
- ensureread(f, sizeof(@a))
+ if !ensureread(f, sizeof(@a))
+ -> `std.None
+ ;;
for i = 0; i < sizeof(@a); i++
b = getb(f) castto(@a::(tcnum,tcint,tctest))
ret = ret | (b << (8*i))
;;
- -> ret
+ -> `std.Some ret
}
/* peeks a single byte from an input stream */
--- a/test/bio-endianrd.myr
+++ b/test/bio-endianrd.myr
@@ -1,6 +1,20 @@
use std
use bio
+generic getle = {fd -> @a::(tcint,tcnum,tctest)
+ match bio.getle(fd)
+ | `std.Some val: -> val
+ | `std.None: std.fatal(1, "read failed")
+ ;;
+}
+
+generic getbe = {fd -> @a::(tcint,tcnum,tctest)
+ match bio.getbe(fd)
+ | `std.Some val: -> val
+ | `std.None: std.fatal(1, "read faibed")
+ ;;
+}
+
const main = {
var b : byte
var w : uint16
@@ -19,27 +33,33 @@
/* FIXME: compiler bug. multiplication on byte
values is currently broken. */
b = 0xaa
- std.assert(bio.getle(f) == b, "le byte broken\n")
- std.assert(bio.getbe(f) == b, "be byte broken\n")
+ std.assert(getle(f) == b, "le byte broken\n")
+ std.assert(getbe(f) == b, "be byte broken\n")
*/
/* word */
w = 0xaabb
- std.assert(bio.getle(f) == w, "le word broken\n")
- std.assert(bio.getbe(f) == w, "be word broken\n")
+ std.assert(getle(f) == w, "le word broken\n")
+ std.assert(getbe(f) == w, "be word broken\n")
/* long */
l = 0xaabbccdd
- std.assert(bio.getle(f) == l, "le long broken\n")
- std.assert(bio.getbe(f) == l, "be long broken\n")
+ std.assert(getle(f) == l, "le long broken\n")
+ std.assert(getbe(f) == l, "be long broken\n")
/* quad */
q = 0x11223344aabbccdd castto(uint64)
- std.assert(bio.getle(f) == q, "le quad broken\n")
- std.assert(bio.getbe(f) == q, "be quad broken\n")
+ std.assert(getle(f) == q, "le quad broken\n")
+ std.assert(getbe(f) == q, "be quad broken\n")
- /* and test for flush on close */
+ /* end of file */
+ match bio.getle(f)
+ | `std.None:
+ | `std.Some v: std.die("read past end of file\n")
+ ;;
+
bio.close(f);
std.put("success: all reads matched\n")
}
+