X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Futils%2FBufWrite.hs;fp=compiler%2Futils%2FBufWrite.hs;h=a03db3d0842d2d42e1576c7a47c2abe584c94847;hb=0065d5ab628975892cea1ec7303f968c3338cbe1;hp=0000000000000000000000000000000000000000;hpb=28a464a75e14cece5db40f2765a29348273ff2d2;p=ghc-hetmet.git diff --git a/compiler/utils/BufWrite.hs b/compiler/utils/BufWrite.hs new file mode 100644 index 0000000..a03db3d --- /dev/null +++ b/compiler/utils/BufWrite.hs @@ -0,0 +1,124 @@ +----------------------------------------------------------------------------- +-- +-- Fast write-buffered Handles +-- +-- (c) The University of Glasgow 2005 +-- +-- This is a simple abstraction over Handles that offers very fast write +-- buffering, but without the thread safety that Handles provide. It's used +-- to save time in Pretty.printDoc. +-- +----------------------------------------------------------------------------- + +module BufWrite ( + BufHandle(..), + newBufHandle, + bPutChar, + bPutStr, + bPutFS, + bPutLitString, + bFlush, + ) where + +#include "HsVersions.h" + +import FastString +import FastMutInt +import Panic ( panic ) + +import Monad ( when ) +import Char ( ord ) +import Foreign +import IO + +import GHC.IOBase ( IO(..) ) +import System.IO ( hPutBuf ) +import GHC.Ptr ( Ptr(..) ) + +import GLAEXTS ( Int(..), Int#, Addr# ) + +-- ----------------------------------------------------------------------------- + +data BufHandle = BufHandle {-#UNPACK#-}!(Ptr Word8) + {-#UNPACK#-}!FastMutInt + Handle + +newBufHandle :: Handle -> IO BufHandle +newBufHandle hdl = do + ptr <- mallocBytes buf_size + r <- newFastMutInt + writeFastMutInt r 0 + return (BufHandle ptr r hdl) + +buf_size = 8192 :: Int + +#define STRICT2(f) f a b | a `seq` b `seq` False = undefined +#define STRICT3(f) f a b c | a `seq` b `seq` c `seq` False = undefined + +bPutChar :: BufHandle -> Char -> IO () +STRICT2(bPutChar) +bPutChar b@(BufHandle buf r hdl) c = do + i <- readFastMutInt r + if (i >= buf_size) + then do hPutBuf hdl buf buf_size + writeFastMutInt r 0 + bPutChar b c + else do pokeElemOff buf i (fromIntegral (ord c) :: Word8) + writeFastMutInt r (i+1) + +bPutStr :: BufHandle -> String -> IO () +STRICT2(bPutStr) +bPutStr b@(BufHandle buf r hdl) str = do + i <- readFastMutInt r + loop str i + where loop _ i | i `seq` False = undefined + loop "" i = do writeFastMutInt r i; return () + loop (c:cs) i + | i >= buf_size = do + hPutBuf hdl buf buf_size + loop (c:cs) 0 + | otherwise = do + pokeElemOff buf i (fromIntegral (ord c)) + loop cs (i+1) + +bPutFS :: BufHandle -> FastString -> IO () +bPutFS b@(BufHandle buf r hdl) fs@(FastString _ len _ fp _) = + withForeignPtr fp $ \ptr -> do + i <- readFastMutInt r + if (i + len) >= buf_size + then do hPutBuf hdl buf i + writeFastMutInt r 0 + if (len >= buf_size) + then hPutBuf hdl ptr len + else bPutFS b fs + else do + copyBytes (buf `plusPtr` i) ptr len + writeFastMutInt r (i+len) + +bPutLitString :: BufHandle -> Addr# -> Int# -> IO () +bPutLitString b@(BufHandle buf r hdl) a# len# = do + let len = I# len# + i <- readFastMutInt r + if (i+len) >= buf_size + then do hPutBuf hdl buf i + writeFastMutInt r 0 + if (len >= buf_size) + then hPutBuf hdl (Ptr a#) len + else bPutLitString b a# len# + else do + copyBytes (buf `plusPtr` i) (Ptr a#) len + writeFastMutInt r (i+len) + +bFlush :: BufHandle -> IO () +bFlush b@(BufHandle buf r hdl) = do + i <- readFastMutInt r + when (i > 0) $ hPutBuf hdl buf i + free buf + return () + +#if 0 +myPutBuf s hdl buf i = + modifyIOError (\e -> ioeSetErrorString e (ioeGetErrorString e ++ ':':s ++ " (" ++ show buf ++ "," ++ show i ++ ")")) $ + + hPutBuf hdl buf i +#endif