Skip to content

Commit 1ffe752

Browse files
Mistukehvr
authored andcommitted
text: Fix termination condition for file reads.
1 parent 9fac5db commit 1ffe752

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

Data/Text/IO.hs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,23 @@ writeFile p = withFile p WriteMode . flip hPutStr
9595
appendFile :: FilePath -> Text -> IO ()
9696
appendFile p = withFile p AppendMode . flip hPutStr
9797

98-
catchError :: String -> Handle -> Handle__ -> IOError -> IO Text
98+
catchError :: String -> Handle -> Handle__ -> IOError -> IO (Text, Bool)
9999
catchError caller h Handle__{..} err
100100
| isEOFError err = do
101101
buf <- readIORef haCharBuffer
102102
return $ if isEmptyBuffer buf
103-
then T.empty
104-
else T.singleton '\r'
103+
then (T.empty, True)
104+
else (T.singleton '\r', True)
105105
| otherwise = E.throwIO (augmentIOError err caller h)
106106

107+
-- | Wrap readChunk and return a value indicating if we're reached the EOF.
108+
-- This is needed because unpack_nl is unable to discern the difference
109+
-- between a buffer with just \r due to EOF or because not enough data was left
110+
-- for decoding. e.g. the final character decoded from the byte buffer was \r.
111+
readChunkEof :: Handle__ -> CharBuffer -> IO (Text, Bool)
112+
readChunkEof hh buf = do t <- readChunk hh buf
113+
return (t, False)
114+
107115
-- | /Experimental./ Read a single chunk of strict text from a
108116
-- 'Handle'. The size of the chunk depends on the amount of input
109117
-- currently buffered.
@@ -116,7 +124,7 @@ hGetChunk h = wantReadableHandle "hGetChunk" h readSingleChunk
116124
where
117125
readSingleChunk hh@Handle__{..} = do
118126
buf <- readIORef haCharBuffer
119-
t <- readChunk hh buf `E.catch` catchError "hGetChunk" h hh
127+
(t, _) <- readChunkEof hh buf `E.catch` catchError "hGetChunk" h hh
120128
return (hh, t)
121129

122130
-- | Read the remaining contents of a 'Handle' as a string. The
@@ -138,8 +146,9 @@ hGetContents h = do
138146
readAll hh@Handle__{..} = do
139147
let readChunks = do
140148
buf <- readIORef haCharBuffer
141-
t <- readChunk hh buf `E.catch` catchError "hGetContents" h hh
142-
if T.null t
149+
(t, eof) <- readChunkEof hh buf
150+
`E.catch` catchError "hGetContents" h hh
151+
if eof
143152
then return [t]
144153
else (t:) `fmap` readChunks
145154
ts <- readChunks

0 commit comments

Comments
 (0)