{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module System.IO.Streams.Handle
(
handleToInputStream
, handleToOutputStream
, handleToStreams
, inputStreamToHandle
, outputStreamToHandle
, streamPairToHandle
, stdin
, stdout
, stderr
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as S
import qualified GHC.IO.Handle as H
import System.IO (Handle, hFlush)
import qualified System.IO as IO
import System.IO.Unsafe (unsafePerformIO)
import System.IO.Streams.Internal (InputStream, OutputStream, SP (..), lockingInputStream, lockingOutputStream, makeInputStream, makeOutputStream)
bUFSIZ :: Int
bUFSIZ :: Int
bUFSIZ = Int
32752
handleToInputStream :: Handle -> IO (InputStream ByteString)
handleToInputStream :: Handle -> IO (InputStream ByteString)
handleToInputStream Handle
h = IO (Maybe ByteString) -> IO (InputStream ByteString)
forall a. IO (Maybe a) -> IO (InputStream a)
makeInputStream IO (Maybe ByteString)
f
where
f :: IO (Maybe ByteString)
f = do
x <- Handle -> Int -> IO ByteString
S.hGetSome Handle
h Int
bUFSIZ
return $! if S.null x then Nothing else Just x
handleToOutputStream :: Handle -> IO (OutputStream ByteString)
handleToOutputStream :: Handle -> IO (OutputStream ByteString)
handleToOutputStream Handle
h = (Maybe ByteString -> IO ()) -> IO (OutputStream ByteString)
forall a. (Maybe a -> IO ()) -> IO (OutputStream a)
makeOutputStream Maybe ByteString -> IO ()
f
where
f :: Maybe ByteString -> IO ()
f Maybe ByteString
Nothing = Handle -> IO ()
hFlush Handle
h
f (Just ByteString
x) = if ByteString -> Bool
S.null ByteString
x
then Handle -> IO ()
hFlush Handle
h
else Handle -> ByteString -> IO ()
S.hPut Handle
h ByteString
x
handleToStreams :: Handle
-> IO (InputStream ByteString, OutputStream ByteString)
handleToStreams :: Handle -> IO (InputStream ByteString, OutputStream ByteString)
handleToStreams Handle
h = do
is <- Handle -> IO (InputStream ByteString)
handleToInputStream Handle
h
os <- handleToOutputStream h
return $! (is, os)
inputStreamToHandle :: InputStream ByteString -> IO Handle
inputStreamToHandle :: InputStream ByteString -> IO Handle
inputStreamToHandle InputStream ByteString
is0 = do
is <- InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
lockingInputStream InputStream ByteString
is0
h <- H.mkDuplexHandle is "*input-stream*" Nothing $! H.noNewlineTranslation
H.hSetBuffering h H.NoBuffering
return h
outputStreamToHandle :: OutputStream ByteString -> IO Handle
outputStreamToHandle :: OutputStream ByteString -> IO Handle
outputStreamToHandle OutputStream ByteString
os0 = do
os <- OutputStream ByteString -> IO (OutputStream ByteString)
forall a. OutputStream a -> IO (OutputStream a)
lockingOutputStream OutputStream ByteString
os0
h <- H.mkDuplexHandle os "*output-stream*" Nothing $! H.noNewlineTranslation
H.hSetBuffering h H.NoBuffering
return $! h
streamPairToHandle :: InputStream ByteString -> OutputStream ByteString -> IO Handle
streamPairToHandle :: InputStream ByteString -> OutputStream ByteString -> IO Handle
streamPairToHandle InputStream ByteString
is0 OutputStream ByteString
os0 = do
is <- InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
lockingInputStream InputStream ByteString
is0
os <- lockingOutputStream os0
h <- H.mkDuplexHandle (SP is os) "*stream*" Nothing $! H.noNewlineTranslation
H.hSetBuffering h H.NoBuffering
return $! h
stdin :: InputStream ByteString
stdin :: InputStream ByteString
stdin = IO (InputStream ByteString) -> InputStream ByteString
forall a. IO a -> a
unsafePerformIO (Handle -> IO (InputStream ByteString)
handleToInputStream Handle
IO.stdin IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
lockingInputStream)
{-# NOINLINE stdin #-}
stdout :: OutputStream ByteString
stdout :: OutputStream ByteString
stdout = IO (OutputStream ByteString) -> OutputStream ByteString
forall a. IO a -> a
unsafePerformIO (Handle -> IO (OutputStream ByteString)
handleToOutputStream Handle
IO.stdout IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
OutputStream ByteString -> IO (OutputStream ByteString)
forall a. OutputStream a -> IO (OutputStream a)
lockingOutputStream)
{-# NOINLINE stdout #-}
stderr :: OutputStream ByteString
stderr :: OutputStream ByteString
stderr = IO (OutputStream ByteString) -> OutputStream ByteString
forall a. IO a -> a
unsafePerformIO (Handle -> IO (OutputStream ByteString)
handleToOutputStream Handle
IO.stderr IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
OutputStream ByteString -> IO (OutputStream ByteString)
forall a. OutputStream a -> IO (OutputStream a)
lockingOutputStream)
{-# NOINLINE stderr #-}