A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://hackage.haskell.org/packages/archive/base/4.6.0.0/doc/html/src/GHC-IO-Handle.html below:

GHC/IO/Handle.hs



















module GHC.IO.Handle (
   Handle,
   BufferMode(..),
 
   mkFileHandle, mkDuplexHandle,
 
   hFileSize, hSetFileSize, hIsEOF, hLookAhead,
   hSetBuffering, hSetBinaryMode, hSetEncoding, hGetEncoding,
   hFlush, hFlushAll, hDuplicate, hDuplicateTo,
 
   hClose, hClose_help,
 
   HandlePosition, HandlePosn(..), hGetPosn, hSetPosn,
   SeekMode(..), hSeek, hTell,
 
   hIsOpen, hIsClosed, hIsReadable, hIsWritable, hGetBuffering, hIsSeekable,
   hSetEcho, hGetEcho, hIsTerminalDevice,
 
   hSetNewlineMode, Newline(..), NewlineMode(..), nativeNewline,
   noNewlineTranslation, universalNewlineMode, nativeNewlineMode,

   hShow,

   hWaitForInput, hGetChar, hGetLine, hGetContents, hPutChar, hPutStr,

   hGetBuf, hGetBufNonBlocking, hPutBuf, hPutBufNonBlocking
 ) where

import GHC.IO
import GHC.IO.Exception
import GHC.IO.Encoding
import GHC.IO.Buffer
import GHC.IO.BufferedIO ( BufferedIO )
import GHC.IO.Device as IODevice
import GHC.IO.Handle.Types
import GHC.IO.Handle.Internals
import GHC.IO.Handle.Text
import qualified GHC.IO.BufferedIO as Buffered

import GHC.Base
import GHC.Exception
import GHC.MVar
import GHC.IORef
import GHC.Show
import GHC.Num
import GHC.Real
import Data.Maybe
import Data.Typeable
import Control.Monad













hClose :: Handle -> IO ()
hClose h@(FileHandle _ m)     = do 
  mb_exc <- hClose' h m
  hClose_maybethrow mb_exc h
