mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-18 08:42:11 +03:00
cff5fc2625
Racket appears to have a different notion of current directory than the system does, so we need to tell it which directory we think we're in when reading and writing bytevectors using the scheme file functions.
197 lines
5.6 KiB
Idris
197 lines
5.6 KiB
Idris
module Data.Buffer
|
|
|
|
import System.Directory
|
|
import System.File
|
|
|
|
export
|
|
data Buffer : Type where [external]
|
|
|
|
%foreign "scheme:blodwen-buffer-size"
|
|
prim__bufferSize : Buffer -> Int
|
|
|
|
export
|
|
rawSize : Buffer -> IO Int
|
|
rawSize buf = pure (prim__bufferSize buf)
|
|
|
|
%foreign "scheme:blodwen-new-buffer"
|
|
prim__newBuffer : Int -> PrimIO Buffer
|
|
|
|
export
|
|
newBuffer : Int -> IO (Maybe Buffer)
|
|
newBuffer size
|
|
= do buf <- primIO (prim__newBuffer size)
|
|
pure $ Just buf
|
|
-- if prim__nullAnyPtr buf /= 0
|
|
-- then pure Nothing
|
|
-- else pure $ Just $ MkBuffer buf size 0
|
|
|
|
-- might be needed if we do this in C...
|
|
export
|
|
freeBuffer : Buffer -> IO ()
|
|
freeBuffer buf = pure ()
|
|
|
|
%foreign "scheme:blodwen-buffer-setbyte"
|
|
prim__setByte : Buffer -> Int -> Int -> PrimIO ()
|
|
|
|
-- Assumes val is in the range 0-255
|
|
export
|
|
setByte : Buffer -> (loc : Int) -> (val : Int) -> IO ()
|
|
setByte buf loc val
|
|
= primIO (prim__setByte buf loc val)
|
|
|
|
%foreign "scheme:blodwen-buffer-getbyte"
|
|
prim__getByte : Buffer -> Int -> PrimIO Int
|
|
|
|
export
|
|
getByte : Buffer -> (loc : Int) -> IO Int
|
|
getByte buf loc
|
|
= primIO (prim__getByte buf loc)
|
|
|
|
%foreign "scheme:blodwen-buffer-setint32"
|
|
prim__setInt32 : Buffer -> Int -> Int -> PrimIO ()
|
|
|
|
export
|
|
setInt32 : Buffer -> (loc : Int) -> (val : Int) -> IO ()
|
|
setInt32 buf loc val
|
|
= primIO (prim__setInt32 buf loc val)
|
|
|
|
%foreign "scheme:blodwen-buffer-getint32"
|
|
prim__getInt32 : Buffer -> Int -> PrimIO Int
|
|
|
|
export
|
|
getInt32 : Buffer -> (loc : Int) -> IO Int
|
|
getInt32 buf loc
|
|
= primIO (prim__getInt32 buf loc)
|
|
|
|
%foreign "scheme:blodwen-buffer-setint"
|
|
prim__setInt : Buffer -> Int -> Int -> PrimIO ()
|
|
|
|
export
|
|
setInt : Buffer -> (loc : Int) -> (val : Int) -> IO ()
|
|
setInt buf loc val
|
|
= primIO (prim__setInt buf loc val)
|
|
|
|
%foreign "scheme:blodwen-buffer-getint"
|
|
prim__getInt : Buffer -> Int -> PrimIO Int
|
|
|
|
export
|
|
getInt : Buffer -> (loc : Int) -> IO Int
|
|
getInt buf loc
|
|
= primIO (prim__getInt buf loc)
|
|
|
|
%foreign "scheme:blodwen-buffer-setdouble"
|
|
prim__setDouble : Buffer -> Int -> Double -> PrimIO ()
|
|
|
|
export
|
|
setDouble : Buffer -> (loc : Int) -> (val : Double) -> IO ()
|
|
setDouble buf loc val
|
|
= primIO (prim__setDouble buf loc val)
|
|
|
|
%foreign "scheme:blodwen-buffer-getdouble"
|
|
prim__getDouble : Buffer -> Int -> PrimIO Double
|
|
|
|
export
|
|
getDouble : Buffer -> (loc : Int) -> IO Double
|
|
getDouble buf loc
|
|
= primIO (prim__getDouble buf loc)
|
|
|
|
-- Get the length of a string in bytes, rather than characters
|
|
export
|
|
%foreign "C:strlen,libc 6"
|
|
stringByteLength : String -> Int
|
|
|
|
%foreign "scheme:blodwen-buffer-setstring"
|
|
prim__setString : Buffer -> Int -> String -> PrimIO ()
|
|
|
|
export
|
|
setString : Buffer -> (loc : Int) -> (val : String) -> IO ()
|
|
setString buf loc val
|
|
= primIO (prim__setString buf loc val)
|
|
|
|
%foreign "scheme:blodwen-buffer-getstring"
|
|
prim__getString : Buffer -> Int -> Int -> PrimIO String
|
|
|
|
export
|
|
getString : Buffer -> (loc : Int) -> (len : Int) -> IO String
|
|
getString buf loc len
|
|
= primIO (prim__getString buf loc len)
|
|
|
|
export
|
|
bufferData : Buffer -> IO (List Int)
|
|
bufferData buf
|
|
= do len <- rawSize buf
|
|
unpackTo [] len
|
|
where
|
|
unpackTo : List Int -> Int -> IO (List Int)
|
|
unpackTo acc 0 = pure acc
|
|
unpackTo acc loc
|
|
= do val <- getByte buf (loc - 1)
|
|
unpackTo (val :: acc) (loc - 1)
|
|
|
|
%foreign "scheme:blodwen-buffer-copydata"
|
|
prim__copyData : Buffer -> Int -> Int -> Buffer -> Int -> PrimIO ()
|
|
|
|
export
|
|
copyData : (src : Buffer) -> (start, len : Int) ->
|
|
(dest : Buffer) -> (loc : Int) -> IO ()
|
|
copyData src start len dest loc
|
|
= primIO (prim__copyData src start len dest loc)
|
|
|
|
-- %foreign "scheme:blodwen-readbuffer-bytes"
|
|
-- prim__readBufferBytes : FilePtr -> AnyPtr -> Int -> Int -> PrimIO Int
|
|
--
|
|
-- export
|
|
-- readBufferFromFile : BinaryFile -> Buffer -> (maxbytes : Int) ->
|
|
-- IO (Either FileError Buffer)
|
|
-- readBufferFromFile (FHandle h) (MkBuffer buf size loc) max
|
|
-- = do read <- primIO (prim__readBufferBytes h buf loc max)
|
|
-- if read >= 0
|
|
-- then pure (Right (MkBuffer buf size (loc + read)))
|
|
-- else pure (Left FileReadError)
|
|
|
|
%foreign "scheme:blodwen-read-bytevec"
|
|
prim__readBufferFromFile : String -> String -> PrimIO Buffer
|
|
|
|
%foreign "scheme:blodwen-isbytevec"
|
|
prim__isBuffer : Buffer -> Int
|
|
|
|
-- Create a new buffer by reading all the contents from the given file
|
|
-- Fails if no bytes can be read or buffer can't be created
|
|
export
|
|
createBufferFromFile : String -> IO (Either FileError Buffer)
|
|
createBufferFromFile fn
|
|
= do Just cwd <- currentDir
|
|
| Nothing => pure (Left FileReadError)
|
|
buf <- primIO (prim__readBufferFromFile cwd fn)
|
|
if prim__isBuffer buf /= 0
|
|
then pure (Left FileReadError)
|
|
else do let sz = prim__bufferSize buf
|
|
pure (Right buf)
|
|
|
|
%foreign "scheme:blodwen-write-bytevec"
|
|
prim__writeBuffer : String -> String -> Buffer -> Int -> PrimIO Int
|
|
|
|
export
|
|
writeBufferToFile : String -> Buffer -> (maxbytes : Int) ->
|
|
IO (Either FileError ())
|
|
writeBufferToFile fn buf max
|
|
= do Just cwd <- currentDir
|
|
| Nothing => pure (Left FileReadError)
|
|
res <- primIO (prim__writeBuffer cwd fn buf max)
|
|
if res /= 0
|
|
then pure (Left FileWriteError)
|
|
else pure (Right ())
|
|
|
|
export
|
|
resizeBuffer : Buffer -> Int -> IO (Maybe Buffer)
|
|
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
|
|
freeBuffer old
|
|
pure (Just buf)
|