shithub: mc

Download patch

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);