hClose h@(DuplexHandle _ r w) = do
  excs <- mapM (hClose' h) [r,w]
  hClose_maybethrow (listToMaybe (catMaybes excs)) h

hClose_maybethrow :: Maybe SomeException -> Handle -> IO ()
hClose_maybethrow Nothing  h = return ()
hClose_maybethrow (Just e) h = hClose_rethrow e h

hClose_rethrow :: SomeException -> Handle -> IO ()
hClose_rethrow e h = 
  case fromException e of
    Just ioe -> ioError (augmentIOError ioe "hClose" h)
    Nothing  -> throwIO e

hClose' :: Handle -> MVar Handle__ -> IO (Maybe SomeException)
hClose' h m = withHandle' "hClose" h m $ hClose_help







hFileSize :: Handle -> IO Integer
hFileSize handle =
    withHandle_ "hFileSize" handle $ \ handle_@Handle__{haDevice=dev} -> do
    case haType handle_ of 
      ClosedHandle              -> ioe_closedHandle
      SemiClosedHandle          -> ioe_closedHandle
      _ -> do flushWriteBuffer handle_
              r <- IODevice.getSize dev
              if r /= 1
                 then return r
                 else ioException (IOError Nothing InappropriateType "hFileSize"
                                   "not a regular file" Nothing Nothing)




hSetFileSize :: Handle -> Integer -> IO ()
hSetFileSize handle size =
    withHandle_ "hSetFileSize" handle $ \ handle_@Handle__{haDevice=dev} -> do
    case haType handle_ of 
      ClosedHandle              -> ioe_closedHandle
      SemiClosedHandle          -> ioe_closedHandle
      _ -> do flushWriteBuffer handle_
              IODevice.setSize dev size
              return ()












hIsEOF :: Handle -> IO Bool
hIsEOF handle = wantReadableHandle_ "hIsEOF" handle $ \Handle__{..} -> do

  cbuf <- readIORef haCharBuffer
  if not (isEmptyBuffer cbuf) then return False else do

  bbuf <- readIORef haByteBuffer
  if not (isEmptyBuffer bbuf) then return False else do

  
  (r,bbuf') <- Buffered.fillReadBuffer haDevice bbuf
  if r == 0
     then return True
     else do writeIORef haByteBuffer bbuf'
             return False












hLookAhead :: Handle -> IO Char
hLookAhead handle =
  wantReadableHandle_ "hLookAhead"  handle hLookAhead_
























hSetBuffering :: Handle -> BufferMode -> IO ()
hSetBuffering handle mode =
  withAllHandles__ "hSetBuffering" handle $ \ handle_@Handle__{..} -> do
  case haType of
    ClosedHandle -> ioe_closedHandle
    _ -> do
         if mode == haBufferMode then return handle_ else do

         

          
          case mode of
              BlockBuffering (Just n) | n <= 0    -> ioe_bufsiz n
              _ -> return ()

          
          
          is_tty <- IODevice.isTerminal haDevice
          when (is_tty && isReadableHandleType haType) $
                case mode of
#ifndef mingw32_HOST_OS
        
        
                  NoBuffering -> IODevice.setRaw haDevice True
#else
                  NoBuffering -> return ()
#endif
                  _           -> IODevice.setRaw haDevice False

          
          writeIORef haBuffers BufferListNil

          return Handle__{ haBufferMode = mode,.. }
















hSetEncoding :: Handle -> TextEncoding -> IO ()
hSetEncoding hdl encoding = do
  withAllHandles__ "hSetEncoding" hdl $ \h_@Handle__{..} -> do
    flushCharBuffer h_
    closeTextCodecs h_
    openTextEncoding (Just encoding) haType $ \ mb_encoder mb_decoder -> do
    bbuf <- readIORef haByteBuffer
    ref <- newIORef (error "last_decode")
    return (Handle__{ haLastDecode = ref, 
                      haDecoder = mb_decoder, 
                      haEncoder = mb_encoder,
                      haCodec   = Just encoding, .. })










hGetEncoding :: Handle -> IO (Maybe TextEncoding)
hGetEncoding hdl =
  withHandle_ "hGetEncoding" hdl $ \h_@Handle__{..} -> return haCodec















hFlush :: Handle -> IO () 
hFlush handle = wantWritableHandle "hFlush" handle flushWriteBuffer


















hFlushAll :: Handle -> IO () 
hFlushAll handle = withHandle_ "hFlushAll" handle flushBuffer




data HandlePosn = HandlePosn Handle HandlePosition

instance Eq HandlePosn where
    (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2

instance Show HandlePosn where
   showsPrec p (HandlePosn h pos) = 
        showsPrec p h . showString " at position " . shows pos

  
  
  
  
type HandlePosition = Integer




hGetPosn :: Handle -> IO HandlePosn
hGetPosn handle = do
    posn <- hTell handle
    return (HandlePosn handle posn)









hSetPosn :: HandlePosn -> IO () 
hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i



























hSeek :: Handle -> SeekMode -> Integer -> IO () 
hSeek handle mode offset =
    wantSeekableHandle "hSeek" handle $ \ handle_@Handle__{..} -> do
    debugIO ("hSeek " ++ show (mode,offset))
    buf <- readIORef haCharBuffer

    if isWriteBuffer buf
        then do flushWriteBuffer handle_
                IODevice.seek haDevice mode offset
        else do

    let r = bufL buf; w = bufR buf
    if mode == RelativeSeek && isNothing haDecoder && 
       offset >= 0 && offset < fromIntegral (w  r)
        then writeIORef haCharBuffer buf{ bufL = r + fromIntegral offset }
        else do 

    flushCharReadBuffer handle_
    flushByteReadBuffer handle_
    IODevice.seek haDevice mode offset











hTell :: Handle -> IO Integer
hTell handle = 
    wantSeekableHandle "hGetPosn" handle $ \ handle_@Handle__{..} -> do

      posn <- IODevice.tell haDevice

      
      
      flushCharBuffer handle_

      bbuf <- readIORef haByteBuffer

      let real_posn
           | isWriteBuffer bbuf = posn + fromIntegral (bufferElems bbuf)
           | otherwise          = posn  fromIntegral (bufferElems bbuf)

      cbuf <- readIORef haCharBuffer
      debugIO ("\nhGetPosn: (posn, real_posn) = " ++ show (posn, real_posn))
      debugIO ("   cbuf: " ++ summaryBuffer cbuf ++
            "   bbuf: " ++ summaryBuffer bbuf)

      return real_posn








hIsOpen :: Handle -> IO Bool
hIsOpen handle =
    withHandle_ "hIsOpen" handle $ \ handle_ -> do
    case haType handle_ of 
      ClosedHandle         -> return False
      SemiClosedHandle     -> return False
      _                    -> return True

hIsClosed :: Handle -> IO Bool
hIsClosed handle =
    withHandle_ "hIsClosed" handle $ \ handle_ -> do
    case haType handle_ of 
      ClosedHandle         -> return True
      _                    -> return False



hIsReadable :: Handle -> IO Bool
hIsReadable (DuplexHandle _ _ _) = return True
hIsReadable handle =
    withHandle_ "hIsReadable" handle $ \ handle_ -> do
    case haType handle_ of 
      ClosedHandle         -> ioe_closedHandle
      SemiClosedHandle     -> ioe_closedHandle
      htype                -> return (isReadableHandleType htype)

hIsWritable :: Handle -> IO Bool
hIsWritable (DuplexHandle _ _ _) = return True
hIsWritable handle =
    withHandle_ "hIsWritable" handle $ \ handle_ -> do
    case haType handle_ of 
      ClosedHandle         -> ioe_closedHandle
      SemiClosedHandle     -> ioe_closedHandle
      htype                -> return (isWritableHandleType htype)




hGetBuffering :: Handle -> IO BufferMode
hGetBuffering handle = 
    withHandle_ "hGetBuffering" handle $ \ handle_ -> do
    case haType handle_ of 
      ClosedHandle         -> ioe_closedHandle
      _ -> 
           
           
          return (haBufferMode handle_)  

hIsSeekable :: Handle -> IO Bool
hIsSeekable handle =
    withHandle_ "hIsSeekable" handle $ \ handle_@Handle__{..} -> do
    case haType of 
      ClosedHandle         -> ioe_closedHandle
      SemiClosedHandle     -> ioe_closedHandle
      AppendHandle         -> return False
      _                    -> IODevice.isSeekable haDevice






hSetEcho :: Handle -> Bool -> IO ()
hSetEcho handle on = do
    isT   <- hIsTerminalDevice handle
    if not isT
     then return ()
     else
      withHandle_ "hSetEcho" handle $ \ Handle__{..} -> do
      case haType of 
         ClosedHandle -> ioe_closedHandle
         _            -> IODevice.setEcho haDevice on



hGetEcho :: Handle -> IO Bool
hGetEcho handle = do
    isT   <- hIsTerminalDevice handle
    if not isT
     then return False
     else
       withHandle_ "hGetEcho" handle $ \ Handle__{..} -> do
       case haType of 
         ClosedHandle -> ioe_closedHandle
         _            -> IODevice.getEcho haDevice



hIsTerminalDevice :: Handle -> IO Bool
hIsTerminalDevice handle = do
    withHandle_ "hIsTerminalDevice" handle $ \ Handle__{..} -> do
     case haType of 
       ClosedHandle -> ioe_closedHandle
       _            -> IODevice.isTerminal haDevice










hSetBinaryMode :: Handle -> Bool -> IO ()
hSetBinaryMode handle bin =
  withAllHandles__ "hSetBinaryMode" handle $ \ h_@Handle__{..} ->
    do 
         flushCharBuffer h_
         closeTextCodecs h_

         mb_te <- if bin then return Nothing
                         else fmap Just getLocaleEncoding

         openTextEncoding mb_te haType $ \ mb_encoder mb_decoder -> do

         
         let nl    | bin       = noNewlineTranslation
                   | otherwise = nativeNewlineMode

         bbuf <- readIORef haByteBuffer
         ref <- newIORef (error "codec_state", bbuf)

         return Handle__{ haLastDecode = ref,
                          haEncoder  = mb_encoder, 
                          haDecoder  = mb_decoder,
                          haCodec    = mb_te,
                          haInputNL  = inputNL nl,
                          haOutputNL = outputNL nl, .. }
  





hSetNewlineMode :: Handle -> NewlineMode -> IO ()
hSetNewlineMode handle NewlineMode{ inputNL=i, outputNL=o } =
  withAllHandles__ "hSetNewlineMode" handle $ \h_@Handle__{..} ->
    do
         flushBuffer h_
         return h_{ haInputNL=i, haOutputNL=o }









hDuplicate :: Handle -> IO Handle
hDuplicate h@(FileHandle path m) = do
  withHandle_' "hDuplicate" h m $ \h_ ->
      dupHandle path h Nothing h_ (Just handleFinalizer)
hDuplicate h@(DuplexHandle path r w) = do
  write_side@(FileHandle _ write_m) <- 
     withHandle_' "hDuplicate" h w $ \h_ ->
        dupHandle path h Nothing h_ (Just handleFinalizer)
  read_side@(FileHandle _ read_m) <- 
    withHandle_' "hDuplicate" h r $ \h_ ->
        dupHandle path h (Just write_m) h_  Nothing
  return (DuplexHandle path read_m write_m)

dupHandle :: FilePath
          -> Handle
          -> Maybe (MVar Handle__)
          -> Handle__
          -> Maybe HandleFinalizer
          -> IO Handle
dupHandle filepath h other_side h_@Handle__{..} mb_finalizer = do
  
  flushBuffer h_
  case other_side of
    Nothing -> do
       new_dev <- IODevice.dup haDevice
       dupHandle_ new_dev filepath other_side h_ mb_finalizer
    Just r  -> 
       withHandle_' "dupHandle" h r $ \Handle__{haDevice=dev} -> do
         dupHandle_ dev filepath other_side h_ mb_finalizer

dupHandle_ :: (IODevice dev, BufferedIO dev, Typeable dev) => dev
           -> FilePath
           -> Maybe (MVar Handle__)
           -> Handle__
           -> Maybe HandleFinalizer
           -> IO Handle
dupHandle_ new_dev filepath other_side h_@Handle__{..} mb_finalizer = do
   
  mb_codec <- if isJust haEncoder then fmap Just getLocaleEncoding else return Nothing
  mkHandle new_dev filepath haType True mb_codec
      NewlineMode { inputNL = haInputNL, outputNL = haOutputNL }
      mb_finalizer other_side






hDuplicateTo :: Handle -> Handle -> IO ()
hDuplicateTo h1@(FileHandle path m1) h2@(FileHandle _ m2)  = do
 withHandle__' "hDuplicateTo" h2 m2 $ \h2_ -> do
   _ <- hClose_help h2_
   withHandle_' "hDuplicateTo" h1 m1 $ \h1_ -> do
     dupHandleTo path h1 Nothing h2_ h1_ (Just handleFinalizer)
hDuplicateTo h1@(DuplexHandle path r1 w1) h2@(DuplexHandle _ r2 w2)  = do
 withHandle__' "hDuplicateTo" h2 w2  $ \w2_ -> do
   _ <- hClose_help w2_
   withHandle_' "hDuplicateTo" h1 w1 $ \w1_ -> do
     dupHandleTo path h1 Nothing w2_ w1_ (Just handleFinalizer)
 withHandle__' "hDuplicateTo" h2 r2  $ \r2_ -> do
   _ <- hClose_help r2_
   withHandle_' "hDuplicateTo" h1 r1 $ \r1_ -> do
     dupHandleTo path h1 (Just w1) r2_ r1_ Nothing
hDuplicateTo h1 _ = 
  ioe_dupHandlesNotCompatible h1


ioe_dupHandlesNotCompatible :: Handle -> IO a
ioe_dupHandlesNotCompatible h =
   ioException (IOError (Just h) IllegalOperation "hDuplicateTo" 
                "handles are incompatible" Nothing Nothing)

dupHandleTo :: FilePath 
            -> Handle
            -> Maybe (MVar Handle__)
            -> Handle__
            -> Handle__
            -> Maybe HandleFinalizer
            -> IO Handle__
dupHandleTo filepath h other_side 
            hto_@Handle__{haDevice=devTo,..}
            h_@Handle__{haDevice=dev} mb_finalizer = do
  flushBuffer h_
  case cast devTo of
    Nothing   -> ioe_dupHandlesNotCompatible h
    Just dev' -> do 
      _ <- IODevice.dup2 dev dev'
      FileHandle _ m <- dupHandle_ dev' filepath other_side h_ mb_finalizer
      takeMVar m







hShow :: Handle -> IO String
hShow h@(FileHandle path _) = showHandle' path False h
hShow h@(DuplexHandle path _ _) = showHandle' path True h

showHandle' :: String -> Bool -> Handle -> IO String
showHandle' filepath is_duplex h = 
  withHandle_ "showHandle" h $ \hdl_ ->
    let
     showType | is_duplex = showString "duplex (read-write)"
              | otherwise = shows (haType hdl_)
    in
    return 
      (( showChar '{' . 
        showHdl (haType hdl_) 
            (showString "loc=" . showString filepath . showChar ',' .
             showString "type=" . showType . showChar ',' .
             showString "buffering=" . showBufMode (unsafePerformIO (readIORef (haCharBuffer hdl_))) (haBufferMode hdl_) . showString "}" )
      ) "")
   where

    showHdl :: HandleType -> ShowS -> ShowS
    showHdl ht cont = 
       case ht of
        ClosedHandle  -> shows ht . showString "}"
        _ -> cont

    showBufMode :: Buffer e -> BufferMode -> ShowS
    showBufMode buf bmo =
      case bmo of
        NoBuffering   -> showString "none"
        LineBuffering -> showString "line"
        BlockBuffering (Just n) -> showString "block " . showParen True (shows n)
        BlockBuffering Nothing  -> showString "block " . showParen True (shows def)
      where
       def :: Int 
       def = bufSize buf


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4