{-# LANGUAGE CPP #-}
module Import
( module X
-- * Utilities borrowed from 'errors'
, hush
, note
, fmapL
-- * Text-based string marshallers
, withTString
, withTStringLen
, withMaybeTString
, peekMaybeTString
-- * memory cleanup
, scrubbing
, scrubbing_
, scrubWith_
, scrubWith
) where
#if MIN_VERSION_base(4,8,0)
#else
import Control.Applicative as X
#endif
import Data.Char (chr)
import Data.Monoid as X
import Foreign as X
import Foreign.C.Types as X
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Foreign as T
import System.Win32.Error as X
import System.Win32.Error.Foreign as X
import System.Win32.Types as X
hiding ( ErrCode, failIfNull, failWith, failUnlessSuccess
, failIfFalse_, failIf, errorWin, withTString, withTStringLen)
import qualified System.Win32.Types as W32
-- |Peek a string that might be null. Null pointers become Nothing
peekMaybeTString :: LPTSTR -> IO (Maybe String)
peekMaybeTString ptr
| ptr == nullPtr = return Nothing
| otherwise = Just <$> peekTString ptr
-- |Temporarily marshal a Maybe String. A nothing becomes a null pointer.
withMaybeTString :: Maybe String -> (LPTSTR -> IO a) -> IO a
withMaybeTString Nothing f = f nullPtr
withMaybeTString (Just str) f = W32.withTString str f
withTStringLen :: Text -> (LPTSTR -> T.I16 -> IO a) -> IO a
withTStringLen text act = T.useAsPtr (T.snoc text (chr 0x0)) $ \ptr len ->
act (castPtr ptr) len
withTString :: Text -> (LPTSTR -> IO a) -> IO a
withTString text act = withTStringLen text $ \ptr _ -> act ptr
-- | Suppress the 'Left' value of an 'Either'
-- taken from the errors package
hush :: Either a b -> Maybe b
hush = either (const Nothing) Just
-- taken from the errors package
note :: e -> Maybe a -> Either e a
note e Nothing = Left e
note _ (Just x) = Right x
-- taken from the errors package
fmapL :: (a -> b) -> Either a r -> Either b r
fmapL f (Left x) = Left (f x)
fmapL _ (Right x) = (Right x)
-- | Perform an action over a double pointer, and then zero it out. If the
-- double pointer is already zeroed out, do nothing and return 'Nothing'.
scrubbing :: (Ptr a -> IO b) -> Ptr (Ptr a) -> IO (Maybe b)
scrubbing f pptr = do
ptr <- peek pptr
if ptr == nullPtr
then return Nothing
else do
ret <- f ptr
poke pptr nullPtr
return $ Just ret
-- |Perform a cleanup operation on memory.
scrubbing_ :: (Ptr a -> IO ()) -> Ptr (Ptr a) -> IO ()
scrubbing_ f pptr = do
_ <- scrubbing f pptr
return ()
scrubWith :: Ptr (Ptr a) -> (Ptr a -> IO b) -> IO (Maybe b)
scrubWith = flip scrubbing
scrubWith_ :: Ptr (Ptr a) -> (Ptr a -> IO ()) -> IO ()
scrubWith_ pptr f = do
_ <-scrubWith pptr f
return ()