{-# LANGUAGE ForeignFunctionInterface #-} module Bio.Util.MMap ( unsafeMMapFile ) where import BasePrelude import Data.ByteString.Internal ( fromForeignPtr, ByteString ) import Foreign.C.Types import System.Posix.Files import System.Posix.IO unsafeMMapFile :: FilePath -> IO ByteString unsafeMMapFile fp = bracket (openFd fp ReadOnly Nothing defaultFileFlags) closeFd $ \fd -> do stat <- getFdStatus fd let size = fromIntegral (fileSize stat) if size <= 0 then return mempty else do ptr <- c_mmap size (fromIntegral fd) if ptr == nullPtr then error "unable to mmap file" else do fptr <- newForeignPtrEnv c_munmap (intPtrToPtr $ fromIntegral size) ptr return $ fromForeignPtr fptr 0 (fromIntegral size) foreign import ccall unsafe "my_mmap" c_mmap :: CSize -> CInt -> IO (Ptr Word8) foreign import ccall unsafe "&my_munmap" c_munmap :: FunPtr (Ptr () -> Ptr Word8 -> IO ())