2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
4 \section[PrelReadTextIO]{Haskell 1.3 Text Input}
6 This module defines the standard set of input operations for reading
7 characters and strings from text files, using {\em handles}.
10 module PreludeReadTextIO (
31 import PreludeMonadicIO
37 ---------------------------------
40 my_then :: IO a -> (a -> PrimIO b) -> PrimIO b
41 {-# INLINE my_then #-}
43 my_then m k = m `thenPrimIO` \ r -> k' r
46 k' (Left err) = error "my_then"
47 ---------------------------------
50 hReady :: Handle -> IO Bool
52 takeMVar handle >>= \ htype ->
54 _ErrorHandle ioError ->
55 putMVar handle htype >>
58 putMVar handle htype >>
59 failWith (IllegalOperation "handle is closed")
60 _SemiClosedHandle _ _ ->
61 putMVar handle htype >>
62 failWith (IllegalOperation "handle is closed")
63 _AppendHandle _ _ _ ->
64 putMVar handle htype >>
65 failWith (IllegalOperation "handle is not open for reading")
67 putMVar handle htype >>
68 failWith (IllegalOperation "handle is not open for reading")
70 _ccall_ inputReady (_filePtr other) `thenPrimIO` \ rc ->
71 putMVar handle (_markHandle htype) >>
75 _ -> _constructError `thenPrimIO` \ ioError ->
80 Computation $hReady hdl$ indicates whether at least
81 one item is available for input from handle {\em hdl}.
85 hGetChar :: Handle -> IO Char
87 takeMVar handle >>= \ htype ->
89 _ErrorHandle ioError ->
90 putMVar handle htype >>
93 putMVar handle htype >>
94 failWith (IllegalOperation "handle is closed")
95 _SemiClosedHandle _ _ ->
96 putMVar handle htype >>
97 failWith (IllegalOperation "handle is closed")
98 _AppendHandle _ _ _ ->
99 putMVar handle htype >>
100 failWith (IllegalOperation "handle is not open for reading")
101 _WriteHandle _ _ _ ->
102 putMVar handle htype >>
103 failWith (IllegalOperation "handle is not open for reading")
105 _ccall_ fileGetc (_filePtr other) `thenPrimIO` \ intc ->
106 putMVar handle (_markHandle htype) >>
107 if intc /= ``EOF'' then
110 _constructError `thenPrimIO` \ ioError ->
114 getChar = hGetChar stdin13
118 Computation $hGetChar hdl$ reads the next character from handle {\em
119 hdl}, blocking until a character is available.
121 $getChar$ reads the next character from $stdin$.
125 hLookAhead :: Handle -> IO Char
127 takeMVar handle >>= \ htype ->
129 _ErrorHandle ioError ->
130 putMVar handle htype >>
133 putMVar handle htype >>
134 failWith (IllegalOperation "handle is closed")
135 _SemiClosedHandle _ _ ->
136 putMVar handle htype >>
137 failWith (IllegalOperation "handle is closed")
138 _AppendHandle _ _ _ ->
139 putMVar handle htype >>
140 failWith (IllegalOperation "handle is not open for reading")
141 _WriteHandle _ _ _ ->
142 putMVar handle htype >>
143 failWith (IllegalOperation "handle is not open for reading")
145 _ccall_ fileLookAhead (_filePtr other) `thenPrimIO` \ intc ->
146 putMVar handle (_markHandle htype) >>
147 if intc /= ``EOF'' then
150 _constructError `thenPrimIO` \ ioError ->
155 Computation $hLookahead hdl$ returns the next character from handle
156 {\em hdl} without removing it from the input buffer, blocking until a
157 character is available.
161 hGetContents :: Handle -> IO String
162 hGetContents handle =
163 takeMVar handle >>= \ htype ->
165 _ErrorHandle ioError ->
166 putMVar handle htype >>
169 putMVar handle htype >>
170 failWith (IllegalOperation "handle is closed")
171 _SemiClosedHandle _ _ ->
172 putMVar handle htype >>
173 failWith (IllegalOperation "handle is closed")
174 _AppendHandle _ _ _ ->
175 putMVar handle htype >>
176 failWith (IllegalOperation "handle is not open for reading")
177 _WriteHandle _ _ _ ->
178 putMVar handle htype >>
179 failWith (IllegalOperation "handle is not open for reading")
183 To avoid introducing an extra layer of buffering here,
184 we provide three lazy read methods, based on character,
185 line, and block buffering.
188 _getBufferMode other `thenPrimIO` \ other ->
189 case _bufferMode other of
190 Just LineBuffering ->
191 allocBuf Nothing >>= \ buf_info ->
192 putMVar handle (_SemiClosedHandle (_filePtr other) buf_info)
194 unsafeInterleavePrimIO (lazyReadLine handle)
195 `thenPrimIO` \ contents ->
198 Just (BlockBuffering size) ->
199 allocBuf size >>= \ buf_info ->
200 putMVar handle (_SemiClosedHandle (_filePtr other) buf_info)
202 unsafeInterleavePrimIO (lazyReadBlock handle)
203 `thenPrimIO` \ contents ->
205 _ -> -- Nothing is treated pessimistically as NoBuffering
206 putMVar handle (_SemiClosedHandle (_filePtr other) (``NULL'', 0))
208 unsafeInterleavePrimIO (lazyReadChar handle)
209 `thenPrimIO` \ contents ->
212 allocBuf :: (Maybe Int) -> IO (_Addr, Int)
214 _ccall_ malloc size `thenPrimIO` \ buf ->
215 if buf /= ``NULL'' then
218 failWith (ResourceExhausted "not enough virtual memory")
223 Nothing -> ``BUFSIZ''
226 Note that someone may yank our handle out from under us, and then re-use
227 the same FILE * for something else. Therefore, we have to re-examine the
228 handle every time through.
231 lazyReadBlock :: Handle -> PrimIO String
232 lazyReadBlock handle =
233 takeMVar handle `my_then` \ htype ->
235 -- There cannae be an _ErrorHandle here
237 putMVar handle htype `seqPrimIO`
239 _SemiClosedHandle fp (buf, size) ->
240 _ccall_ readBlock buf fp size `thenPrimIO` \ bytes ->
241 (if bytes <= 0 then returnStrictlyST _nilPS
242 else _packCBytesST bytes buf) `thenStrictlyST` \ some ->
244 putMVar handle (_SemiClosedHandle ``NULL'' (``NULL'', 0))
246 _ccall_ free buf `thenPrimIO` \ () ->
247 _ccall_ closeFile fp `seqPrimIO`
248 returnPrimIO (_unpackPS some)
250 putMVar handle htype `seqPrimIO`
251 unsafeInterleavePrimIO (lazyReadBlock handle)
252 `thenPrimIO` \ more ->
253 returnPrimIO (_unpackPS some ++ more)
255 lazyReadLine :: Handle -> PrimIO String
256 lazyReadLine handle =
257 takeMVar handle `my_then` \ htype ->
259 -- There cannae be an _ErrorHandle here
261 putMVar handle htype `seqPrimIO`
263 _SemiClosedHandle fp (buf, size) ->
264 _ccall_ readLine buf fp size `thenPrimIO` \ bytes ->
265 (if bytes <= 0 then returnStrictlyST _nilPS
266 else _packCBytesST bytes buf) `thenStrictlyST` \ some ->
268 putMVar handle (_SemiClosedHandle ``NULL'' (``NULL'', 0))
270 _ccall_ free buf `thenPrimIO` \ () ->
271 _ccall_ closeFile fp `seqPrimIO`
272 returnPrimIO (_unpackPS some)
274 putMVar handle htype `seqPrimIO`
275 unsafeInterleavePrimIO (lazyReadLine handle)
276 `thenPrimIO` \ more ->
277 returnPrimIO (_unpackPS some ++ more)
279 lazyReadChar :: Handle -> PrimIO String
280 lazyReadChar handle =
281 takeMVar handle `my_then` \ htype ->
283 -- There cannae be an _ErrorHandle here
285 putMVar handle htype `seqPrimIO`
287 _SemiClosedHandle fp buf_info ->
288 _ccall_ readChar fp `thenPrimIO` \ char ->
289 if char == ``EOF'' then
290 putMVar handle (_SemiClosedHandle ``NULL'' buf_info)
292 _ccall_ closeFile fp `seqPrimIO`
295 putMVar handle htype `seqPrimIO`
296 unsafeInterleavePrimIO (lazyReadChar handle)
297 `thenPrimIO` \ more ->
298 returnPrimIO (chr char : more)
302 Computation $hGetContents hdl$ returns the list of characters
303 corresponding to the unread portion of the channel or file managed by
304 {\em hdl}, which is made semi-closed.
308 readFile13 :: FilePath -> IO String
309 readFile13 name = openFile name ReadMode >>= hGetContents
313 $readFile file$ returns the contents of {\em file} as a lazy string.