{-# LANGUAGE BangPatterns, CPP, RecordWildCards, ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
module Data.Text.IO
(
readFile
, writeFile
, appendFile
, hGetContents
, hGetChunk
, hGetLine
, hPutStr
, hPutStrLn
, interact
, getContents
, getLine
, putStr
, putStrLn
) where
import Data.Text (Text)
import Prelude hiding (appendFile, getContents, getLine, interact,
putStr, putStrLn, readFile, writeFile)
import System.IO (Handle, IOMode(..), hPutChar, openFile, stdin, stdout,
withFile)
import qualified Control.Exception as E
import Control.Monad (liftM2, when)
import Data.IORef (readIORef, writeIORef)
import qualified Data.Text as T
import Data.Text.Internal.Fusion (stream)
import Data.Text.Internal.Fusion.Types (Step(..), Stream(..))
import Data.Text.Internal.IO (hGetLineWith, readChunk)
import GHC.IO.Buffer (Buffer(..), BufferState(..), CharBufElem, CharBuffer,
RawCharBuffer, emptyBuffer, isEmptyBuffer, newCharBuffer,
writeCharBuf)
import GHC.IO.Exception (IOException(ioe_type), IOErrorType(InappropriateType))
import GHC.IO.Handle.Internals (augmentIOError, hClose_help, wantReadableHandle,
wantWritableHandle)
import GHC.IO.Handle.Text (commitBuffer')
import GHC.IO.Handle.Types (BufferList(..), BufferMode(..), Handle__(..),
HandleType(..), Newline(..))
import System.IO (hGetBuffering, hFileSize, hSetBuffering, hTell)
import System.IO.Error (isEOFError)
readFile :: FilePath -> IO Text
readFile :: FilePath -> IO Text
readFile FilePath
name = FilePath -> IOMode -> IO Handle
openFile FilePath
name IOMode
ReadMode IO Handle -> (Handle -> IO Text) -> IO Text
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Handle -> IO Text
hGetContents
writeFile :: FilePath -> Text -> IO ()
writeFile :: FilePath -> Text -> IO ()
writeFile FilePath
p = FilePath -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
p IOMode
WriteMode ((Handle -> IO ()) -> IO ())
-> (Text -> Handle -> IO ()) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Handle -> Text -> IO ()) -> Text -> Handle -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Handle -> Text -> IO ()
hPutStr
appendFile :: FilePath -> Text -> IO ()
appendFile :: FilePath -> Text -> IO ()
appendFile FilePath
p = FilePath -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
p IOMode
AppendMode ((Handle -> IO ()) -> IO ())
-> (Text -> Handle -> IO ()) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Handle -> Text -> IO ()) -> Text -> Handle -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Handle -> Text -> IO ()
hPutStr
catchError :: String -> Handle -> Handle__ -> IOError -> IO (Text, Bool)
catchError :: FilePath -> Handle -> Handle__ -> IOException -> IO (Text, Bool)
catchError FilePath
caller Handle
h Handle__{dev
Maybe (MVar Handle__)
Maybe TextEncoding
Maybe (TextEncoder enc_state)
Maybe (TextDecoder dec_state)
IORef (dec_state, Buffer Word8)
IORef (Buffer CharBufElem)
IORef (Buffer Word8)
IORef (BufferList CharBufElem)
Newline
BufferMode
HandleType
haDevice :: dev
haType :: HandleType
haByteBuffer :: IORef (Buffer Word8)
haBufferMode :: BufferMode
haLastDecode :: IORef (dec_state, Buffer Word8)
haCharBuffer :: IORef (Buffer CharBufElem)
haBuffers :: IORef (BufferList CharBufElem)
haEncoder :: Maybe (TextEncoder enc_state)
haDecoder :: Maybe (TextDecoder dec_state)
haCodec :: Maybe TextEncoding
haInputNL :: Newline
haOutputNL :: Newline
haOtherSide :: Maybe (MVar Handle__)
haOtherSide :: Handle__ -> Maybe (MVar Handle__)
haOutputNL :: Handle__ -> Newline
haInputNL :: Handle__ -> Newline
haCodec :: Handle__ -> Maybe TextEncoding
haDecoder :: ()
haEncoder :: ()
haBuffers :: Handle__ -> IORef (BufferList CharBufElem)
haCharBuffer :: Handle__ -> IORef (Buffer CharBufElem)
haLastDecode :: ()
haBufferMode :: Handle__ -> BufferMode
haByteBuffer :: Handle__ -> IORef (Buffer Word8)
haType :: Handle__ -> HandleType
haDevice :: ()
..} IOException
err
| IOException -> Bool
isEOFError IOException
err = do
buf <- IORef (Buffer CharBufElem) -> IO (Buffer CharBufElem)
forall a. IORef a -> IO a
readIORef IORef (Buffer CharBufElem)
haCharBuffer
return $ if isEmptyBuffer buf
then (T.empty, True)
else (T.singleton '\r', True)
| Bool
otherwise = IOException -> IO (Text, Bool)
forall e a. (HasCallStack, Exception e) => e -> IO a
E.throwIO (IOException -> FilePath -> Handle -> IOException
augmentIOError IOException
err FilePath
caller Handle
h)
readChunkEof :: Handle__ -> CharBuffer -> IO (Text, Bool)
readChunkEof :: Handle__ -> Buffer CharBufElem -> IO (Text, Bool)
readChunkEof Handle__
hh Buffer CharBufElem
buf = do t <- Handle__ -> Buffer CharBufElem -> IO Text
readChunk Handle__
hh Buffer CharBufElem
buf
return (t, False)
hGetChunk :: Handle -> IO Text
hGetChunk :: Handle -> IO Text
hGetChunk Handle
h = FilePath -> Handle -> (Handle__ -> IO (Handle__, Text)) -> IO Text
forall a.
FilePath -> Handle -> (Handle__ -> IO (Handle__, a)) -> IO a
wantReadableHandle FilePath
"hGetChunk" Handle
h Handle__ -> IO (Handle__, Text)
readSingleChunk
where
readSingleChunk :: Handle__ -> IO (Handle__, Text)
readSingleChunk hh :: Handle__
hh@Handle__{dev
Maybe (MVar Handle__)
Maybe TextEncoding
Maybe (TextEncoder enc_state)
Maybe (TextDecoder dec_state)
IORef (dec_state, Buffer Word8)
IORef (Buffer CharBufElem)
IORef (Buffer Word8)
IORef (BufferList CharBufElem)
Newline
BufferMode
HandleType
haOtherSide :: Handle__ -> Maybe (MVar Handle__)
haOutputNL :: Handle__ -> Newline
haInputNL :: Handle__ -> Newline
haCodec :: Handle__ -> Maybe TextEncoding
haDecoder :: ()
haEncoder :: ()
haBuffers :: Handle__ -> IORef (BufferList CharBufElem)
haCharBuffer :: Handle__ -> IORef (Buffer CharBufElem)
haLastDecode :: ()
haBufferMode :: Handle__ -> BufferMode
haByteBuffer :: Handle__ -> IORef (Buffer Word8)
haType :: Handle__ -> HandleType
haDevice :: ()
haDevice :: dev
haType :: HandleType
haByteBuffer :: IORef (Buffer Word8)
haBufferMode :: BufferMode
haLastDecode :: IORef (dec_state, Buffer Word8)
haCharBuffer :: IORef (Buffer CharBufElem)
haBuffers :: IORef (BufferList CharBufElem)
haEncoder :: Maybe (TextEncoder enc_state)
haDecoder :: Maybe (TextDecoder dec_state)
haCodec :: Maybe TextEncoding
haInputNL :: Newline
haOutputNL :: Newline
haOtherSide :: Maybe (MVar Handle__)
..} = do
buf <- IORef (Buffer CharBufElem) -> IO (Buffer CharBufElem)
forall a. IORef a -> IO a
readIORef IORef (Buffer CharBufElem)
haCharBuffer
(t, _) <- readChunkEof hh buf `E.catch` catchError "hGetChunk" h hh
return (hh, t)
hGetContents :: Handle -> IO Text
hGetContents :: Handle -> IO Text
hGetContents Handle
h = do
Handle -> IO ()
chooseGoodBuffering Handle
h
FilePath -> Handle -> (Handle__ -> IO (Handle__, Text)) -> IO Text
forall a.
FilePath -> Handle -> (Handle__ -> IO (Handle__, a)) -> IO a
wantReadableHandle FilePath
"hGetContents" Handle
h Handle__ -> IO (Handle__, Text)
readAll
where
readAll :: Handle__ -> IO (Handle__, Text)
readAll hh :: Handle__
hh@Handle__{dev
Maybe (MVar Handle__)
Maybe TextEncoding
Maybe (TextEncoder enc_state)
Maybe (TextDecoder dec_state)
IORef (dec_state, Buffer Word8)
IORef (Buffer CharBufElem)
IORef (Buffer Word8)
IORef (BufferList CharBufElem)
Newline
BufferMode
HandleType
haOtherSide :: Handle__ -> Maybe (MVar Handle__)
haOutputNL :: Handle__ -> Newline
haInputNL :: Handle__ -> Newline
haCodec :: Handle__ -> Maybe TextEncoding
haDecoder :: ()
haEncoder :: ()
haBuffers :: Handle__ -> IORef (BufferList CharBufElem)
haCharBuffer :: Handle__ -> IORef (Buffer CharBufElem)
haLastDecode :: ()
haBufferMode :: Handle__ -> BufferMode
haByteBuffer :: Handle__ -> IORef (Buffer Word8)
haType :: Handle__ -> HandleType
haDevice :: ()
haDevice :: dev
haType :: HandleType
haByteBuffer :: IORef (Buffer Word8)
haBufferMode :: BufferMode
haLastDecode :: IORef (dec_state, Buffer Word8)
haCharBuffer :: IORef (Buffer CharBufElem)
haBuffers :: IORef (BufferList CharBufElem)
haEncoder :: Maybe (TextEncoder enc_state)
haDecoder :: Maybe (TextDecoder dec_state)
haCodec :: Maybe TextEncoding
haInputNL :: Newline
haOutputNL :: Newline
haOtherSide :: Maybe (MVar Handle__)
..} = do
let readChunks :: IO [Text]
readChunks = do
buf <- IORef (Buffer CharBufElem) -> IO (Buffer CharBufElem)
forall a. IORef a -> IO a
readIORef IORef (Buffer CharBufElem)
haCharBuffer
(t, eof) <- readChunkEof hh buf
`E.catch` catchError "hGetContents" h hh
if eof
then return [t]
else (t:) `fmap` readChunks
ts <- IO [Text]
readChunks
(hh', _) <- hClose_help hh
return (hh'{haType=ClosedHandle}, T.concat ts)
chooseGoodBuffering :: Handle -> IO ()
chooseGoodBuffering :: Handle -> IO ()
chooseGoodBuffering Handle
h = do
bufMode <- Handle -> IO BufferMode
hGetBuffering Handle
h
case bufMode of
BlockBuffering Maybe Int
Nothing -> do
d <- IO Integer -> (IOException -> IO Integer) -> IO Integer
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
E.catch ((Integer -> Integer -> Integer)
-> IO Integer -> IO Integer -> IO Integer
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (-) (Handle -> IO Integer
hFileSize Handle
h) (Handle -> IO Integer
hTell Handle
h)) ((IOException -> IO Integer) -> IO Integer)
-> (IOException -> IO Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ \(IOException
e::IOException) ->
if IOException -> IOErrorType
ioe_type IOException
e IOErrorType -> IOErrorType -> Bool
forall a. Eq a => a -> a -> Bool
== IOErrorType
InappropriateType
then Integer -> IO Integer
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
16384
else IOException -> IO Integer
forall e a. (HasCallStack, Exception e) => e -> IO a
E.throwIO IOException
e
when (d > 0) . hSetBuffering h . BlockBuffering . Just . fromInteger $ d
BufferMode
_ -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
hGetLine :: Handle -> IO Text
hGetLine :: Handle -> IO Text
hGetLine = ([Text] -> Text) -> Handle -> IO Text
forall t. ([Text] -> t) -> Handle -> IO t
hGetLineWith [Text] -> Text
T.concat
hPutStr :: Handle -> Text -> IO ()
hPutStr :: Handle -> Text -> IO ()
hPutStr Handle
h Text
t = do
(buffer_mode, nl) <-
FilePath
-> Handle
-> (Handle__ -> IO ((BufferMode, Buffer CharBufElem), Newline))
-> IO ((BufferMode, Buffer CharBufElem), Newline)
forall a. FilePath -> Handle -> (Handle__ -> IO a) -> IO a
wantWritableHandle FilePath
"hPutStr" Handle
h ((Handle__ -> IO ((BufferMode, Buffer CharBufElem), Newline))
-> IO ((BufferMode, Buffer CharBufElem), Newline))
-> (Handle__ -> IO ((BufferMode, Buffer CharBufElem), Newline))
-> IO ((BufferMode, Buffer CharBufElem), Newline)
forall a b. (a -> b) -> a -> b
$ \Handle__
h_ -> do
bmode <- Handle__ -> IO (BufferMode, Buffer CharBufElem)
getSpareBuffer Handle__
h_
return (bmode, haOutputNL h_)
let str = Text -> Stream CharBufElem
stream Text
t
case buffer_mode of
(BufferMode
NoBuffering, Buffer CharBufElem
_) -> Handle -> Stream CharBufElem -> IO ()
hPutChars Handle
h Stream CharBufElem
str
(BufferMode
LineBuffering, Buffer CharBufElem
buf) -> Handle
-> Newline -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeLines Handle
h Newline
nl Buffer CharBufElem
buf Stream CharBufElem
str
(BlockBuffering Maybe Int
_, Buffer CharBufElem
buf)
| Newline
nl Newline -> Newline -> Bool
forall a. Eq a => a -> a -> Bool
== Newline
CRLF -> Handle -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeBlocksCRLF Handle
h Buffer CharBufElem
buf Stream CharBufElem
str
| Bool
otherwise -> Handle -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeBlocksRaw Handle
h Buffer CharBufElem
buf Stream CharBufElem
str
hPutChars :: Handle -> Stream Char -> IO ()
hPutChars :: Handle -> Stream CharBufElem -> IO ()
hPutChars Handle
h (Stream s -> Step s CharBufElem
next0 s
s0 Size
_len) = s -> IO ()
loop s
s0
where
loop :: s -> IO ()
loop !s
s = case s -> Step s CharBufElem
next0 s
s of
Step s CharBufElem
Done -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Skip s
s' -> s -> IO ()
loop s
s'
Yield CharBufElem
x s
s' -> Handle -> CharBufElem -> IO ()
hPutChar Handle
h CharBufElem
x IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> s -> IO ()
loop s
s'
writeLines :: Handle -> Newline -> Buffer CharBufElem -> Stream Char -> IO ()
writeLines :: Handle
-> Newline -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeLines Handle
h Newline
nl Buffer CharBufElem
buf0 (Stream s -> Step s CharBufElem
next0 s
s0 Size
_len) = s -> Buffer CharBufElem -> IO ()
outer s
s0 Buffer CharBufElem
buf0
where
outer :: s -> Buffer CharBufElem -> IO ()
outer s
s1 Buffer{bufRaw :: forall e. Buffer e -> RawBuffer e
bufRaw=RawBuffer CharBufElem
raw, bufSize :: forall e. Buffer e -> Int
bufSize=Int
len} = s -> Int -> IO ()
inner s
s1 (Int
0::Int)
where
inner :: s -> Int -> IO ()
inner !s
s !Int
n =
case s -> Step s CharBufElem
next0 s
s of
Step s CharBufElem
Done -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
False Bool
True IO (Buffer CharBufElem) -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Skip s
s' -> s -> Int -> IO ()
inner s
s' Int
n
Yield CharBufElem
x s
s'
| Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
True Bool
False IO (Buffer CharBufElem) -> (Buffer CharBufElem -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Buffer CharBufElem -> IO ()
outer s
s
| CharBufElem
x CharBufElem -> CharBufElem -> Bool
forall a. Eq a => a -> a -> Bool
== CharBufElem
'\n' -> do
n' <- if Newline
nl Newline -> Newline -> Bool
forall a. Eq a => a -> a -> Bool
== Newline
CRLF
then do n1 <- RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
'\r'
writeCharBuf raw n1 '\n'
else RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
x
commit n' True False >>= outer s'
| Bool
otherwise -> RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
x IO Int -> (Int -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Int -> IO ()
inner s
s'
commit :: Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit = Handle
-> RawBuffer CharBufElem
-> Int
-> Int
-> Bool
-> Bool
-> IO (Buffer CharBufElem)
commitBuffer Handle
h RawBuffer CharBufElem
raw Int
len
writeBlocksCRLF :: Handle -> Buffer CharBufElem -> Stream Char -> IO ()
writeBlocksCRLF :: Handle -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeBlocksCRLF Handle
h Buffer CharBufElem
buf0 (Stream s -> Step s CharBufElem
next0 s
s0 Size
_len) = s -> Buffer CharBufElem -> IO ()
outer s
s0 Buffer CharBufElem
buf0
where
outer :: s -> Buffer CharBufElem -> IO ()
outer s
s1 Buffer{bufRaw :: forall e. Buffer e -> RawBuffer e
bufRaw=RawBuffer CharBufElem
raw, bufSize :: forall e. Buffer e -> Int
bufSize=Int
len} = s -> Int -> IO ()
inner s
s1 (Int
0::Int)
where
inner :: s -> Int -> IO ()
inner !s
s !Int
n =
case s -> Step s CharBufElem
next0 s
s of
Step s CharBufElem
Done -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
False Bool
True IO (Buffer CharBufElem) -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Skip s
s' -> s -> Int -> IO ()
inner s
s' Int
n
Yield CharBufElem
x s
s'
| Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
True Bool
False IO (Buffer CharBufElem) -> (Buffer CharBufElem -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Buffer CharBufElem -> IO ()
outer s
s
| CharBufElem
x CharBufElem -> CharBufElem -> Bool
forall a. Eq a => a -> a -> Bool
== CharBufElem
'\n' -> do n1 <- RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
'\r'
writeCharBuf raw n1 '\n' >>= inner s'
| Bool
otherwise -> RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
x IO Int -> (Int -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Int -> IO ()
inner s
s'
commit :: Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit = Handle
-> RawBuffer CharBufElem
-> Int
-> Int
-> Bool
-> Bool
-> IO (Buffer CharBufElem)
commitBuffer Handle
h RawBuffer CharBufElem
raw Int
len
writeBlocksRaw :: Handle -> Buffer CharBufElem -> Stream Char -> IO ()
writeBlocksRaw :: Handle -> Buffer CharBufElem -> Stream CharBufElem -> IO ()
writeBlocksRaw Handle
h Buffer CharBufElem
buf0 (Stream s -> Step s CharBufElem
next0 s
s0 Size
_len) = s -> Buffer CharBufElem -> IO ()
outer s
s0 Buffer CharBufElem
buf0
where
outer :: s -> Buffer CharBufElem -> IO ()
outer s
s1 Buffer{bufRaw :: forall e. Buffer e -> RawBuffer e
bufRaw=RawBuffer CharBufElem
raw, bufSize :: forall e. Buffer e -> Int
bufSize=Int
len} = s -> Int -> IO ()
inner s
s1 (Int
0::Int)
where
inner :: s -> Int -> IO ()
inner !s
s !Int
n =
case s -> Step s CharBufElem
next0 s
s of
Step s CharBufElem
Done -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
False Bool
True IO (Buffer CharBufElem) -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Skip s
s' -> s -> Int -> IO ()
inner s
s' Int
n
Yield CharBufElem
x s
s'
| Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len -> Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit Int
n Bool
True Bool
False IO (Buffer CharBufElem) -> (Buffer CharBufElem -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Buffer CharBufElem -> IO ()
outer s
s
| Bool
otherwise -> RawBuffer CharBufElem -> Int -> CharBufElem -> IO Int
writeCharBuf RawBuffer CharBufElem
raw Int
n CharBufElem
x IO Int -> (Int -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> Int -> IO ()
inner s
s'
commit :: Int -> Bool -> Bool -> IO (Buffer CharBufElem)
commit = Handle
-> RawBuffer CharBufElem
-> Int
-> Int
-> Bool
-> Bool
-> IO (Buffer CharBufElem)
commitBuffer Handle
h RawBuffer CharBufElem
raw Int
len
getSpareBuffer :: Handle__ -> IO (BufferMode, CharBuffer)
getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer CharBufElem)
getSpareBuffer Handle__{haCharBuffer :: Handle__ -> IORef (Buffer CharBufElem)
haCharBuffer=IORef (Buffer CharBufElem)
ref,
haBuffers :: Handle__ -> IORef (BufferList CharBufElem)
haBuffers=IORef (BufferList CharBufElem)
spare_ref,
haBufferMode :: Handle__ -> BufferMode
haBufferMode=BufferMode
mode}
= do
case BufferMode
mode of
BufferMode
NoBuffering -> (BufferMode, Buffer CharBufElem)
-> IO (BufferMode, Buffer CharBufElem)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (BufferMode
mode, FilePath -> Buffer CharBufElem
forall a. HasCallStack => FilePath -> a
error FilePath
"no buffer!")
BufferMode
_ -> do
bufs <- IORef (BufferList CharBufElem) -> IO (BufferList CharBufElem)
forall a. IORef a -> IO a
readIORef IORef (BufferList CharBufElem)
spare_ref
buf <- readIORef ref
case bufs of
BufferListCons RawBuffer CharBufElem
b BufferList CharBufElem
rest -> do
IORef (BufferList CharBufElem) -> BufferList CharBufElem -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (BufferList CharBufElem)
spare_ref BufferList CharBufElem
rest
(BufferMode, Buffer CharBufElem)
-> IO (BufferMode, Buffer CharBufElem)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ( BufferMode
mode, RawBuffer CharBufElem -> Int -> BufferState -> Buffer CharBufElem
forall e. RawBuffer e -> Int -> BufferState -> Buffer e
emptyBuffer RawBuffer CharBufElem
b (Buffer CharBufElem -> Int
forall e. Buffer e -> Int
bufSize Buffer CharBufElem
buf) BufferState
WriteBuffer)
BufferList CharBufElem
BufferListNil -> do
new_buf <- Int -> BufferState -> IO (Buffer CharBufElem)
newCharBuffer (Buffer CharBufElem -> Int
forall e. Buffer e -> Int
bufSize Buffer CharBufElem
buf) BufferState
WriteBuffer
return (mode, new_buf)
commitBuffer :: Handle -> RawCharBuffer -> Int -> Int -> Bool -> Bool
-> IO CharBuffer
commitBuffer :: Handle
-> RawBuffer CharBufElem
-> Int
-> Int
-> Bool
-> Bool
-> IO (Buffer CharBufElem)
commitBuffer Handle
hdl !RawBuffer CharBufElem
raw !Int
sz !Int
count Bool
flush Bool
release =
FilePath
-> Handle
-> (Handle__ -> IO (Buffer CharBufElem))
-> IO (Buffer CharBufElem)
forall a. FilePath -> Handle -> (Handle__ -> IO a) -> IO a
wantWritableHandle FilePath
"commitAndReleaseBuffer" Handle
hdl ((Handle__ -> IO (Buffer CharBufElem)) -> IO (Buffer CharBufElem))
-> (Handle__ -> IO (Buffer CharBufElem)) -> IO (Buffer CharBufElem)
forall a b. (a -> b) -> a -> b
$
RawBuffer CharBufElem
-> Int
-> Int
-> Bool
-> Bool
-> Handle__
-> IO (Buffer CharBufElem)
commitBuffer' RawBuffer CharBufElem
raw Int
sz Int
count Bool
flush Bool
release
{-# INLINE commitBuffer #-}
hPutStrLn :: Handle -> Text -> IO ()
hPutStrLn :: Handle -> Text -> IO ()
hPutStrLn Handle
h Text
t = Handle -> Text -> IO ()
hPutStr Handle
h Text
t IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Handle -> CharBufElem -> IO ()
hPutChar Handle
h CharBufElem
'\n'
interact :: (Text -> Text) -> IO ()
interact :: (Text -> Text) -> IO ()
interact Text -> Text
f = Text -> IO ()
putStr (Text -> IO ()) -> (Text -> Text) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
f (Text -> IO ()) -> IO Text -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO Text
getContents
getContents :: IO Text
getContents :: IO Text
getContents = Handle -> IO Text
hGetContents Handle
stdin
getLine :: IO Text
getLine :: IO Text
getLine = Handle -> IO Text
hGetLine Handle
stdin
putStr :: Text -> IO ()
putStr :: Text -> IO ()
putStr = Handle -> Text -> IO ()
hPutStr Handle
stdout
putStrLn :: Text -> IO ()
putStrLn :: Text -> IO ()
putStrLn = Handle -> Text -> IO ()
hPutStrLn Handle
stdout