module LLVM.General.Internal.RawOStream where import LLVM.General.Prelude import Control.Monad.Exceptable import Control.Monad.AnyCont import Data.IORef import Foreign.C import Foreign.Ptr import qualified LLVM.General.Internal.FFI.RawOStream as FFI import LLVM.General.Internal.Coding import LLVM.General.Internal.Inject import LLVM.General.Internal.String () withFileRawOStream :: (Inject String e, MonadError e m, MonadAnyCont IO m, MonadIO m) => String -> Bool -> Bool -> (Ptr FFI.RawOStream -> ExceptT String IO ()) -> m () withFileRawOStream path excl binary c = do path <- encodeM path excl <- encodeM excl binary <- encodeM binary msgPtr <- alloca errorRef <- liftIO $ newIORef undefined succeeded <- decodeM =<< (liftIO $ FFI.withFileRawOStream path excl binary msgPtr $ \os -> do r <- runExceptableT (ExceptableT $ c os) writeIORef errorRef r) unless succeeded $ do s <- decodeM msgPtr throwError $ inject (s :: String) e <- liftIO $ readIORef errorRef either (throwError . inject) return e withBufferRawOStream :: (Inject String e, MonadError e m, MonadIO m, DecodeM IO a (Ptr CChar, CSize)) => (Ptr FFI.RawOStream -> ExceptT String IO ()) -> m a withBufferRawOStream c = do resultRef <- liftIO $ newIORef Nothing errorRef <- liftIO $ newIORef undefined let saveBuffer :: Ptr CChar -> CSize -> IO () saveBuffer start size = do r <- decodeM (start, size) writeIORef resultRef (Just r) saveError os = do r <- runExceptableT (ExceptableT $ c os) writeIORef errorRef r liftIO $ FFI.withBufferRawOStream saveBuffer saveError e <- liftIO $ readIORef errorRef case e of Left e -> throwError $ inject e _ -> do Just r <- liftIO $ readIORef resultRef return r