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