module Data.Repa.Array.Auto.IO
(
readFile
, writeFile
, appendFile
, hGetArray, hGetArrayPre
, hPutArray)
where
import Data.Repa.Array.Auto.Base
import Data.Repa.Array.Generic.Convert
import Data.Word
import qualified Data.Repa.Array.Material.Foreign as A
import qualified Foreign.Ptr as F
import qualified Foreign.ForeignPtr as F
import qualified Foreign.Marshal.Alloc as F
import qualified Foreign.Marshal.Utils as F
import qualified System.IO as S
import qualified System.FileLock as S
import Prelude hiding (readFile, writeFile, appendFile)
readFile :: FilePath -> IO (Array Word8)
readFile path
= S.withFileLock path S.Shared
$ \_lock -> do
h <- S.openFile path S.ReadMode
S.hSeek h S.SeekFromEnd 0
len <- S.hTell h
S.hSeek h S.AbsoluteSeek 0
!arr <- hGetArray h (fromIntegral len)
S.hClose h
return arr
writeFile :: FilePath -> Array Word8 -> IO ()
writeFile path arr
= S.withFileLock path S.Exclusive
$ \_lock -> do
h <- S.openFile path S.WriteMode
hPutArray h arr
S.hClose h
appendFile :: FilePath -> Array Word8 -> IO ()
appendFile path arr
= S.withFileLock path S.Exclusive
$ \_lock -> do
h <- S.openFile path S.AppendMode
hPutArray h arr
S.hClose h
hGetArray :: S.Handle -> Int -> IO (Array Word8)
hGetArray h len
= do buf :: F.Ptr Word8 <- F.mallocBytes len
bytesRead <- S.hGetBuf h buf len
fptr <- F.newForeignPtr F.finalizerFree buf
return $! convert $! A.fromForeignPtr bytesRead fptr
hGetArrayPre :: S.Handle -> Int -> Array Word8 -> IO (Array Word8)
hGetArrayPre h len arr
| (offset, lenPre, fptrPre :: F.ForeignPtr Word8)
<- A.toForeignPtr $ convert arr
= F.withForeignPtr fptrPre
$ \ptrPre' -> do
let ptrPre = F.plusPtr ptrPre' offset
ptrBuf :: F.Ptr Word8 <- F.mallocBytes (lenPre + len)
F.copyBytes ptrBuf ptrPre lenPre
lenRead <- S.hGetBuf h (F.plusPtr ptrBuf lenPre) len
let bytesTotal = lenPre + lenRead
fptrBuf <- F.newForeignPtr F.finalizerFree ptrBuf
return $ convert $! A.fromForeignPtr bytesTotal fptrBuf
hPutArray :: S.Handle -> Array Word8 -> IO ()
hPutArray h arr
| (offset, lenPre, fptrPre :: F.ForeignPtr Word8)
<- A.toForeignPtr $ convert arr
= F.withForeignPtr fptrPre
$ \ptr' -> do
let ptr = F.plusPtr ptr' offset
S.hPutBuf h ptr lenPre