{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP
, NoImplicitPrelude
, ExistentialQuantification
#-}
{-# OPTIONS_GHC -funbox-strict-fields #-}
{-# OPTIONS_HADDOCK not-home #-}
module GHC.IO.Handle.Types (
Handle(..), Handle__(..), showHandle,
checkHandleInvariants,
BufferList(..),
HandleType(..),
isReadableHandleType, isWritableHandleType, isReadWriteHandleType,
isAppendHandleType,
BufferMode(..),
BufferCodec(..),
NewlineMode(..), Newline(..), nativeNewline,
universalNewlineMode, noNewlineTranslation, nativeNewlineMode
) where
#undef DEBUG
import GHC.Base
import GHC.MVar
import GHC.IO
import GHC.IO.Buffer
import GHC.IO.BufferedIO
import GHC.IO.Encoding.Types
import GHC.IORef
import GHC.Show
import GHC.Read
import GHC.Word
import GHC.IO.Device
import Data.Typeable
#if defined(DEBUG)
import Control.Monad
#endif
data Handle
= FileHandle
FilePath
!(MVar Handle__)
| DuplexHandle
FilePath
!(MVar Handle__)
!(MVar Handle__)
instance Eq Handle where
(FileHandle FilePath
_ MVar Handle__
h1) == :: Handle -> Handle -> Bool
== (FileHandle FilePath
_ MVar Handle__
h2) = MVar Handle__
h1 MVar Handle__ -> MVar Handle__ -> Bool
forall a. Eq a => a -> a -> Bool
== MVar Handle__
h2
(DuplexHandle FilePath
_ MVar Handle__
h1 MVar Handle__
_) == (DuplexHandle FilePath
_ MVar Handle__
h2 MVar Handle__
_) = MVar Handle__
h1 MVar Handle__ -> MVar Handle__ -> Bool
forall a. Eq a => a -> a -> Bool
== MVar Handle__
h2
Handle
_ == Handle
_ = Bool
False
data Handle__
= forall dev enc_state dec_state . (RawIO dev, IODevice dev, BufferedIO dev, Typeable dev) =>
Handle__ {
()
haDevice :: !dev,
Handle__ -> HandleType
haType :: HandleType,
Handle__ -> IORef (Buffer Word8)
haByteBuffer :: !(IORef (Buffer Word8)),
Handle__ -> BufferMode
haBufferMode :: BufferMode,
()
haLastDecode :: !(IORef (dec_state, Buffer Word8)),
Handle__ -> IORef (Buffer CharBufElem)
haCharBuffer :: !(IORef (Buffer CharBufElem)),
Handle__ -> IORef (BufferList CharBufElem)
haBuffers :: !(IORef (BufferList CharBufElem)),
()
haEncoder :: Maybe (TextEncoder enc_state),
()
haDecoder :: Maybe (TextDecoder dec_state),
Handle__ -> Maybe TextEncoding
haCodec :: Maybe TextEncoding,
Handle__ -> Newline
haInputNL :: Newline,
Handle__ -> Newline
haOutputNL :: Newline,
Handle__ -> Maybe (MVar Handle__)
haOtherSide :: Maybe (MVar Handle__)
}
data BufferList e
= BufferListNil
| BufferListCons (RawBuffer e) (BufferList e)
data HandleType
= ClosedHandle
| SemiClosedHandle
| ReadHandle
| WriteHandle
| AppendHandle
| ReadWriteHandle
isReadableHandleType :: HandleType -> Bool
isReadableHandleType :: HandleType -> Bool
isReadableHandleType HandleType
ReadHandle = Bool
True
isReadableHandleType HandleType
ReadWriteHandle = Bool
True
isReadableHandleType HandleType
_ = Bool
False
isWritableHandleType :: HandleType -> Bool
isWritableHandleType :: HandleType -> Bool
isWritableHandleType HandleType
AppendHandle = Bool
True
isWritableHandleType HandleType
WriteHandle = Bool
True
isWritableHandleType HandleType
ReadWriteHandle = Bool
True
isWritableHandleType HandleType
_ = Bool
False
isReadWriteHandleType :: HandleType -> Bool
isReadWriteHandleType :: HandleType -> Bool
isReadWriteHandleType ReadWriteHandle{} = Bool
True
isReadWriteHandleType HandleType
_ = Bool
False
isAppendHandleType :: HandleType -> Bool
isAppendHandleType :: HandleType -> Bool
isAppendHandleType HandleType
AppendHandle = Bool
True
isAppendHandleType HandleType
_ = Bool
False
checkHandleInvariants :: Handle__ -> IO ()
#if defined(DEBUG)
checkHandleInvariants h_ = do
bbuf <- readIORef (haByteBuffer h_)
checkBuffer bbuf
cbuf <- readIORef (haCharBuffer h_)
checkBuffer cbuf
when (isWriteBuffer cbuf && not (isEmptyBuffer cbuf)) $
errorWithoutStackTrace ("checkHandleInvariants: char write buffer non-empty: " ++
summaryBuffer bbuf ++ ", " ++ summaryBuffer cbuf)
when (isWriteBuffer bbuf /= isWriteBuffer cbuf) $
errorWithoutStackTrace ("checkHandleInvariants: buffer modes differ: " ++
summaryBuffer bbuf ++ ", " ++ summaryBuffer cbuf)
#else
checkHandleInvariants :: Handle__ -> IO ()
checkHandleInvariants Handle__
_ = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
#endif
data BufferMode
= NoBuffering
| LineBuffering
| BlockBuffering (Maybe Int)
deriving ( BufferMode -> BufferMode -> Bool
(BufferMode -> BufferMode -> Bool)
-> (BufferMode -> BufferMode -> Bool) -> Eq BufferMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BufferMode -> BufferMode -> Bool
== :: BufferMode -> BufferMode -> Bool
$c/= :: BufferMode -> BufferMode -> Bool
/= :: BufferMode -> BufferMode -> Bool
Eq
, Eq BufferMode
Eq BufferMode
-> (BufferMode -> BufferMode -> Ordering)
-> (BufferMode -> BufferMode -> Bool)
-> (BufferMode -> BufferMode -> Bool)
-> (BufferMode -> BufferMode -> Bool)
-> (BufferMode -> BufferMode -> Bool)
-> (BufferMode -> BufferMode -> BufferMode)
-> (BufferMode -> BufferMode -> BufferMode)
-> Ord BufferMode
BufferMode -> BufferMode -> Bool
BufferMode -> BufferMode -> Ordering
BufferMode -> BufferMode -> BufferMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BufferMode -> BufferMode -> Ordering
compare :: BufferMode -> BufferMode -> Ordering
$c< :: BufferMode -> BufferMode -> Bool
< :: BufferMode -> BufferMode -> Bool
$c<= :: BufferMode -> BufferMode -> Bool
<= :: BufferMode -> BufferMode -> Bool
$c> :: BufferMode -> BufferMode -> Bool
> :: BufferMode -> BufferMode -> Bool
$c>= :: BufferMode -> BufferMode -> Bool
>= :: BufferMode -> BufferMode -> Bool
$cmax :: BufferMode -> BufferMode -> BufferMode
max :: BufferMode -> BufferMode -> BufferMode
$cmin :: BufferMode -> BufferMode -> BufferMode
min :: BufferMode -> BufferMode -> BufferMode
Ord
, ReadPrec [BufferMode]
ReadPrec BufferMode
Int -> ReadS BufferMode
ReadS [BufferMode]
(Int -> ReadS BufferMode)
-> ReadS [BufferMode]
-> ReadPrec BufferMode
-> ReadPrec [BufferMode]
-> Read BufferMode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS BufferMode
readsPrec :: Int -> ReadS BufferMode
$creadList :: ReadS [BufferMode]
readList :: ReadS [BufferMode]
$creadPrec :: ReadPrec BufferMode
readPrec :: ReadPrec BufferMode
$creadListPrec :: ReadPrec [BufferMode]
readListPrec :: ReadPrec [BufferMode]
Read
, Int -> BufferMode -> ShowS
[BufferMode] -> ShowS
BufferMode -> FilePath
(Int -> BufferMode -> ShowS)
-> (BufferMode -> FilePath)
-> ([BufferMode] -> ShowS)
-> Show BufferMode
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BufferMode -> ShowS
showsPrec :: Int -> BufferMode -> ShowS
$cshow :: BufferMode -> FilePath
show :: BufferMode -> FilePath
$cshowList :: [BufferMode] -> ShowS
showList :: [BufferMode] -> ShowS
Show
)
data Newline = LF
| CRLF
deriving ( Newline -> Newline -> Bool
(Newline -> Newline -> Bool)
-> (Newline -> Newline -> Bool) -> Eq Newline
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Newline -> Newline -> Bool
== :: Newline -> Newline -> Bool
$c/= :: Newline -> Newline -> Bool
/= :: Newline -> Newline -> Bool
Eq
, Eq Newline
Eq Newline
-> (Newline -> Newline -> Ordering)
-> (Newline -> Newline -> Bool)
-> (Newline -> Newline -> Bool)
-> (Newline -> Newline -> Bool)
-> (Newline -> Newline -> Bool)
-> (Newline -> Newline -> Newline)
-> (Newline -> Newline -> Newline)
-> Ord Newline
Newline -> Newline -> Bool
Newline -> Newline -> Ordering
Newline -> Newline -> Newline
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Newline -> Newline -> Ordering
compare :: Newline -> Newline -> Ordering
$c< :: Newline -> Newline -> Bool
< :: Newline -> Newline -> Bool
$c<= :: Newline -> Newline -> Bool
<= :: Newline -> Newline -> Bool
$c> :: Newline -> Newline -> Bool
> :: Newline -> Newline -> Bool
$c>= :: Newline -> Newline -> Bool
>= :: Newline -> Newline -> Bool
$cmax :: Newline -> Newline -> Newline
max :: Newline -> Newline -> Newline
$cmin :: Newline -> Newline -> Newline
min :: Newline -> Newline -> Newline
Ord
, ReadPrec [Newline]
ReadPrec Newline
Int -> ReadS Newline
ReadS [Newline]
(Int -> ReadS Newline)
-> ReadS [Newline]
-> ReadPrec Newline
-> ReadPrec [Newline]
-> Read Newline
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Newline
readsPrec :: Int -> ReadS Newline
$creadList :: ReadS [Newline]
readList :: ReadS [Newline]
$creadPrec :: ReadPrec Newline
readPrec :: ReadPrec Newline
$creadListPrec :: ReadPrec [Newline]
readListPrec :: ReadPrec [Newline]
Read
, Int -> Newline -> ShowS
[Newline] -> ShowS
Newline -> FilePath
(Int -> Newline -> ShowS)
-> (Newline -> FilePath) -> ([Newline] -> ShowS) -> Show Newline
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Newline -> ShowS
showsPrec :: Int -> Newline -> ShowS
$cshow :: Newline -> FilePath
show :: Newline -> FilePath
$cshowList :: [Newline] -> ShowS
showList :: [Newline] -> ShowS
Show
)
data NewlineMode
= NewlineMode { NewlineMode -> Newline
inputNL :: Newline,
NewlineMode -> Newline
outputNL :: Newline
}
deriving ( NewlineMode -> NewlineMode -> Bool
(NewlineMode -> NewlineMode -> Bool)
-> (NewlineMode -> NewlineMode -> Bool) -> Eq NewlineMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NewlineMode -> NewlineMode -> Bool
== :: NewlineMode -> NewlineMode -> Bool
$c/= :: NewlineMode -> NewlineMode -> Bool
/= :: NewlineMode -> NewlineMode -> Bool
Eq
, Eq NewlineMode
Eq NewlineMode
-> (NewlineMode -> NewlineMode -> Ordering)
-> (NewlineMode -> NewlineMode -> Bool)
-> (NewlineMode -> NewlineMode -> Bool)
-> (NewlineMode -> NewlineMode -> Bool)
-> (NewlineMode -> NewlineMode -> Bool)
-> (NewlineMode -> NewlineMode -> NewlineMode)
-> (NewlineMode -> NewlineMode -> NewlineMode)
-> Ord NewlineMode
NewlineMode -> NewlineMode -> Bool
NewlineMode -> NewlineMode -> Ordering
NewlineMode -> NewlineMode -> NewlineMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: NewlineMode -> NewlineMode -> Ordering
compare :: NewlineMode -> NewlineMode -> Ordering
$c< :: NewlineMode -> NewlineMode -> Bool
< :: NewlineMode -> NewlineMode -> Bool
$c<= :: NewlineMode -> NewlineMode -> Bool
<= :: NewlineMode -> NewlineMode -> Bool
$c> :: NewlineMode -> NewlineMode -> Bool
> :: NewlineMode -> NewlineMode -> Bool
$c>= :: NewlineMode -> NewlineMode -> Bool
>= :: NewlineMode -> NewlineMode -> Bool
$cmax :: NewlineMode -> NewlineMode -> NewlineMode
max :: NewlineMode -> NewlineMode -> NewlineMode
$cmin :: NewlineMode -> NewlineMode -> NewlineMode
min :: NewlineMode -> NewlineMode -> NewlineMode
Ord
, ReadPrec [NewlineMode]
ReadPrec NewlineMode
Int -> ReadS NewlineMode
ReadS [NewlineMode]
(Int -> ReadS NewlineMode)
-> ReadS [NewlineMode]
-> ReadPrec NewlineMode
-> ReadPrec [NewlineMode]
-> Read NewlineMode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS NewlineMode
readsPrec :: Int -> ReadS NewlineMode
$creadList :: ReadS [NewlineMode]
readList :: ReadS [NewlineMode]
$creadPrec :: ReadPrec NewlineMode
readPrec :: ReadPrec NewlineMode
$creadListPrec :: ReadPrec [NewlineMode]
readListPrec :: ReadPrec [NewlineMode]
Read
, Int -> NewlineMode -> ShowS
[NewlineMode] -> ShowS
NewlineMode -> FilePath
(Int -> NewlineMode -> ShowS)
-> (NewlineMode -> FilePath)
-> ([NewlineMode] -> ShowS)
-> Show NewlineMode
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NewlineMode -> ShowS
showsPrec :: Int -> NewlineMode -> ShowS
$cshow :: NewlineMode -> FilePath
show :: NewlineMode -> FilePath
$cshowList :: [NewlineMode] -> ShowS
showList :: [NewlineMode] -> ShowS
Show
)
nativeNewline :: Newline
#if defined(mingw32_HOST_OS)
nativeNewline = CRLF
#else
nativeNewline :: Newline
nativeNewline = Newline
LF
#endif
universalNewlineMode :: NewlineMode
universalNewlineMode :: NewlineMode
universalNewlineMode = NewlineMode { inputNL :: Newline
inputNL = Newline
CRLF,
outputNL :: Newline
outputNL = Newline
nativeNewline }
nativeNewlineMode :: NewlineMode
nativeNewlineMode :: NewlineMode
nativeNewlineMode = NewlineMode { inputNL :: Newline
inputNL = Newline
nativeNewline,
outputNL :: Newline
outputNL = Newline
nativeNewline }
noNewlineTranslation :: NewlineMode
noNewlineTranslation :: NewlineMode
noNewlineTranslation = NewlineMode { inputNL :: Newline
inputNL = Newline
LF, outputNL :: Newline
outputNL = Newline
LF }
instance Show HandleType where
showsPrec :: Int -> HandleType -> ShowS
showsPrec Int
_ HandleType
t =
case HandleType
t of
HandleType
ClosedHandle -> FilePath -> ShowS
showString FilePath
"closed"
HandleType
SemiClosedHandle -> FilePath -> ShowS
showString FilePath
"semi-closed"
HandleType
ReadHandle -> FilePath -> ShowS
showString FilePath
"readable"
HandleType
WriteHandle -> FilePath -> ShowS
showString FilePath
"writable"
HandleType
AppendHandle -> FilePath -> ShowS
showString FilePath
"writable (append)"
HandleType
ReadWriteHandle -> FilePath -> ShowS
showString FilePath
"read-writable"
instance Show Handle where
showsPrec :: Int -> Handle -> ShowS
showsPrec Int
_ (FileHandle FilePath
file MVar Handle__
_) = FilePath -> ShowS
showHandle FilePath
file
showsPrec Int
_ (DuplexHandle FilePath
file MVar Handle__
_ MVar Handle__
_) = FilePath -> ShowS
showHandle FilePath
file
showHandle :: FilePath -> String -> String
showHandle :: FilePath -> ShowS
showHandle FilePath
file = FilePath -> ShowS
showString FilePath
"{handle: " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ShowS
showString FilePath
file ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ShowS
showString FilePath
"}"