structure Buffer = struct fun append (a : Word8ArraySlice.slice) (b : Word8ArraySlice.slice) : Word8ArraySlice.slice = let val bLen = Word8ArraySlice.length b val (base, i, aLen) = Word8ArraySlice.base a val baseLen = Word8Array.length base in if i + aLen + bLen <= baseLen then (Word8ArraySlice.copy { 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.copy { 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.WR { name = "buffer" , chunkSize = 1 , writeVec = NONE , writeArr = SOME (fn a => (buffer := append (!buffer) a ; Word8ArraySlice.length a)) , writeVecNB = NONE , writeArrNB = NONE , block = NONE , canOutput = NONE , getPos = NONE , setPos = NONE , endPos = NONE , verifyPos = NONE , close = fn () => () , ioDesc = NONE }, IO.NO_BUF)), buffer) end end