2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[IO]{Module @IO@}
8 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
13 IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),
14 BufferMode(NoBuffering,LineBuffering,BlockBuffering),
15 SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),
17 stdin, stdout, stderr,
20 hFileSize, hIsEOF, isEOF,
21 hSetBuffering, hGetBuffering, hFlush,
22 hGetPosn, hSetPosn, hSeek,
23 hReady, hGetChar, hLookAhead, hGetContents,
24 hPutChar, hPutStr, hPutStrLn, hPrint,
25 hIsOpen, hIsClosed, hIsReadable, hIsWritable, hIsSeekable,
27 isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
28 isFullError, isEOFError,
29 isIllegalOperation, isPermissionError, isUserError,
31 ioeGetHandle, ioeGetFileName
37 import ArrBase ( MutableByteArray(..), newCharArray )
38 import IOHandle -- much of the real stuff is in here
39 import PackedString ( nilPS, packCBytesST, unpackPS )
42 import Foreign ( makeForeignObj )
45 %*********************************************************
47 \subsection{Signatures}
49 %*********************************************************
52 --IOHandle:hClose :: Handle -> IO ()
53 --IOHandle:hFileSize :: Handle -> IO Integer
54 --IOHandle:hFlush :: Handle -> IO ()
55 --IOHandle:hGetBuffering :: Handle -> IO BufferMode
56 hGetChar :: Handle -> IO Char
57 hGetContents :: Handle -> IO String
58 --IOHandle:hGetPosn :: Handle -> IO HandlePosn
59 --IOHandle:hIsClosed :: Handle -> IO Bool
60 --IOHandle:hIsEOF :: Handle -> IO Bool
61 --IOHandle:hIsOpen :: Handle -> IO Bool
62 --IOHandle:hIsReadable :: Handle -> IO Bool
63 --IOHandle:hIsSeekable :: Handle -> IO Bool
64 --IOHandle:hIsWritable :: Handle -> IO Bool
65 hLookAhead :: Handle -> IO Char
66 hPrint :: Show a => Handle -> a -> IO ()
67 hPutChar :: Handle -> Char -> IO ()
68 hPutStr :: Handle -> String -> IO ()
69 hPutStrLn :: Handle -> String -> IO ()
70 hReady :: Handle -> IO Bool
71 --IOHandle:hSeek :: Handle -> SeekMode -> Integer -> IO ()
72 --IOHandle:hSetBuffering :: Handle -> BufferMode -> IO ()
73 --IOHandle:hSetPosn :: HandlePosn -> IO ()
74 -- ioeGetFileName :: IOError -> Maybe FilePath
75 -- ioeGetErrorString :: IOError -> Maybe String
76 -- ioeGetHandle :: IOError -> Maybe Handle
77 -- isAlreadyExistsError :: IOError -> Bool
78 -- isAlreadyInUseError :: IOError -> Bool
79 --IOHandle:isEOF :: IO Bool
80 -- isEOFError :: IOError -> Bool
81 -- isFullError :: IOError -> Bool
82 -- isIllegalOperation :: IOError -> Bool
83 -- isPermissionError :: IOError -> Bool
84 -- isUserError :: IOError -> Maybe String
85 --IOHandle:openFile :: FilePath -> IOMode -> IO Handle
86 --IOHandle:stdin, stdout, stderr :: Handle
89 %*********************************************************
91 \subsection{Simple input operations}
93 %*********************************************************
95 Computation $hReady hdl$ indicates whether at least
96 one item is available for input from handle {\em hdl}.
99 --hReady :: Handle -> IO Bool
101 readHandle handle >>= \ htype ->
103 ErrorHandle ioError ->
104 writeHandle handle htype >>
107 writeHandle handle htype >>
108 ioe_closedHandle handle
109 SemiClosedHandle _ _ ->
110 writeHandle handle htype >>
111 ioe_closedHandle handle
112 AppendHandle _ _ _ ->
113 writeHandle handle htype >>
114 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
116 writeHandle handle htype >>
117 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
119 _ccall_ inputReady (filePtr other) `thenIO_Prim` \ rc ->
120 writeHandle handle (markHandle htype) >>
124 _ -> constructErrorAndFail "hReady"
127 Computation $hGetChar hdl$ reads the next character from handle
128 {\em hdl}, blocking until a character is available.
131 --hGetChar :: Handle -> IO Char
134 readHandle handle >>= \ htype ->
136 ErrorHandle ioError ->
137 writeHandle handle htype >>
140 writeHandle handle htype >>
141 ioe_closedHandle handle
142 SemiClosedHandle _ _ ->
143 writeHandle handle htype >>
144 ioe_closedHandle handle
145 AppendHandle _ _ _ ->
146 writeHandle handle htype >>
147 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
149 writeHandle handle htype >>
150 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
152 _ccall_ fileGetc (filePtr other) `thenIO_Prim` \ intc ->
153 writeHandle handle (markHandle htype) >>
154 if intc /= ``EOF'' then
157 constructErrorAndFail "hGetChar"
160 Computation $hLookahead hdl$ returns the next character from handle
161 {\em hdl} without removing it from the input buffer, blocking until a
162 character is available.
165 --hLookAhead :: Handle -> IO Char
168 readHandle handle >>= \ htype ->
170 ErrorHandle ioError ->
171 writeHandle handle htype >>
174 writeHandle handle htype >>
175 ioe_closedHandle handle
176 SemiClosedHandle _ _ ->
177 writeHandle handle htype >>
178 ioe_closedHandle handle
179 AppendHandle _ _ _ ->
180 writeHandle handle htype >>
181 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
183 writeHandle handle htype >>
184 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
186 _ccall_ fileLookAhead (filePtr other) `thenIO_Prim` \ intc ->
187 writeHandle handle (markHandle htype) >>
188 if intc /= ``EOF'' then
191 constructErrorAndFail "hLookAhead"
195 %*********************************************************
197 \subsection{Getting the entire contents of a handle}
199 %*********************************************************
201 Computation $hGetContents hdl$ returns the list of characters
202 corresponding to the unread portion of the channel or file managed by
203 {\em hdl}, which is made semi-closed.
206 --hGetContents :: Handle -> IO String
208 hGetContents handle =
209 readHandle handle >>= \ htype ->
211 ErrorHandle ioError ->
212 writeHandle handle htype >>
215 writeHandle handle htype >>
216 ioe_closedHandle handle
217 SemiClosedHandle _ _ ->
218 writeHandle handle htype >>
219 ioe_closedHandle handle
220 AppendHandle _ _ _ ->
221 writeHandle handle htype >>
222 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
224 writeHandle handle htype >>
225 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
228 To avoid introducing an extra layer of buffering here,
229 we provide three lazy read methods, based on character,
230 line, and block buffering.
232 stToIO (getBufferMode other) >>= \ other ->
233 case (bufferMode other) of
234 Just LineBuffering ->
235 allocBuf Nothing >>= \ buf_info ->
236 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
238 unsafeInterleavePrimIO (lazyReadLine handle)
239 `thenIO_Prim` \ contents ->
242 Just (BlockBuffering size) ->
243 allocBuf size >>= \ buf_info ->
244 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
246 unsafeInterleavePrimIO (lazyReadBlock handle)
247 `thenIO_Prim` \ contents ->
249 _ -> -- Nothing is treated pessimistically as NoBuffering
250 writeHandle handle (SemiClosedHandle (filePtr other) (``NULL'', 0))
252 unsafeInterleavePrimIO (lazyReadChar handle)
253 `thenIO_Prim` \ contents ->
256 allocBuf :: Maybe Int -> IO (Addr, Int)
258 _ccall_ malloc size `thenIO_Prim` \ buf ->
259 if buf /= ``NULL'' then
262 fail (IOError Nothing ResourceExhausted "not enough virtual memory")
267 Nothing -> ``BUFSIZ''
270 Note that someone may yank our handle out from under us, and then re-use
271 the same FILE * for something else. Therefore, we have to re-examine the
272 handle every time through.
275 lazyReadBlock :: Handle -> PrimIO String
276 lazyReadLine :: Handle -> PrimIO String
277 lazyReadChar :: Handle -> PrimIO String
279 lazyReadBlock handle =
280 ioToST (readHandle handle) >>= \ htype ->
282 -- There cannae be an ErrorHandle here
284 ioToST (writeHandle handle htype) >>
286 SemiClosedHandle fp (buf, size) ->
287 _ccall_ readBlock buf fp size >>= \ bytes ->
290 else packCBytesST bytes buf) >>= \ some ->
292 makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
293 ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0)))
295 _ccall_ free buf >>= \ () ->
296 _ccall_ closeFile fp >>
297 returnPrimIO (unpackPS some)
299 ioToST (writeHandle handle htype) >>
300 unsafeInterleavePrimIO (lazyReadBlock handle)
302 returnPrimIO (unpackPS some ++ more)
304 lazyReadLine handle =
305 ioToST (readHandle handle) >>= \ htype ->
307 -- There cannae be an ErrorHandle here
309 ioToST (writeHandle handle htype) >>
311 SemiClosedHandle fp (buf, size) ->
312 _ccall_ readLine buf fp size >>= \ bytes ->
315 else packCBytesST bytes buf) >>= \ some ->
317 makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
318 ioToST (writeHandle handle (SemiClosedHandle null_fp (``NULL'', 0)))
320 _ccall_ free buf >>= \ () ->
321 _ccall_ closeFile fp >>
322 returnPrimIO (unpackPS some)
324 ioToST (writeHandle handle htype) >>
325 unsafeInterleavePrimIO (lazyReadLine handle)
327 returnPrimIO (unpackPS some ++ more)
329 lazyReadChar handle =
330 ioToST (readHandle handle) >>= \ htype ->
332 -- There cannae be an ErrorHandle here
334 ioToST (writeHandle handle htype) >>
336 SemiClosedHandle fp buf_info ->
337 _ccall_ readChar fp >>= \ char ->
338 if char == ``EOF'' then
339 makeForeignObj ``NULL'' ``&freeFile'' >>= \ null_fp ->
340 ioToST (writeHandle handle (SemiClosedHandle null_fp buf_info))
342 _ccall_ closeFile fp >>
345 ioToST (writeHandle handle htype) >>
346 unsafeInterleavePrimIO (lazyReadChar handle)
348 returnPrimIO (chr char : more)
352 %*********************************************************
354 \subsection{Simple output functions}
356 %*********************************************************
358 Computation $hPutChar hdl c$ writes the character {\em c} to the file
359 or channel managed by {\em hdl}. Characters may be buffered if
360 buffering is enabled for {\em hdl}.
363 --hPutChar :: Handle -> Char -> IO ()
366 readHandle handle >>= \ htype ->
368 ErrorHandle ioError ->
369 writeHandle handle htype >>
372 writeHandle handle htype >>
373 ioe_closedHandle handle
374 SemiClosedHandle _ _ ->
375 writeHandle handle htype >>
376 ioe_closedHandle handle
378 writeHandle handle htype >>
379 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
381 _ccall_ filePutc (filePtr other) (ord c) `thenIO_Prim` \ rc ->
382 writeHandle handle (markHandle htype) >>
386 constructErrorAndFail "hPutChar"
389 Computation $hPutStr hdl s$ writes the string {\em s} to the file or
390 channel managed by {\em hdl}.
393 --hPutStr :: Handle -> String -> IO ()
396 readHandle handle >>= \ htype ->
398 ErrorHandle ioError ->
399 writeHandle handle htype >>
402 writeHandle handle htype >>
403 ioe_closedHandle handle
404 SemiClosedHandle _ _ ->
405 writeHandle handle htype >>
406 ioe_closedHandle handle
408 writeHandle handle htype >>
409 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
411 getBufferMode other `thenIO_Prim` \ other ->
412 (case bufferMode other of
413 Just LineBuffering ->
414 writeLines (filePtr other) str
415 Just (BlockBuffering (Just size)) ->
416 writeBlocks (filePtr other) size str
417 Just (BlockBuffering Nothing) ->
418 writeBlocks (filePtr other) ``BUFSIZ'' str
419 _ -> -- Nothing is treated pessimistically as NoBuffering
420 writeChars (filePtr other) str
421 ) `thenIO_Prim` \ success ->
422 writeHandle handle (markHandle other) >>
426 constructErrorAndFail "hPutStr"
428 writeLines :: ForeignObj -> String -> PrimIO Bool
429 writeLines = writeChunks ``BUFSIZ'' True
431 writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool
432 writeBlocks fp size s = writeChunks size False fp s
435 The breaking up of output into lines along \n boundaries
436 works fine as long as there are newlines to split by.
437 Avoid the splitting up into lines alltogether (doesn't work
438 for overly long lines like the stuff that showsPrec instances
439 normally return). Instead, we split them up into fixed size
440 chunks before blasting them off to the Real World.
442 Hacked to avoid multiple passes over the strings - unsightly, but
443 a whole lot quicker. -- SOF 3/96
446 writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool
448 writeChunks (I# bufLen) chopOnNewLine fp s =
449 newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) ->
451 write_char :: MutableByteArray# RealWorld -> Int# -> Char# -> PrimIO ()
452 write_char arr# n x = ST $ \ (S# s#) ->
453 case (writeCharArray# arr# n x s#) of { s1# ->
456 shoveString :: Int# -> [Char] -> PrimIO Bool
463 _ccall_ writeFile arr fp (I# n) >>= \rc ->
467 write_char arr# n x >>
469 {- Flushing lines - should we bother? -}
470 if n ==# bufLen {- || (chopOnNewLine && (x `eqChar#` '\n'#)) -} then
471 _ccall_ writeFile arr fp (I# (n +# 1#)) >>= \ rc ->
477 shoveString (n +# 1#) xs
481 writeChars :: ForeignObj -> String -> PrimIO Bool
482 writeChars fp "" = returnPrimIO True
483 writeChars fp (c:cs) =
484 _ccall_ filePutc fp (ord c) >>= \ rc ->
491 Computation $hPrint hdl t$ writes the string representation of {\em t}
492 given by the $shows$ function to the file or channel managed by {\em
495 SOF 2/97: Seem to have disappeared in 1.4 libs.
498 --hPrint :: Show a => Handle -> a -> IO ()
499 hPrint hdl = hPutStr hdl . show
502 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
503 the handle \tr{hdl}, adding a newline at the end.
506 --hPutStrLn :: Handle -> String -> IO ()
507 hPutStrLn hndl str = do