{-# LANGUAGE ForeignFunctionInterface #-} module Bio.Util.MMap where import Bio.Prelude import Data.ByteString.Internal ( fromForeignPtr ) import Foreign.C.Types unsafeMMapFile :: FilePath -> IO Bytes 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 ())