1 {-# OPTIONS_GHC -XNoImplicitPrelude -#include "HsBase.h" #-}
2 {-# OPTIONS_GHC -fno-warn-unused-matches #-}
3 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
4 {-# OPTIONS_GHC -XRecordWildCards #-}
5 {-# OPTIONS_HADDOCK hide #-}
7 -----------------------------------------------------------------------------
9 -- Module : GHC.IO.Handle.Internals
10 -- Copyright : (c) The University of Glasgow, 1994-2001
11 -- License : see libraries/base/LICENSE
13 -- Maintainer : libraries@haskell.org
14 -- Stability : internal
15 -- Portability : non-portable
17 -- This module defines the basic operations on I\/O \"handles\". All
18 -- of the operations defined here are independent of the underlying
21 -----------------------------------------------------------------------------
24 module GHC.IO.Handle.Internals (
25 withHandle, withHandle', withHandle_,
26 withHandle__', withHandle_', withAllHandles__,
27 wantWritableHandle, wantReadableHandle, wantReadableHandle_,
30 mkHandle, mkFileHandle, mkDuplexHandle,
31 openTextEncoding, initBufferState,
32 dEFAULT_CHAR_BUFFER_SIZE,
34 flushBuffer, flushWriteBuffer, flushWriteBuffer_, flushCharReadBuffer,
35 flushCharBuffer, flushByteReadBuffer,
37 readTextDevice, writeTextDevice, readTextDeviceNonBlocking,
40 ioe_closedHandle, ioe_EOF, ioe_notReadable, ioe_notWritable,
41 ioe_finalizedHandle, ioe_bufsiz,
43 hClose_help, hLookAhead_,
45 HandleFinalizer, handleFinalizer,
52 import GHC.IO.Encoding
53 import GHC.IO.Handle.Types
55 import GHC.IO.BufferedIO (BufferedIO)
56 import GHC.IO.Exception
57 import GHC.IO.Device (IODevice, SeekMode(..))
58 import qualified GHC.IO.Device as IODevice
59 import qualified GHC.IO.BufferedIO as Buffered
64 import GHC.Num ( Num(..) )
72 -- import System.IO.Error
73 import System.Posix.Internals hiding (FD)
80 -- ---------------------------------------------------------------------------
81 -- Creating a new handle
83 type HandleFinalizer = FilePath -> MVar Handle__ -> IO ()
85 newFileHandle :: FilePath -> Maybe HandleFinalizer -> Handle__ -> IO Handle
86 newFileHandle filepath mb_finalizer hc = do
89 Just finalizer -> addMVarFinalizer m (finalizer filepath m)
91 return (FileHandle filepath m)
93 -- ---------------------------------------------------------------------------
94 -- Working with Handles
97 In the concurrent world, handles are locked during use. This is done
98 by wrapping an MVar around the handle which acts as a mutex over
99 operations on the handle.
101 To avoid races, we use the following bracketing operations. The idea
102 is to obtain the lock, do some operation and replace the lock again,
103 whether the operation succeeded or failed. We also want to handle the
104 case where the thread receives an exception while processing the IO
105 operation: in these cases we also want to relinquish the lock.
107 There are three versions of @withHandle@: corresponding to the three
108 possible combinations of:
110 - the operation may side-effect the handle
111 - the operation may return a result
113 If the operation generates an error or an exception is raised, the
114 original handle is always replaced.
117 {-# INLINE withHandle #-}
118 withHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
119 withHandle fun h@(FileHandle _ m) act = withHandle' fun h m act
120 withHandle fun h@(DuplexHandle _ m _) act = withHandle' fun h m act
122 withHandle' :: String -> Handle -> MVar Handle__
123 -> (Handle__ -> IO (Handle__,a)) -> IO a
124 withHandle' fun h m act =
127 checkHandleInvariants h_
128 (h',v) <- (act h_ `catchAny` \err -> putMVar m h_ >> throw err)
129 `catchException` \ex -> ioError (augmentIOError ex fun h)
130 checkHandleInvariants h'
134 {-# INLINE withHandle_ #-}
135 withHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
136 withHandle_ fun h@(FileHandle _ m) act = withHandle_' fun h m act
137 withHandle_ fun h@(DuplexHandle _ m _) act = withHandle_' fun h m act
139 withHandle_' :: String -> Handle -> MVar Handle__ -> (Handle__ -> IO a) -> IO a
140 withHandle_' fun h m act =
143 checkHandleInvariants h_
144 v <- (act h_ `catchAny` \err -> putMVar m h_ >> throw err)
145 `catchException` \ex -> ioError (augmentIOError ex fun h)
146 checkHandleInvariants h_
150 withAllHandles__ :: String -> Handle -> (Handle__ -> IO Handle__) -> IO ()
151 withAllHandles__ fun h@(FileHandle _ m) act = withHandle__' fun h m act
152 withAllHandles__ fun h@(DuplexHandle _ r w) act = do
153 withHandle__' fun h r act
154 withHandle__' fun h w act
156 withHandle__' :: String -> Handle -> MVar Handle__ -> (Handle__ -> IO Handle__)
158 withHandle__' fun h m act =
161 checkHandleInvariants h_
162 h' <- (act h_ `catchAny` \err -> putMVar m h_ >> throw err)
163 `catchException` \ex -> ioError (augmentIOError ex fun h)
164 checkHandleInvariants h'
168 augmentIOError :: IOException -> String -> Handle -> IOException
169 augmentIOError ioe@IOError{ ioe_filename = fp } fun h
170 = ioe { ioe_handle = Just h, ioe_location = fun, ioe_filename = filepath }
173 | otherwise = case h of
174 FileHandle path _ -> Just path
175 DuplexHandle path _ _ -> Just path
177 -- ---------------------------------------------------------------------------
178 -- Wrapper for write operations.
180 wantWritableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
181 wantWritableHandle fun h@(FileHandle _ m) act
182 = wantWritableHandle' fun h m act
183 wantWritableHandle fun h@(DuplexHandle _ _ m) act
184 = withHandle_' fun h m act
187 :: String -> Handle -> MVar Handle__
188 -> (Handle__ -> IO a) -> IO a
189 wantWritableHandle' fun h m act
190 = withHandle_' fun h m (checkWritableHandle act)
192 checkWritableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a
193 checkWritableHandle act h_@Handle__{..}
195 ClosedHandle -> ioe_closedHandle
196 SemiClosedHandle -> ioe_closedHandle
197 ReadHandle -> ioe_notWritable
198 ReadWriteHandle -> do
199 buf <- readIORef haCharBuffer
200 when (not (isWriteBuffer buf)) $ do
201 flushCharReadBuffer h_
202 flushByteReadBuffer h_
203 buf <- readIORef haCharBuffer
204 writeIORef haCharBuffer buf{ bufState = WriteBuffer }
205 buf <- readIORef haByteBuffer
206 buf' <- Buffered.emptyWriteBuffer haDevice buf
207 writeIORef haByteBuffer buf'
211 -- ---------------------------------------------------------------------------
212 -- Wrapper for read operations.
214 wantReadableHandle :: String -> Handle -> (Handle__ -> IO (Handle__,a)) -> IO a
215 wantReadableHandle fun h act = withHandle fun h (checkReadableHandle act)
217 wantReadableHandle_ :: String -> Handle -> (Handle__ -> IO a) -> IO a
218 wantReadableHandle_ fun h@(FileHandle _ m) act
219 = wantReadableHandle' fun h m act
220 wantReadableHandle_ fun h@(DuplexHandle _ m _) act
221 = withHandle_' fun h m act
224 :: String -> Handle -> MVar Handle__
225 -> (Handle__ -> IO a) -> IO a
226 wantReadableHandle' fun h m act
227 = withHandle_' fun h m (checkReadableHandle act)
229 checkReadableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a
230 checkReadableHandle act h_@Handle__{..} =
232 ClosedHandle -> ioe_closedHandle
233 SemiClosedHandle -> ioe_closedHandle
234 AppendHandle -> ioe_notReadable
235 WriteHandle -> ioe_notReadable
236 ReadWriteHandle -> do
237 -- a read/write handle and we want to read from it. We must
238 -- flush all buffered write data first.
239 cbuf <- readIORef haCharBuffer
240 when (isWriteBuffer cbuf) $ do
241 cbuf' <- flushWriteBuffer_ h_ cbuf
242 writeIORef haCharBuffer cbuf'{ bufState = ReadBuffer }
243 bbuf <- readIORef haByteBuffer
244 writeIORef haByteBuffer bbuf{ bufState = ReadBuffer }
248 -- ---------------------------------------------------------------------------
249 -- Wrapper for seek operations.
251 wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a
252 wantSeekableHandle fun h@(DuplexHandle _ _ _) _act =
253 ioException (IOError (Just h) IllegalOperation fun
254 "handle is not seekable" Nothing Nothing)
255 wantSeekableHandle fun h@(FileHandle _ m) act =
256 withHandle_' fun h m (checkSeekableHandle act)
258 checkSeekableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a
259 checkSeekableHandle act handle_@Handle__{haDevice=dev} =
260 case haType handle_ of
261 ClosedHandle -> ioe_closedHandle
262 SemiClosedHandle -> ioe_closedHandle
263 AppendHandle -> ioe_notSeekable
264 _ -> do b <- IODevice.isSeekable dev
265 if b then act handle_
268 -- -----------------------------------------------------------------------------
271 ioe_closedHandle, ioe_EOF,
272 ioe_notReadable, ioe_notWritable, ioe_cannotFlushNotSeekable,
273 ioe_notSeekable, ioe_invalidCharacter :: IO a
275 ioe_closedHandle = ioException
276 (IOError Nothing IllegalOperation ""
277 "handle is closed" Nothing Nothing)
278 ioe_EOF = ioException
279 (IOError Nothing EOF "" "" Nothing Nothing)
280 ioe_notReadable = ioException
281 (IOError Nothing IllegalOperation ""
282 "handle is not open for reading" Nothing Nothing)
283 ioe_notWritable = ioException
284 (IOError Nothing IllegalOperation ""
285 "handle is not open for writing" Nothing Nothing)
286 ioe_notSeekable = ioException
287 (IOError Nothing IllegalOperation ""
288 "handle is not seekable" Nothing Nothing)
289 ioe_cannotFlushNotSeekable = ioException
290 (IOError Nothing IllegalOperation ""
291 "cannot flush the read buffer: underlying device is not seekable"
293 ioe_invalidCharacter = ioException
294 (IOError Nothing InvalidArgument ""
295 ("invalid byte sequence for this encoding") Nothing Nothing)
297 ioe_finalizedHandle :: FilePath -> Handle__
298 ioe_finalizedHandle fp = throw
299 (IOError Nothing IllegalOperation ""
300 "handle is finalized" Nothing (Just fp))
302 ioe_bufsiz :: Int -> IO a
303 ioe_bufsiz n = ioException
304 (IOError Nothing InvalidArgument "hSetBuffering"
305 ("illegal buffer size " ++ showsPrec 9 n []) Nothing Nothing)
306 -- 9 => should be parens'ified.
308 -- -----------------------------------------------------------------------------
311 -- For a duplex handle, we arrange that the read side points to the write side
312 -- (and hence keeps it alive if the read side is alive). This is done by
313 -- having the haOtherSide field of the read side point to the read side.
314 -- The finalizer is then placed on the write side, and the handle only gets
315 -- finalized once, when both sides are no longer required.
317 -- NOTE about finalized handles: It's possible that a handle can be
318 -- finalized and then we try to use it later, for example if the
319 -- handle is referenced from another finalizer, or from a thread that
320 -- has become unreferenced and then resurrected (arguably in the
321 -- latter case we shouldn't finalize the Handle...). Anyway,
322 -- we try to emit a helpful message which is better than nothing.
324 handleFinalizer :: FilePath -> MVar Handle__ -> IO ()
325 handleFinalizer fp m = do
326 handle_ <- takeMVar m
327 case haType handle_ of
328 ClosedHandle -> return ()
329 _ -> do flushWriteBuffer handle_ `catchAny` \_ -> return ()
330 -- ignore errors and async exceptions, and close the
331 -- descriptor anyway...
332 _ <- hClose_handle_ handle_
334 putMVar m (ioe_finalizedHandle fp)
336 -- ---------------------------------------------------------------------------
337 -- Allocating buffers
339 -- using an 8k char buffer instead of 32k improved performance for a
340 -- basic "cat" program by ~30% for me. --SDM
341 dEFAULT_CHAR_BUFFER_SIZE :: Int
342 dEFAULT_CHAR_BUFFER_SIZE = dEFAULT_BUFFER_SIZE `div` 4
344 getCharBuffer :: IODevice dev => dev -> BufferState
345 -> IO (IORef CharBuffer, BufferMode)
346 getCharBuffer dev state = do
347 buffer <- newCharBuffer dEFAULT_CHAR_BUFFER_SIZE state
348 ioref <- newIORef buffer
349 is_tty <- IODevice.isTerminal dev
352 | is_tty = LineBuffering
353 | otherwise = BlockBuffering Nothing
355 return (ioref, buffer_mode)
357 mkUnBuffer :: BufferState -> IO (IORef CharBuffer, BufferMode)
358 mkUnBuffer state = do
359 buffer <- case state of -- See [note Buffer Sizing], GHC.IO.Handle.Types
360 ReadBuffer -> newCharBuffer dEFAULT_CHAR_BUFFER_SIZE state
361 WriteBuffer -> newCharBuffer 1 state
362 ref <- newIORef buffer
363 return (ref, NoBuffering)
365 -- -----------------------------------------------------------------------------
368 -- | syncs the file with the buffer, including moving the
369 -- file pointer backwards in the case of a read buffer. This can fail
370 -- on a non-seekable read Handle.
371 flushBuffer :: Handle__ -> IO ()
372 flushBuffer h_@Handle__{..} = do
373 buf <- readIORef haCharBuffer
376 flushCharReadBuffer h_
377 flushByteReadBuffer h_
379 buf' <- flushWriteBuffer_ h_ buf
380 writeIORef haCharBuffer buf'
382 -- | flushes at least the Char buffer, and the byte buffer for a write
383 -- Handle. Works on all Handles.
384 flushCharBuffer :: Handle__ -> IO ()
385 flushCharBuffer h_@Handle__{..} = do
386 buf <- readIORef haCharBuffer
389 flushCharReadBuffer h_
391 buf' <- flushWriteBuffer_ h_ buf
392 writeIORef haCharBuffer buf'
394 -- -----------------------------------------------------------------------------
395 -- Writing data (flushing write buffers)
397 -- flushWriteBuffer flushes the buffer iff it contains pending write
398 -- data. Flushes both the Char and the byte buffer, leaving both
400 flushWriteBuffer :: Handle__ -> IO ()
401 flushWriteBuffer h_@Handle__{..} = do
402 buf <- readIORef haCharBuffer
404 then do buf' <- flushWriteBuffer_ h_ buf
405 writeIORef haCharBuffer buf'
408 flushWriteBuffer_ :: Handle__ -> CharBuffer -> IO CharBuffer
409 flushWriteBuffer_ h_@Handle__{..} cbuf = do
410 bbuf <- readIORef haByteBuffer
411 if not (isEmptyBuffer cbuf) || not (isEmptyBuffer bbuf)
412 then do writeTextDevice h_ cbuf
413 return cbuf{ bufL=0, bufR=0 }
416 -- -----------------------------------------------------------------------------
417 -- Flushing read buffers
419 -- It is always possible to flush the Char buffer back to the byte buffer.
420 flushCharReadBuffer :: Handle__ -> IO ()
421 flushCharReadBuffer Handle__{..} = do
422 cbuf <- readIORef haCharBuffer
423 if isWriteBuffer cbuf || isEmptyBuffer cbuf then return () else do
425 -- haLastDecode is the byte buffer just before we did our last batch of
426 -- decoding. We're going to re-decode the bytes up to the current char,
427 -- to find out where we should revert the byte buffer to.
428 (codec_state, bbuf0) <- readIORef haLastDecode
430 cbuf0 <- readIORef haCharBuffer
431 writeIORef haCharBuffer cbuf0{ bufL=0, bufR=0 }
433 -- if we haven't used any characters from the char buffer, then just
434 -- re-install the old byte buffer.
436 then do writeIORef haByteBuffer bbuf0
442 writeIORef haByteBuffer bbuf0 { bufL = bufL bbuf0 + bufL cbuf0 }
443 -- no decoder: the number of bytes to decode is the same as the
444 -- number of chars we have used up.
447 debugIO ("flushCharReadBuffer re-decode, bbuf=" ++ summaryBuffer bbuf0 ++
448 " cbuf=" ++ summaryBuffer cbuf0)
450 -- restore the codec state
451 setState decoder codec_state
453 (bbuf1,cbuf1) <- (encode decoder) bbuf0
454 cbuf0{ bufL=0, bufR=0, bufSize = bufL cbuf0 }
456 debugIO ("finished, bbuf=" ++ summaryBuffer bbuf1 ++
457 " cbuf=" ++ summaryBuffer cbuf1)
459 writeIORef haByteBuffer bbuf1
462 -- When flushing the byte read buffer, we seek backwards by the number
463 -- of characters in the buffer. The file descriptor must therefore be
464 -- seekable: attempting to flush the read buffer on an unseekable
465 -- handle is not allowed.
467 flushByteReadBuffer :: Handle__ -> IO ()
468 flushByteReadBuffer h_@Handle__{..} = do
469 bbuf <- readIORef haByteBuffer
471 if isEmptyBuffer bbuf then return () else do
473 seekable <- IODevice.isSeekable haDevice
474 when (not seekable) $ ioe_cannotFlushNotSeekable
476 let seek = negate (bufR bbuf - bufL bbuf)
478 debugIO ("flushByteReadBuffer: new file offset = " ++ show seek)
479 IODevice.seek haDevice RelativeSeek (fromIntegral seek)
481 writeIORef haByteBuffer bbuf{ bufL=0, bufR=0 }
483 -- ----------------------------------------------------------------------------
486 mkHandle :: (IODevice dev, BufferedIO dev, Typeable dev) => dev
490 -> Maybe TextEncoding
492 -> Maybe HandleFinalizer
493 -> Maybe (MVar Handle__)
496 mkHandle dev filepath ha_type buffered mb_codec nl finalizer other_side = do
497 openTextEncoding mb_codec ha_type $ \ mb_encoder mb_decoder -> do
499 let buf_state = initBufferState ha_type
500 bbuf <- Buffered.newBuffer dev buf_state
501 bbufref <- newIORef bbuf
502 last_decode <- newIORef (error "codec_state", bbuf)
505 if buffered then getCharBuffer dev buf_state
506 else mkUnBuffer buf_state
508 spares <- newIORef BufferListNil
509 newFileHandle filepath finalizer
510 (Handle__ { haDevice = dev,
512 haBufferMode = bmode,
513 haByteBuffer = bbufref,
514 haLastDecode = last_decode,
515 haCharBuffer = cbufref,
517 haEncoder = mb_encoder,
518 haDecoder = mb_decoder,
520 haInputNL = inputNL nl,
521 haOutputNL = outputNL nl,
522 haOtherSide = other_side
525 -- | makes a new 'Handle'
526 mkFileHandle :: (IODevice dev, BufferedIO dev, Typeable dev)
527 => dev -- ^ the underlying IO device, which must support
528 -- 'IODevice', 'BufferedIO' and 'Typeable'
530 -- ^ a string describing the 'Handle', e.g. the file
531 -- path for a file. Used in error messages.
533 -- The mode in which the 'Handle' is to be used
534 -> Maybe TextEncoding
535 -- Create the 'Handle' with no text encoding?
537 -- Translate newlines?
539 mkFileHandle dev filepath iomode mb_codec tr_newlines = do
540 mkHandle dev filepath (ioModeToHandleType iomode) True{-buffered-} mb_codec
542 (Just handleFinalizer) Nothing{-other_side-}
544 -- | like 'mkFileHandle', except that a 'Handle' is created with two
545 -- independent buffers, one for reading and one for writing. Used for
546 -- full-dupliex streams, such as network sockets.
547 mkDuplexHandle :: (IODevice dev, BufferedIO dev, Typeable dev) => dev
548 -> FilePath -> Maybe TextEncoding -> NewlineMode -> IO Handle
549 mkDuplexHandle dev filepath mb_codec tr_newlines = do
551 write_side@(FileHandle _ write_m) <-
552 mkHandle dev filepath WriteHandle True mb_codec
554 (Just handleFinalizer)
555 Nothing -- no othersie
557 read_side@(FileHandle _ read_m) <-
558 mkHandle dev filepath ReadHandle True mb_codec
560 Nothing -- no finalizer
563 return (DuplexHandle filepath read_m write_m)
565 ioModeToHandleType :: IOMode -> HandleType
566 ioModeToHandleType ReadMode = ReadHandle
567 ioModeToHandleType WriteMode = WriteHandle
568 ioModeToHandleType ReadWriteMode = ReadWriteHandle
569 ioModeToHandleType AppendMode = AppendHandle
571 initBufferState :: HandleType -> BufferState
572 initBufferState ReadHandle = ReadBuffer
573 initBufferState _ = WriteBuffer
576 :: Maybe TextEncoding
578 -> (forall es ds . Maybe (TextEncoder es) -> Maybe (TextDecoder ds) -> IO a)
581 openTextEncoding Nothing ha_type cont = cont Nothing Nothing
582 openTextEncoding (Just TextEncoding{..}) ha_type cont = do
583 mb_decoder <- if isReadableHandleType ha_type then do
584 decoder <- mkTextDecoder
585 return (Just decoder)
588 mb_encoder <- if isWritableHandleType ha_type then do
589 encoder <- mkTextEncoder
590 return (Just encoder)
593 cont mb_encoder mb_decoder
595 -- ---------------------------------------------------------------------------
598 -- hClose_help is also called by lazyRead (in GHC.IO.Handle.Text) when
599 -- EOF is read or an IO error occurs on a lazy stream. The
600 -- semi-closed Handle is then closed immediately. We have to be
601 -- careful with DuplexHandles though: we have to leave the closing to
602 -- the finalizer in that case, because the write side may still be in
604 hClose_help :: Handle__ -> IO (Handle__, Maybe SomeException)
605 hClose_help handle_ =
606 case haType handle_ of
607 ClosedHandle -> return (handle_,Nothing)
608 _ -> do mb_exc1 <- trymaybe $ flushWriteBuffer handle_ -- interruptible
609 -- it is important that hClose doesn't fail and
610 -- leave the Handle open (#3128), so we catch
611 -- exceptions when flushing the buffer.
612 (h_, mb_exc2) <- hClose_handle_ handle_
613 return (h_, if isJust mb_exc1 then mb_exc1 else mb_exc2)
616 trymaybe :: IO () -> IO (Maybe SomeException)
617 trymaybe io = (do io; return Nothing) `catchException` \e -> return (Just e)
619 hClose_handle_ :: Handle__ -> IO (Handle__, Maybe SomeException)
620 hClose_handle_ Handle__{..} = do
622 -- close the file descriptor, but not when this is the read
623 -- side of a duplex handle.
624 -- If an exception is raised by the close(), we want to continue
625 -- to close the handle and release the lock if it has one, then
626 -- we return the exception to the caller of hClose_help which can
627 -- raise it if necessary.
630 Nothing -> trymaybe $ IODevice.close haDevice
631 Just _ -> return Nothing
633 -- free the spare buffers
634 writeIORef haBuffers BufferListNil
635 writeIORef haCharBuffer noCharBuffer
636 writeIORef haByteBuffer noByteBuffer
638 -- release our encoder/decoder
639 case haDecoder of Nothing -> return (); Just d -> close d
640 case haEncoder of Nothing -> return (); Just d -> close d
642 -- we must set the fd to -1, because the finalizer is going
643 -- to run eventually and try to close/unlock it.
644 -- ToDo: necessary? the handle will be marked ClosedHandle
645 -- XXX GHC won't let us use record update here, hence wildcards
646 return (Handle__{ haType = ClosedHandle, .. }, maybe_exception)
648 {-# NOINLINE noCharBuffer #-}
649 noCharBuffer :: CharBuffer
650 noCharBuffer = unsafePerformIO $ newCharBuffer 1 ReadBuffer
652 {-# NOINLINE noByteBuffer #-}
653 noByteBuffer :: Buffer Word8
654 noByteBuffer = unsafePerformIO $ newByteBuffer 1 ReadBuffer
656 -- ---------------------------------------------------------------------------
659 hLookAhead_ :: Handle__ -> IO Char
660 hLookAhead_ handle_@Handle__{..} = do
661 buf <- readIORef haCharBuffer
663 -- fill up the read buffer if necessary
664 new_buf <- if isEmptyBuffer buf
665 then readTextDevice handle_ buf
667 writeIORef haCharBuffer new_buf
669 peekCharBuf (bufRaw buf) (bufL buf)
671 -- ---------------------------------------------------------------------------
674 debugIO :: String -> IO ()
677 = do _ <- withCStringLen (s ++ "\n") $
678 \(p, len) -> c_write 1 (castPtr p) (fromIntegral len)
680 | otherwise = return ()
682 -- ----------------------------------------------------------------------------
685 -- Write the contents of the supplied Char buffer to the device, return
686 -- only when all the data has been written.
687 writeTextDevice :: Handle__ -> CharBuffer -> IO ()
688 writeTextDevice h_@Handle__{..} cbuf = do
690 bbuf <- readIORef haByteBuffer
692 debugIO ("writeTextDevice: cbuf=" ++ summaryBuffer cbuf ++
693 " bbuf=" ++ summaryBuffer bbuf)
695 (cbuf',bbuf') <- case haEncoder of
696 Nothing -> latin1_encode cbuf bbuf
697 Just encoder -> (encode encoder) cbuf bbuf
699 debugIO ("writeTextDevice after encoding: cbuf=" ++ summaryBuffer cbuf' ++
700 " bbuf=" ++ summaryBuffer bbuf')
702 bbuf' <- Buffered.flushWriteBuffer haDevice bbuf'
703 writeIORef haByteBuffer bbuf'
704 if not (isEmptyBuffer cbuf')
705 then writeTextDevice h_ cbuf'
708 -- Read characters into the provided buffer. Return when any
709 -- characters are available; raise an exception if the end of
711 readTextDevice :: Handle__ -> CharBuffer -> IO CharBuffer
712 readTextDevice h_@Handle__{..} cbuf = do
714 bbuf0 <- readIORef haByteBuffer
716 debugIO ("readTextDevice: cbuf=" ++ summaryBuffer cbuf ++
717 " bbuf=" ++ summaryBuffer bbuf0)
719 bbuf1 <- if not (isEmptyBuffer bbuf0)
722 (r,bbuf1) <- Buffered.fillReadBuffer haDevice bbuf0
723 if r == 0 then ioe_EOF else do -- raise EOF
726 debugIO ("readTextDevice after reading: bbuf=" ++ summaryBuffer bbuf1)
731 writeIORef haLastDecode (error "codec_state", bbuf1)
732 latin1_decode bbuf1 cbuf
734 state <- getState decoder
735 writeIORef haLastDecode (state, bbuf1)
736 (encode decoder) bbuf1 cbuf
738 debugIO ("readTextDevice after decoding: cbuf=" ++ summaryBuffer cbuf' ++
739 " bbuf=" ++ summaryBuffer bbuf2)
741 writeIORef haByteBuffer bbuf2
742 if bufR cbuf' == bufR cbuf -- no new characters
743 then readTextDevice' h_ bbuf2 cbuf -- we need more bytes to make a Char
746 -- we have an incomplete byte sequence at the end of the buffer: try to
748 readTextDevice' :: Handle__ -> Buffer Word8 -> CharBuffer -> IO CharBuffer
749 readTextDevice' h_@Handle__{..} bbuf0 cbuf = do
751 -- copy the partial sequence to the beginning of the buffer, so we have
752 -- room to read more bytes.
753 bbuf1 <- slideContents bbuf0
755 bbuf2 <- do (r,bbuf2) <- Buffered.fillReadBuffer haDevice bbuf1
757 then ioe_invalidCharacter
760 debugIO ("readTextDevice after reading: bbuf=" ++ summaryBuffer bbuf2)
765 writeIORef haLastDecode (error "codec_state", bbuf2)
766 latin1_decode bbuf2 cbuf
768 state <- getState decoder
769 writeIORef haLastDecode (state, bbuf2)
770 (encode decoder) bbuf2 cbuf
772 debugIO ("readTextDevice after decoding: cbuf=" ++ summaryBuffer cbuf' ++
773 " bbuf=" ++ summaryBuffer bbuf3)
775 writeIORef haByteBuffer bbuf3
776 if bufR cbuf == bufR cbuf'
777 then readTextDevice' h_ bbuf3 cbuf'
780 -- Read characters into the provided buffer. Do not block;
781 -- return zero characters instead. Raises an exception on end-of-file.
782 readTextDeviceNonBlocking :: Handle__ -> CharBuffer -> IO CharBuffer
783 readTextDeviceNonBlocking h_@Handle__{..} cbuf = do
785 bbuf0 <- readIORef haByteBuffer
786 bbuf1 <- if not (isEmptyBuffer bbuf0)
789 (r,bbuf1) <- Buffered.fillReadBuffer0 haDevice bbuf0
790 if isNothing r then ioe_EOF else do -- raise EOF
796 writeIORef haLastDecode (error "codec_state", bbuf1)
797 latin1_decode bbuf1 cbuf
799 state <- getState decoder
800 writeIORef haLastDecode (state, bbuf1)
801 (encode decoder) bbuf1 cbuf
803 writeIORef haByteBuffer bbuf2