@@ -26,6 +26,7 @@ module Data.Text.IO
2626 , appendFile
2727 -- * Operations on handles
2828 , hGetContents
29+ , hGetChunk
2930 , hGetLine
3031 , hPutStr
3132 , hPutStrLn
@@ -97,6 +98,30 @@ writeFile p = withFile p WriteMode . flip hPutStr
9798appendFile :: FilePath -> Text -> IO ()
9899appendFile p = withFile p AppendMode . flip hPutStr
99100
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
106+ then T.empty
107+ else T.singleton '\r'
108+ | otherwise = E.throwIO (augmentIOError err caller h)
109+
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.
113+--
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
119+ where
120+ readSingleChunk hh@Handle__{..} = do
121+ buf <- readIORef haCharBuffer
122+ t <- readChunk hh buf `E.catch` catchError "hGetChunk" h hh
123+ return (hh, t)
124+
100125-- | Read the remaining contents of a 'Handle' as a string. The
101126-- 'Handle' is closed once the contents have been read, or if an
102127-- exception is thrown.
@@ -117,16 +142,9 @@ hGetContents h = do
117142 wantReadableHandle "hGetContents" h readAll
118143 where
119144 readAll hh@Handle__{..} = do
120− let catchError e
121− | isEOFError e = do
122− buf <- readIORef haCharBuffer
123− return $ if isEmptyBuffer buf
124− then T.empty
125− else T.singleton '\r'
126− | otherwise = E.throwIO (augmentIOError e "hGetContents" h)
127− readChunks = do
145+ let readChunks = do
128146 buf <- readIORef haCharBuffer
129− t <- readChunk hh buf `E.catch` catchError
147+ t <- readChunk hh buf `E.catch` catchError "hGetContents" h hh
130148 if T.null t
131149 then return [t]
132150 else (t:) `fmap` readChunks