@@ -26,6 +26,7 @@ module Data.Text.IO
26 , appendFile
26 , appendFile
27 -- * Operations on handles
27 -- * Operations on handles
28 , hGetContents
28 , hGetContents
29 , hGetLine
30 , hGetLine
31 , hPutStrLn
32 , hPutStrLn
@@ -97,6 +98,30 @@ writeFile p = withFile p WriteMode . flip hPutStr
97appendFile :: FilePath -> Text -> IO ()
98appendFile :: FilePath -> Text -> IO ()
98appendFile p = withFile p AppendMode . flip hPutStr
99appendFile p = withFile p AppendMode . flip hPutStr
101+catchError :: String -> Handle -> Handle__ -> IOError -> IO Text
102+catchError caller h Handle__{..} err
103+ | isEOFError err = do
104+ buf <- readIORef haCharBuffer
105+ return $ if isEmptyBuffer buf
107+ else T.singleton '\r'
108+ | otherwise = E.throwIO (augmentIOError err caller h)
110+-- | /Experimental./ Read a single chunk of strict text from a
111+-- 'Handle'. The size of the chunk depends on the amount of input
112+-- currently buffered.
114+-- This function blocks only if there is no data available, and EOF
115+-- has not yet been reached. Once EOF is reached, this function
116+-- returns an empty string instead of throwing an exception.
117+hGetChunk :: Handle -> IO Text
118+hGetChunk h = wantReadableHandle "hGetChunk" h readSingleChunk
120+ readSingleChunk hh@Handle__{..} = do
121+ buf <- readIORef haCharBuffer
122+ t <- readChunk hh buf `E.catch` catchError "hGetChunk" h hh
100-- | Read the remaining contents of a 'Handle' as a string. The
125-- | Read the remaining contents of a 'Handle' as a string. The
101-- 'Handle' is closed once the contents have been read, or if an
126-- 'Handle' is closed once the contents have been read, or if an
102-- exception is thrown.
127-- exception is thrown.
@@ -117,16 +142,9 @@ hGetContents h = do
117 wantReadableHandle "hGetContents" h readAll
142 wantReadableHandle "hGetContents" h readAll
119 readAll hh@Handle__{..} = do
144 readAll hh@Handle__{..} = do
122− buf <- readIORef haCharBuffer
123− return $ if isEmptyBuffer buf
125− else T.singleton '\r'
126− | otherwise = E.throwIO (augmentIOError e "hGetContents" h)
127− readChunks = do
145+ let readChunks = do
128 buf <- readIORef haCharBuffer
146 buf <- readIORef haCharBuffer
129− t <- readChunk hh buf `E.catch` catchError
147+ t <- readChunk hh buf `E.catch` catchError "hGetContents" h hh
130 if T.null t
148 if T.null t
131 then return [t]
149 then return [t]
132 else (t:) `fmap` readChunks
150 else (t:) `fmap` readChunks