ref: 8fd9e2ceba598d96e07cfbf99674eb1ab025ee4f
parent: 493c8c7489b7e0cdf5aad513a4888a0360181f4c
author: Ori Bernstein <[email protected]>
date: Sat Jan 17 15:00:37 EST 2015
Move to sized reads/writes.
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
MYRLIB=bio
MYRSRC= \
- bio.myr
+ bio.myr \
+ puti.myr \
+ geti.myr
include config.mk
include mk/myr.mk
--- a/bio.myr
+++ b/bio.myr
@@ -42,12 +42,6 @@
const getb : (f : file# -> std.option(byte))
const getc : (f : file# -> std.option(char))
- /* typed binary reads */
- generic putbe : (f : file#, v : @a::(numeric,integral) -> std.size)
- generic putle : (f : file#, v : @a::(numeric,integral) -> std.size)
- generic getbe : (f : file# -> std.option(@a::(numeric,integral)))
- generic getle : (f : file# -> std.option(@a::(numeric,integral)))
-
/* peeking */
const peekb : (f : file# -> std.option(byte))
const peekc : (f : file# -> std.option(char))
@@ -59,6 +53,10 @@
/* formatted i/o */
const put : (f : file#, fmt : byte[:], args : ... -> std.size)
+
+ /* pkg funcs */
+ pkglocal const ensureread : (f : file#, n : std.size -> bool)
+ pkglocal const ensurewrite : (f : file#, n : std.size -> bool)
;;
const Bufsz = 16*std.KiB
@@ -315,45 +313,7 @@
-> sizeof(@a)
}
-/*
- reads a single integer-like value to the output stream, in
- big endian format
-*/
-generic getbe = {f
- var ret
- var i
- ret = 0
- if !ensureread(f, sizeof(@a))
- -> `std.None
- ;;
- for i = 0; i < sizeof(@a); i++
- ret <<= 8
- ret |= f.rbuf[f.rstart++] castto(@a::(numeric,integral))
- ;;
- -> `std.Some ret
-}
-
-/*
- reads a single integer-like value to the output stream, in
- little endian format
-*/
-generic getle = {f
- var ret
- var b
- var i
-
- ret = 0
- if !ensureread(f, sizeof(@a))
- -> `std.None
- ;;
- for i = 0; i < sizeof(@a); i++
- b = f.rbuf[f.rstart++] castto(@a::(numeric,integral))
- ret = ret | (b << (8*i))
- ;;
- -> `std.Some ret
-}
-
/* peeks a single byte from an input stream */
const peekb = {f
if !ensureread(f, 1)
@@ -467,8 +427,9 @@
const ensurewrite = {f, n
std.assert(n < f.wbuf.len, "ensured write capacity > buffer size")
if n > f.wbuf.len - f.wend
- flush(f)
+ -> flush(f)
;;
+ -> true
}
/*
--- a/bldfile
+++ b/bldfile
@@ -1,1 +1,5 @@
-lib bio = bio.myr;;
+lib bio =
+ bio.myr
+ geti.myr
+ puti.myr
+;;
--- /dev/null
+++ b/geti.myr
@@ -1,0 +1,63 @@
+use std
+
+use "bio.use"
+
+pkg bio =
+ /* unsigned big endian */
+ generic getbe8 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getbe16 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getbe32 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getbe64 : (f : file# -> std.option(@a::(numeric,integral)))
+
+ /* signed big endian */
+ generic getle8 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getle16 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getle32 : (f : file# -> std.option(@a::(numeric,integral)))
+ generic getle64 : (f : file# -> std.option(@a::(numeric,integral)))
+;;
+
+/*
+ reads a single integer-like value to the output stream, in
+ little endian format
+*/
+generic getle = {f, n -> std.option(@a::(numeric,integral))
+ var v, i
+
+ v = 0
+ if !ensureread(f, n)
+ -> `std.None
+ ;;
+ for i = 0; i < n; i++
+ v |= (f.rbuf[f.rstart++] castto(uint64)) << (8*(i castto(uint64)))
+ ;;
+ -> `std.Some v castto(@a::(numeric,integral))
+}
+
+/*
+ reads a single integer-like value to the output stream, in
+ big endian format
+*/
+generic getbe = {f, n -> std.option(@a::(numeric,integral))
+ var v, i
+
+ v = 0
+ if !ensureread(f,n)
+ -> `std.None
+ ;;
+ for i = 0; i < n; i++
+ v <<= 8
+ v |= (f.rbuf[f.rstart++] castto(uint64))
+ ;;
+ -> `std.Some v castto(@a::(numeric,integral))
+}
+
+generic getbe8 = {f; -> getbe(f, 1)}
+generic getbe16 = {f; -> getbe(f, 2)}
+generic getbe32 = {f; -> getbe(f, 4)}
+generic getbe64 = {f; -> getbe(f, 8)}
+
+generic getle8 = {f; -> getle(f, 1)}
+generic getle16 = {f; -> getle(f, 2)}
+generic getle32 = {f; -> getle(f, 4)}
+generic getle64 = {f; -> getle(f, 8)}
+
--- /dev/null
+++ b/puti.myr
@@ -1,0 +1,62 @@
+use std
+
+use "bio.use"
+
+pkg bio =
+ /* unsigned big endian */
+ generic putbe8 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putbe16 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putbe32 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putbe64 : (f : file#, v : @a::(numeric,integral) -> std.size)
+
+ /* unsigned little endian */
+ generic putle8 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putle16 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putle32 : (f : file#, v : @a::(numeric,integral) -> std.size)
+ generic putle64 : (f : file#, v : @a::(numeric,integral) -> std.size)
+;;
+
+generic putbe8 = {f, v; -> putbe(f, v castto(uint64), 1)}
+generic putbe16 = {f, v; -> putbe(f, v castto(uint64), 2)}
+generic putbe32 = {f, v; -> putbe(f, v castto(uint64), 4)}
+generic putbe64 = {f, v; -> putbe(f, v castto(uint64), 8)}
+
+generic putle8 = {f, v; -> putle(f, v castto(uint64), 1)}
+generic putle16 = {f, v; -> putle(f, v castto(uint64), 2)}
+generic putle32 = {f, v; -> putle(f, v castto(uint64), 4)}
+generic putle64 = {f, v; -> putle(f, v castto(uint64), 8)}
+
+const putle = {f, v, n
+ var buf : byte[8]
+
+ if !ensurewrite(f, n)
+ -> 0
+ ;;
+ buf[0] = (v >> 0) & 0xff castto(byte)
+ buf[1] = (v >> 8) & 0xff castto(byte)
+ buf[2] = (v >> 16) & 0xff castto(byte)
+ buf[3] = (v >> 24) & 0xff castto(byte)
+ buf[4] = (v >> 32) & 0xff castto(byte)
+ buf[5] = (v >> 40) & 0xff castto(byte)
+ buf[6] = (v >> 48) & 0xff castto(byte)
+ buf[7] = (v >> 56) & 0xff castto(byte)
+ write(f, buf[:n])
+}
+
+const putbe = {f, v, n
+ var buf : byte[8]
+
+ if !ensurewrite(f, n)
+ -> 0
+ ;;
+ buf[0] = (v >> 56) & 0xff castto(byte)
+ buf[1] = (v >> 48) & 0xff castto(byte)
+ buf[2] = (v >> 40) & 0xff castto(byte)
+ buf[3] = (v >> 32) & 0xff castto(byte)
+ buf[4] = (v >> 24) & 0xff castto(byte)
+ buf[5] = (v >> 16) & 0xff castto(byte)
+ buf[6] = (v >> 8) & 0xff castto(byte)
+ buf[7] = (v >> 0) & 0xff castto(byte)
+ write(f, buf[8-n:])
+}
+
--- a/test/bio-endianrd.myr
+++ b/test/bio-endianrd.myr
@@ -1,20 +1,12 @@
use std
use bio
-generic getle = {fd -> @a::(integral,numeric)
- match bio.getle(fd)
+generic try = {opt : std.option(@a::(integral,numeric))-> @a::(integral,numeric)
+ match opt
| `std.Some val: -> val
| `std.None: std.fatal(1, "read failed")
;;
}
-
-generic getbe = {fd -> @a::(integral,numeric)
- match bio.getbe(fd)
- | `std.Some val: -> val
- | `std.None: std.fatal(1, "read faibed")
- ;;
-}
-
const main = {
var b : byte
var w : uint16
@@ -33,27 +25,27 @@
/* FIXME: compiler bug. multiplication on byte
values is currently broken. */
b = 0xaa
- std.assert(getle(f) == b, "le byte broken\n")
- std.assert(getbe(f) == b, "be byte broken\n")
+ std.assert(try(bio.getle8(f)) == b, "le byte broken\n")
+ std.assert(try(bio.getbe8(f)) == b, "be byte broken\n")
*/
/* word */
w = 0xaabb
- std.assert(getle(f) == w, "le word broken\n")
- std.assert(getbe(f) == w, "be word broken\n")
+ std.assert(try(bio.getle16(f)) == w, "le word broken\n")
+ std.assert(try(bio.getbe16(f)) == w, "be word broken\n")
/* long */
l = 0xaabbccdd
- std.assert(getle(f) == l, "le long broken\n")
- std.assert(getbe(f) == l, "be long broken\n")
+ std.assert(try(bio.getle32(f)) == l, "le long broken\n")
+ std.assert(try(bio.getbe32(f)) == l, "be long broken\n")
/* quad */
q = 0x11223344aabbccdd castto(uint64)
- std.assert(getle(f) == q, "le quad broken\n")
- std.assert(getbe(f) == q, "be quad broken\n")
+ std.assert(try(bio.getle64(f)) == q, "le quad broken\n")
+ std.assert(try(bio.getbe64(f)) == q, "be quad broken\n")
/* end of file */
- match bio.getle(f)
+ match bio.getle64(f)
| `std.None:
| `std.Some v: std.die("read past end of file\n")
;;
--- a/test/bio-endianwr.myr
+++ b/test/bio-endianwr.myr
@@ -24,18 +24,18 @@
/* word */
w = 0xaabb
- bio.putle(f, w)
- bio.putbe(f, w)
+ bio.putle16(f, w)
+ bio.putbe16(f, w)
/* long */
l = 0xaabbccdd
- bio.putle(f, l)
- bio.putbe(f, l)
+ bio.putle32(f, l)
+ bio.putbe32(f, l)
/* quad */
q = 0x11223344aabbccdd castto(uint64)
- bio.putle(f, q)
- bio.putbe(f, q)
+ bio.putle64(f, q)
+ bio.putbe64(f, q)
/* and test for flush on close */
bio.close(f);