2020-05-18 15:59:07 +03:00
|
|
|
module Data.Buffer
|
|
|
|
|
2020-07-04 03:20:44 +03:00
|
|
|
import Data.List
|
|
|
|
|
2021-06-09 01:05:10 +03:00
|
|
|
%default total
|
|
|
|
|
2020-06-11 14:42:52 +03:00
|
|
|
-- Reading and writing binary buffers. Note that this primitives are unsafe,
|
|
|
|
-- in that they don't check that buffer locations are within bounds.
|
|
|
|
-- We really need a safe wrapper!
|
|
|
|
-- They are used in the Idris compiler itself for reading/writing checked
|
|
|
|
-- files.
|
|
|
|
|
|
|
|
-- This is known to the compiler, so maybe ought to be moved to Builtin
|
2020-05-18 15:59:07 +03:00
|
|
|
export
|
|
|
|
data Buffer : Type where [external]
|
|
|
|
|
2020-06-18 01:29:54 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-size"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:getBufferSize"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:b => b.length"
|
2020-05-18 15:59:07 +03:00
|
|
|
prim__bufferSize : Buffer -> Int
|
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2020-07-01 23:55:14 +03:00
|
|
|
rawSize : HasIO io => Buffer -> io Int
|
2020-05-18 15:59:07 +03:00
|
|
|
rawSize buf = pure (prim__bufferSize buf)
|
|
|
|
|
|
|
|
%foreign "scheme:blodwen-new-buffer"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:newBuffer"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:s=>Buffer.alloc(s)"
|
2020-05-18 15:59:07 +03:00
|
|
|
prim__newBuffer : Int -> PrimIO Buffer
|
|
|
|
|
|
|
|
export
|
2020-07-01 23:55:14 +03:00
|
|
|
newBuffer : HasIO io => Int -> io (Maybe Buffer)
|
2020-05-18 15:59:07 +03:00
|
|
|
newBuffer size
|
2021-06-23 20:08:27 +03:00
|
|
|
= if size >= 0
|
|
|
|
then do buf <- primIO (prim__newBuffer size)
|
|
|
|
pure $ Just buf
|
|
|
|
else pure Nothing
|
2020-05-18 15:59:07 +03:00
|
|
|
-- if prim__nullAnyPtr buf /= 0
|
|
|
|
-- then pure Nothing
|
|
|
|
-- else pure $ Just $ MkBuffer buf size 0
|
|
|
|
|
2022-11-15 14:15:06 +03:00
|
|
|
|
|
|
|
-- There is no endianness indication (LE/BE) for UInt8 since it is a single byte
|
|
|
|
|
2022-11-15 12:42:07 +03:00
|
|
|
-- TODO: remove me when we remove the deprecated `setByte` in a future release
|
2020-05-18 15:59:07 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-setbyte"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferUInt8"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeUInt8(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setByte : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
|
2020-06-18 01:29:54 +03:00
|
|
|
|
2020-06-01 03:45:15 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-setbyte"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferUInt8"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeUInt8(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setBits8 : Buffer -> (offset : Int) -> (val: Bits8) -> PrimIO ()
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
-- Assumes val is in the range 0-255
|
2022-11-15 12:42:07 +03:00
|
|
|
||| Use `setBits8` instead, as its value is correctly limited.
|
|
|
|
%deprecate
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setByte : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
|
|
|
|
setByte buf offset val
|
|
|
|
= primIO (prim__setByte buf offset val)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setBits8 : HasIO io => Buffer -> (offset : Int) -> (val : Bits8) -> io ()
|
|
|
|
setBits8 buf offset val
|
|
|
|
= primIO (prim__setBits8 buf offset val)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2022-11-15 12:42:07 +03:00
|
|
|
-- TODO: remove me when we remove the deprecated `getByte` in a future release
|
2020-05-18 15:59:07 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-getbyte"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:getBufferByte"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readUInt8(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getByte : Buffer -> (offset : Int) -> PrimIO Int
|
2020-06-18 01:29:54 +03:00
|
|
|
|
2020-06-01 03:45:15 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-getbyte"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferUInt8"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readUInt8(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getBits8 : Buffer -> (offset : Int) -> PrimIO Bits8
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2022-11-15 12:42:07 +03:00
|
|
|
||| Use `getBits8` instead, as its value is correctly limited.
|
|
|
|
%deprecate
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getByte : HasIO io => Buffer -> (offset : Int) -> io Int
|
|
|
|
getByte buf offset
|
|
|
|
= primIO (prim__getByte buf offset)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getBits8 : HasIO io => Buffer -> (offset : Int) -> io Bits8
|
|
|
|
getBits8 buf offset
|
|
|
|
= primIO (prim__getBits8 buf offset)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-setbits16"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferUInt16LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeUInt16LE(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setBits16 : Buffer -> (offset : Int) -> (value : Bits16) -> PrimIO ()
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setBits16 : HasIO io => Buffer -> (offset : Int) -> (val : Bits16) -> io ()
|
|
|
|
setBits16 buf offset val
|
|
|
|
= primIO (prim__setBits16 buf offset val)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getbits16"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferUInt16LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readUInt16LE(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getBits16 : Buffer -> (offset : Int) -> PrimIO Bits16
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getBits16 : HasIO io => Buffer -> (offset : Int) -> io Bits16
|
|
|
|
getBits16 buf offset
|
|
|
|
= primIO (prim__getBits16 buf offset)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-setbits32"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferUInt32LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeUInt32LE(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setBits32 : Buffer -> (offset : Int) -> (value : Bits32) -> PrimIO ()
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setBits32 : HasIO io => Buffer -> (offset : Int) -> (val : Bits32) -> io ()
|
|
|
|
setBits32 buf offset val
|
|
|
|
= primIO (prim__setBits32 buf offset val)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getbits32"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferUInt32LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readUInt32LE(offset)"
|
2020-06-01 03:45:15 +03:00
|
|
|
prim__getBits32 : Buffer -> Int -> PrimIO Bits32
|
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getBits32 : HasIO io => Buffer -> (offset : Int) -> io Bits32
|
|
|
|
getBits32 buf offset
|
|
|
|
= primIO (prim__getBits32 buf offset)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-setbits64"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferUInt64LE"
|
2022-04-22 17:45:52 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeBigUInt64LE(value, offset)"
|
2020-06-01 03:45:15 +03:00
|
|
|
prim__setBits64 : Buffer -> Int -> Bits64 -> PrimIO ()
|
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setBits64 : HasIO io => Buffer -> (offset : Int) -> (val : Bits64) -> io ()
|
|
|
|
setBits64 buf offset val
|
|
|
|
= primIO (prim__setBits64 buf offset val)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getbits64"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferUInt64LE"
|
2022-04-22 17:45:52 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readBigUInt64LE(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getBits64 : Buffer -> (offset : Int) -> PrimIO Bits64
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getBits64 : HasIO io => Buffer -> (offset : Int) -> io Bits64
|
|
|
|
getBits64 buf offset
|
|
|
|
= primIO (prim__getBits64 buf offset)
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2022-11-15 14:15:06 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-setint16"
|
|
|
|
"RefC:setBufferInt16LE"
|
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeInt16LE(value, offset)"
|
|
|
|
prim__setInt16 : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
|
|
|
|
|
|
|
|
export %inline
|
|
|
|
setInt16 : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
|
|
|
|
setInt16 buf offset val
|
|
|
|
= primIO (prim__setInt16 buf offset val)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-19 19:03:18 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-setint32"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferInt32LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeInt32LE(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setInt32 : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
|
2020-05-19 19:03:18 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setInt32 : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
|
|
|
|
setInt32 buf offset val
|
|
|
|
= primIO (prim__setInt32 buf offset val)
|
2020-05-19 19:03:18 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getint32"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferInt32LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readInt32LE(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getInt32 : Buffer -> (offset : Int) -> PrimIO Int
|
2020-05-19 19:03:18 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getInt32 : HasIO io => Buffer -> (offset : Int) -> io Int
|
|
|
|
getInt32 buf offset
|
|
|
|
= primIO (prim__getInt32 buf offset)
|
2020-05-19 19:03:18 +03:00
|
|
|
|
2020-05-18 15:59:07 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-setint"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:setBufferInt64LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeInt32LE(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setInt : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setInt : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
|
|
|
|
setInt buf offset val
|
|
|
|
= primIO (prim__setInt buf offset val)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getint"
|
2022-11-15 14:15:06 +03:00
|
|
|
"RefC:getBufferInt64LE"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readInt32LE(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getInt : Buffer -> (offset : Int) -> PrimIO Int
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getInt : HasIO io => Buffer -> (offset : Int) -> io Int
|
|
|
|
getInt buf offset
|
|
|
|
= primIO (prim__getInt buf offset)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-setdouble"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:setBufferDouble"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.writeDoubleLE(value, offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setDouble : Buffer -> (offset : Int) -> (val : Double) -> PrimIO ()
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setDouble : HasIO io => Buffer -> (offset : Int) -> (val : Double) -> io ()
|
|
|
|
setDouble buf offset val
|
|
|
|
= primIO (prim__setDouble buf offset val)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getdouble"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:getBufferDouble"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset)=>buf.readDoubleLE(offset)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getDouble : Buffer -> (offset : Int) -> PrimIO Double
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getDouble : HasIO io => Buffer -> (offset : Int) -> io Double
|
|
|
|
getDouble buf offset
|
|
|
|
= primIO (prim__getDouble buf offset)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
-- Get the length of a string in bytes, rather than characters
|
|
|
|
export
|
2021-07-13 13:52:15 +03:00
|
|
|
%foreign "scheme:blodwen-stringbytelen"
|
|
|
|
"C:strlen, libc 6"
|
2022-04-22 17:45:52 +03:00
|
|
|
"javascript:lambda:(string)=>new TextEncoder().encode(string).length"
|
2020-05-18 15:59:07 +03:00
|
|
|
stringByteLength : String -> Int
|
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-setstring"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:setBufferString"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,value)=>buf.write(value, offset,buf.length - offset, 'utf-8')"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__setString : Buffer -> (offset : Int) -> (val : String) -> PrimIO ()
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
setString : HasIO io => Buffer -> (offset : Int) -> (val : String) -> io ()
|
|
|
|
setString buf offset val
|
|
|
|
= primIO (prim__setString buf offset val)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
%foreign "scheme:blodwen-buffer-getstring"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:getBufferString"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(buf,offset,len)=>buf.slice(offset, offset+len).toString('utf-8')"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__getString : Buffer -> (offset : Int) -> (len : Int) -> PrimIO String
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2021-05-09 19:31:44 +03:00
|
|
|
export %inline
|
2021-07-08 01:39:24 +03:00
|
|
|
getString : HasIO io => Buffer -> (offset : Int) -> (len : Int) -> io String
|
|
|
|
getString buf offset len
|
|
|
|
= primIO (prim__getString buf offset len)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
export
|
2021-06-09 01:05:10 +03:00
|
|
|
covering
|
2020-07-01 23:55:14 +03:00
|
|
|
bufferData : HasIO io => Buffer -> io (List Int)
|
2020-05-18 15:59:07 +03:00
|
|
|
bufferData buf
|
|
|
|
= do len <- rawSize buf
|
|
|
|
unpackTo [] len
|
|
|
|
where
|
2021-06-09 01:05:10 +03:00
|
|
|
covering
|
2020-07-01 23:55:14 +03:00
|
|
|
unpackTo : List Int -> Int -> io (List Int)
|
2020-05-18 15:59:07 +03:00
|
|
|
unpackTo acc 0 = pure acc
|
2021-07-08 01:39:24 +03:00
|
|
|
unpackTo acc offset
|
|
|
|
= do val <- getByte buf (offset - 1)
|
|
|
|
unpackTo (val :: acc) (offset - 1)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
2020-07-01 23:55:14 +03:00
|
|
|
|
2020-05-18 15:59:07 +03:00
|
|
|
%foreign "scheme:blodwen-buffer-copydata"
|
2021-06-10 13:19:09 +03:00
|
|
|
"RefC:copyBuffer"
|
2021-07-10 13:15:21 +03:00
|
|
|
"node:lambda:(b1,o1,length,b2,o2)=>b1.copy(b2,o2,o1,o1+length)"
|
2021-07-08 01:39:24 +03:00
|
|
|
prim__copyData : (src : Buffer) -> (srcOffset, len : Int) ->
|
|
|
|
(dst : Buffer) -> (dstOffset : Int) -> PrimIO ()
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
export
|
2021-07-08 01:39:24 +03:00
|
|
|
copyData : HasIO io => Buffer -> (srcOffset, len : Int) ->
|
|
|
|
(dst : Buffer) -> (dstOffset : Int) -> io ()
|
|
|
|
copyData src start len dest offset
|
|
|
|
= primIO (prim__copyData src start len dest offset)
|
2020-05-18 15:59:07 +03:00
|
|
|
|
|
|
|
export
|
2020-07-01 23:55:14 +03:00
|
|
|
resizeBuffer : HasIO io => Buffer -> Int -> io (Maybe Buffer)
|
2020-05-18 15:59:07 +03:00
|
|
|
resizeBuffer old newsize
|
|
|
|
= do Just buf <- newBuffer newsize
|
|
|
|
| Nothing => pure Nothing
|
|
|
|
-- If the new buffer is smaller than the old one, just copy what
|
|
|
|
-- fits
|
|
|
|
oldsize <- rawSize old
|
|
|
|
let len = if newsize < oldsize then newsize else oldsize
|
|
|
|
copyData old 0 len buf 0
|
|
|
|
pure (Just buf)
|
2020-07-04 03:20:44 +03:00
|
|
|
|
|
|
|
||| Create a buffer containing the concatenated content from a
|
|
|
|
||| list of buffers.
|
|
|
|
export
|
|
|
|
concatBuffers : HasIO io => List Buffer -> io (Maybe Buffer)
|
|
|
|
concatBuffers xs
|
|
|
|
= do let sizes = map prim__bufferSize xs
|
|
|
|
let (totalSize, revCumulative) = foldl scanSize (0,[]) sizes
|
|
|
|
let cumulative = reverse revCumulative
|
|
|
|
Just buf <- newBuffer totalSize
|
|
|
|
| Nothing => pure Nothing
|
2021-02-24 14:07:16 +03:00
|
|
|
traverse_ (\(b, size, watermark) => copyData b 0 size buf watermark) (zip3 xs sizes cumulative)
|
2020-07-04 03:20:44 +03:00
|
|
|
pure (Just buf)
|
|
|
|
where
|
|
|
|
scanSize : (Int, List Int) -> Int -> (Int, List Int)
|
|
|
|
scanSize (s, cs) x = (s+x, s::cs)
|
|
|
|
|
|
|
|
||| Split a buffer into two at a position.
|
|
|
|
export
|
|
|
|
splitBuffer : HasIO io => Buffer -> Int -> io (Maybe (Buffer, Buffer))
|
|
|
|
splitBuffer buf pos = do size <- rawSize buf
|
2020-07-04 12:37:37 +03:00
|
|
|
if pos > 0 && pos < size
|
|
|
|
then do Just first <- newBuffer pos
|
2020-07-04 03:20:44 +03:00
|
|
|
| Nothing => pure Nothing
|
|
|
|
Just second <- newBuffer (size - pos)
|
|
|
|
| Nothing => pure Nothing
|
|
|
|
copyData buf 0 pos first 0
|
|
|
|
copyData buf pos (size-pos) second 0
|
|
|
|
pure $ Just (first, second)
|
2020-07-04 12:37:37 +03:00
|
|
|
else pure Nothing
|