shithub: mc

Download patch

ref: 77c5545e66f2d1457dc79f409cb1858ba2f7605a
parent: 88ea359679904cea21275be12cbc60eb3ec1c81d
parent: 755f0be63055887635f1675ae33f8992c38e6881
author: Ori Bernstein <[email protected]>
date: Mon Oct 28 15:53:37 EDT 2013

Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/libbio

Conflicts:
	bio.myr

--- a/bio.myr
+++ b/bio.myr
@@ -59,9 +59,10 @@
 	const fill	: (f : file#, sz : std.size -> std.size)
 ;;
 
-const Bufsz = 16*1024 /* 16k */
+const Bufsz = 16*std.KiB
 const Small = 512
 
+/* Creates a file from an fd, opened in the given mode. */
 const mkfile = {fd, mode
 	var f
 
@@ -81,14 +82,20 @@
 	-> f
 }
 
+/* Opens a file with mode provided. */
 const open = {path, mode 
 	-> create(path, mode, 0o777)
 }
 
+/*
+   Creates a file for the provided path, with opened in
+   the requested mode, with the requested permissions
+*/
 const create = {path, mode, perm
 	var openmode
 	var fd
 
+	/* map from the bio modes to the unix open modes */
 	if mode == Rd
 		openmode = std.Ordonly
 	elif mode == Wr
@@ -98,6 +105,7 @@
 	;;
 	openmode |= std.Ocreat
 
+	/* open the file, and return it */
 	fd = std.open(path, openmode, perm castto(int64))
 	if fd < 0
 		-> `std.None
@@ -106,6 +114,7 @@
 	;;
 }
 
+/* closes a file, flushing it to the output fd */
 const close = {f
 	flush(f)
 	if f.mode & Rd
@@ -118,6 +127,10 @@
 	-> std.close(f.fd) == 0
 }
 
+/* 
+writes to as much from `src` as possible to a file,
+returning the number of bytes written.
+*/
 const write = {f, src
 	std.assert(f.mode & Wr != 0, "File is not in write mode")
 	/*
@@ -134,6 +147,10 @@
 	;;
 }
 
+/*
+reads as much into 'dst' as possible, up to the size of 'dst',
+returning the number of bytes read.
+*/
 const read = {f, dst
 	var n
 	var d
@@ -172,6 +189,7 @@
 	-> dst[:count]
 }
 
+/* flushes f out to the backing fd */
 const flush = {f
 	var ret
 
@@ -180,6 +198,7 @@
 	-> ret
 }
 
+/* writes a single byte to the output stream */
 const putb = {f, b
 	ensurewrite(f, 1)
 	f.wbuf[f.wend++] = b
@@ -186,6 +205,7 @@
 	-> 1
 }
 
+/* writes a single character to the output stream, encoded in utf8 */
 const putc = {f, c
 	var sz
 	
@@ -196,6 +216,7 @@
 	-> sz
 }
 
+/* reads a single byte from the input stream */
 const getb = {f
 	if ensureread(f, 1)
 		-> f.rbuf[f.rstart++]
@@ -203,6 +224,7 @@
 	-> -1
 }
 
+/* reads a single character from the input stream, encoded in utf8 */
 const getc = {f
 	var c
 
@@ -214,6 +236,7 @@
 	-> -1
 }
 
+/* ensures we have enough to read a single codepoint in the buffer */
 const ensurecodepoint = {f
 	var b
 	var len
@@ -233,6 +256,10 @@
 	-> ensureread(f, len)
 }
 
+/*
+  writes a single integer-like value to the output stream, in
+  little endian format
+*/
 generic putle = {f, v : @a::(tcnum,tcint,tctest)
 	var i
 
@@ -243,6 +270,10 @@
 	-> sizeof(@a)
 }
 
+/*
+  writes a single integer-like value to the output stream, in
+  big endian format
+*/
 generic putbe = {f, v : @a::(tcnum,tcint,tctest)
 	var i
 
@@ -252,6 +283,10 @@
 	-> sizeof(@a)
 }
 
+/*
+  reads a single integer-like value to the output stream, in
+  big endian format
+*/
 generic getbe = {f -> @a::(tcnum,tcint,tctest)
 	var ret
 	var i
@@ -265,6 +300,10 @@
 	-> ret
 }
 
+/*
+  reads a single integer-like value to the output stream, in
+  little endian format
+*/
 generic getle = {f -> @a::(tcnum,tcint,tctest)
 	var ret
 	var i
@@ -277,12 +316,13 @@
 	-> ret
 }
 
-
+/* peeks a single byte from an input stream */
 const peekb = {f
 	ensureread(f, 1)
 	-> f.rbuf[f.rstart]
 }
 
+/* peeks a single character from a utf8 encoded input stream */
 const peekc = {f
 	if !ensurecodepoint(f)
 		-> -1
@@ -290,6 +330,15 @@
 	-> std.decode(f.rbuf[f.rstart:f.rend])
 }
 
+/*
+  reads up to a single character delimiter. drops the delimiter
+  from the input stream. EOF always counts as a delimiter.
+  
+  Eg, with the input "foo,bar\n"
+
+  	bio.readto(f, ',')	-> "foo"
+  	bio.readto(f, ',')	-> "bar\n"
+*/
 const readto = {f, c
 	var buf : byte[4]
 	var srch
@@ -307,21 +356,25 @@
 	while true
 		std.put("srch.len = %i\n", srch.len)
 		if !ensureread(f, srch.len)
-			-> readappend(f, ret, 0)
+			-> readinto(f, ret, f.rend - f.rstart)
 		;;
 		for i = f.rstart; i < f.rend; i++
-			std.put("Taking %i from %i to %i\n", i castto(int), f.rstart castto(int), i - f.rstart castto(int))
-			if f.rbuf[i] == srch[0] && std.sleq(f.rbuf[i + 1:i + srch.len - 1], srch[1:])
-				ret = readappend(f, ret, i - f.rstart)
-				f.rstart += srch.len
-				-> ret
+			if std.sleq(f.rbuf[i + 1:i + srch.len - 1], srch[1:])
+				-> readinto(f, ret, i - f.rstart)
 			;;
 		;;
-		ret = readappend(f, ret, i - f.rstart)
+		ret = readinto(f, ret, i - f.rstart)
 	;;
 	-> ret
 }
 
+/*
+  reads up to a single byte delimiter. drops the delimiter
+  from the input stream. Eg, with the input "foo\xFFbar"
+
+  	bio.readto(f, 0xff)	-> "foo"
+  	bio.readto(f, 0xff)	-> "bar"
+*/
 const readtob = {f, b
 	var ret
 	var i
@@ -331,34 +384,42 @@
 	while true
 		fill(f, 1)
 		if !ensureread(f, 1)
-			-> readappend(f, ret, 0)
+			-> readinto(f, ret, 0)
 		;;
 		for i = f.rstart; i < f.rend; i++
 			if f.rbuf[i] == b
-				ret = readappend(f, ret, i - f.rstart)
+				ret = readinto(f, ret, i - f.rstart)
 				/* skip past the recognized byte */
 				f.rstart += 1
 				-> ret
 			;;
 		;;
-		ret = readappend(f, ret, i - f.rstart)
+		ret = readinto(f, ret, i - f.rstart)
 	;;
 }
 
+/* Same as readto, but the delimiter is always a '\n' */
 const readln = {f
 	-> readto(f, '\n')
 }
 
+/*
+Same as std.put, but buffered. Returns the number of bytes written.
+
+FIXME: depends on std.fmt() having a flush buffer API. Until then,
+we're stuck with a small static buffer.
+*/
 const put = {f, fmt, args
-	std.fatal(1, "Formatted put on BIO unimplemented")
-	-> 0
+	var buf : byte[2048]
+
+	-> write(f,  std.fmt(buf[:], fmt, std.vastart(&args)))
 }
 
 /* 
-appends n bytes from the read buffer onto the heap-allocated slice
-provided
+reads n bytes from the read buffer onto the heap-allocated slice
+provided.
 */
-const readappend = {f, buf, n
+const readinto = {f, buf, n
 	var ret
 
 	std.assert(f.rstart + n <= f.rend, "Reading too much from buffer")