{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module System.IO.Streams.Handle
(
handleToInputStream
, handleToOutputStream
, 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 = 32752
handleToInputStream :: Handle -> IO (InputStream ByteString)
handleToInputStream h = makeInputStream f
where
f = do
x <- S.hGetSome h bUFSIZ
return $! if S.null x then Nothing else Just x
handleToOutputStream :: Handle -> IO (OutputStream ByteString)
handleToOutputStream h = makeOutputStream f
where
f Nothing = hFlush h
f (Just x) = if S.null x
then hFlush h
else S.hPut h x
inputStreamToHandle :: InputStream ByteString -> IO Handle
inputStreamToHandle is0 = do
is <- lockingInputStream is0
h <- H.mkDuplexHandle is "*input-stream*" Nothing $! H.noNewlineTranslation
H.hSetBuffering h H.NoBuffering
return h
outputStreamToHandle :: OutputStream ByteString -> IO Handle
outputStreamToHandle os0 = do
os <- lockingOutputStream 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 is0 os0 = do
is <- lockingInputStream 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 = unsafePerformIO (handleToInputStream IO.stdin >>= lockingInputStream)
{-# NOINLINE stdin #-}
stdout :: OutputStream ByteString
stdout = unsafePerformIO (handleToOutputStream IO.stdout >>=
lockingOutputStream)
{-# NOINLINE stdout #-}
stderr :: OutputStream ByteString
stderr = unsafePerformIO (handleToOutputStream IO.stderr >>=
lockingOutputStream)
{-# NOINLINE stderr #-}