diff options
Diffstat (limited to 'buffer.sml')
| -rw-r--r-- | buffer.sml | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/buffer.sml b/buffer.sml new file mode 100644 index 0000000..03292bb --- /dev/null +++ b/buffer.sml @@ -0,0 +1,51 @@ +structure Buffer = +struct + fun append (a : Word8ArraySlice.slice) (b : Word8VectorSlice.slice) : Word8ArraySlice.slice = + let + val bLen = Word8VectorSlice.length b + val (base, i, aLen) = Word8ArraySlice.base a + val baseLen = Word8Array.length base + in + if i + aLen + bLen <= baseLen + then + (Word8ArraySlice.copyVec { src = b, dst = base, di = i + aLen } ; + Word8ArraySlice.slice (base, i, SOME (aLen + bLen))) + else + let val newBuf = Word8Array.array (baseLen * 2 + bLen, Word8.fromInt 0) + in + Word8ArraySlice.copy { src = a, dst = newBuf, di = 0 } ; + Word8ArraySlice.copyVec { src = b, dst = newBuf, di = aLen } ; + Word8ArraySlice.slice (newBuf, 0, SOME (aLen + bLen)) + end + end + + fun buf () : BinIO.outstream * Word8ArraySlice.slice ref = + let val buffer = ref (Word8ArraySlice.full (Word8Array.array (0, Word8.fromInt 0))) + in + (BinIO.mkOutstream + (BinIO.StreamIO.mkOutstream + (BinPrimIO.augmentWriter + (BinPrimIO.WR + { name = "buffer" + , chunkSize = 1 + , writeVec = + SOME + (fn a => + (buffer := append (!buffer) a ; + Word8VectorSlice.length a)) + , writeArr = NONE + , writeVecNB = NONE + , writeArrNB = NONE + , block = SOME (fn () => ()) + , canOutput = SOME (fn () => true) + , getPos = NONE + , setPos = NONE + , endPos = NONE + , verifyPos = NONE + , close = fn () => () + , ioDesc = NONE + }), + IO.NO_BUF)), + buffer) + end +end |
