hsdev-0.1.3.0: src/System/Win32/FileMapping/Memory.hs
module System.Win32.FileMapping.Memory (
createMap, openMap, mapFile,
withMapFile, readMapFile
) where
import Control.Arrow (left)
import Control.Monad.Catch
import Control.Monad.Cont
import Control.Monad.Error
import Data.ByteString.Char8
import qualified Data.ByteString.Char8 as BS
import Foreign.Ptr
import System.Win32.File (closeHandle)
import System.Win32.FileMapping hiding (mapFile)
import System.Win32.Types
import System.Win32.Mem
createMap :: Maybe HANDLE -> ProtectFlags -> DDWORD -> Maybe String -> ContT r IO HANDLE
createMap mh pf sz mn = ContT $ bracket
(verify iNVALID_HANDLE_VALUE "Invalid handle" $
createFileMapping mh pf sz mn)
closeHandle
openMap :: FileMapAccess -> Bool -> Maybe String -> ContT r IO HANDLE
openMap f i mn = ContT $ bracket
(verify iNVALID_HANDLE_VALUE "Invalid handle" $
openFileMapping f i mn)
closeHandle
mapFile :: HANDLE -> FileMapAccess -> DDWORD -> SIZE_T -> IO (Ptr a)
mapFile h f off sz = verify nullPtr "null pointer" $ mapViewOfFile h f off sz
-- | Write data to named map view of file
withMapFile :: String -> ByteString -> IO a -> ErrorT String IO a
withMapFile name str act = liftE $ flip runContT return $ do
p <- ContT $ BS.useAsCString str
h <- createMap Nothing pAGE_READWRITE (fromIntegral len) (Just name)
ptr <- lift $ mapFile h fILE_MAP_ALL_ACCESS 0 0
liftIO $ do
copyMemory ptr p (fromIntegral len)
unmapViewOfFile ptr
act
where
len = BS.length str + 1
-- | Read data from named map view of file
readMapFile :: String -> ErrorT String IO ByteString
readMapFile name = liftE $ flip runContT return $ do
h <- openMap fILE_MAP_ALL_ACCESS True (Just name)
ptr <- lift $ mapFile h fILE_MAP_ALL_ACCESS 0 0
liftIO $ BS.packCString ptr
verify :: Eq a => a -> String -> IO a -> IO a
verify v str act = do
x <- act
if x == v
then ioError (userError str)
else return x
liftE :: MonadCatch m => m a -> ErrorT String m a
liftE = ErrorT . liftM (left (\(SomeException e) -> show e)) . try