ref: ddff3ee8120284a2da46b3bcfeb366949b1c07d2
parent: cfa84e404def22f3bf7ccb8f0551b864ae08d926
author: Ori Bernstein <[email protected]>
date: Mon Oct 14 09:10:50 EDT 2013
Add comments.
--- 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)
}
-const create = {path, mode, perm
+/*
+ Creates a file for the provided path, with opened in
+ the requested mode, with the requested permissions
+*/
+const createfile = {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,10 @@
-> -1
}
+/*
+ writes a single integer-like value to the output stream, in
+ little endian format
+*/
generic putle = {f, v : @a::(tcnum,tcint,tctest)
var i
@@ -224,6 +250,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
@@ -233,6 +263,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
@@ -245,6 +279,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
@@ -256,17 +294,27 @@
-> 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
ensureread(f, std.Maxcharlen)
-> std.decode(f.rbuf)
}
+/*
+ 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
@@ -281,18 +329,25 @@
ret = [][:]
while true
if !ensureread(f, srch.len)
- -> readappend(f, ret, f.rend - f.rstart)
+ -> readinto(f, ret, f.rend - f.rstart)
;;
for i = f.rstart; i < f.rend; i++
- if f.rbuf[i] == srch[0] && std.sleq(f.rbuf[i + 1:i + srch.len - 1], srch[1:])
- -> readappend(f, ret, i - f.rstart)
+ 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
@@ -302,34 +357,45 @@
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]
+ var len
+
+ std.fmt(buf, fmt, valist(args))
+ len = write(f, buf)
+ -> write(f, buf[:len])
}
/*
-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")