hsdev-0.1.1.0: src/System/Win32/FileMapping/Memory.hs
module System.Win32.FileMapping.Memory (
createMap, openMap, mapFile,
withMapFile, readMapFile
) where
import Control.Monad.CatchIO (bracket)
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 (ErrorT String IO) HANDLE
createMap mh pf sz mn = ContT $ bracket
(verify iNVALID_HANDLE_VALUE "Invalid handle" $
liftIO (createFileMapping mh pf sz mn))
(liftIO . closeHandle)
openMap :: FileMapAccess -> Bool -> Maybe String -> ContT r (ErrorT String IO) HANDLE
openMap f i mn = ContT $ bracket
(verify iNVALID_HANDLE_VALUE "Invalid handle" $
liftIO (openFileMapping f i mn))
(liftIO . closeHandle)
mapFile :: HANDLE -> FileMapAccess -> DDWORD -> SIZE_T -> ErrorT String IO (Ptr a)
mapFile h f off sz = verify nullPtr "null pointer" $ liftIO (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 = flip runContT return $ do
p <- ContT $ \f -> ErrorT (BS.useAsCString str (runErrorT . f))
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 = 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 :: (Error e, MonadError e m, Eq a) => a -> String -> m a -> m a
verify v str act = do
x <- act
if x == v
then throwError (strMsg str)
else return x