2 -- The above warning supression flag is a temporary kludge.
3 -- While working on this module you are encouraged to remove it and fix
4 -- any warnings in the module. See
5 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
8 -----------------------------------------------------------------------------
10 -- Fast write-buffered Handles
12 -- (c) The University of Glasgow 2005-2006
14 -- This is a simple abstraction over Handles that offers very fast write
15 -- buffering, but without the thread safety that Handles provide. It's used
16 -- to save time in Pretty.printDoc.
18 -----------------------------------------------------------------------------
30 #include "HsVersions.h"
35 import Control.Monad ( when )
36 import Data.Char ( ord )
40 import GHC.IOBase ( IO(..) )
41 import GHC.Ptr ( Ptr(..) )
43 import GHC.Exts ( Int(..), Int#, Addr# )
45 -- -----------------------------------------------------------------------------
47 data BufHandle = BufHandle {-#UNPACK#-}!(Ptr Word8)
48 {-#UNPACK#-}!FastMutInt
51 newBufHandle :: Handle -> IO BufHandle
53 ptr <- mallocBytes buf_size
56 return (BufHandle ptr r hdl)
58 buf_size = 8192 :: Int
60 #define STRICT2(f) f a b | a `seq` b `seq` False = undefined
61 #define STRICT3(f) f a b c | a `seq` b `seq` c `seq` False = undefined
63 bPutChar :: BufHandle -> Char -> IO ()
65 bPutChar b@(BufHandle buf r hdl) c = do
68 then do hPutBuf hdl buf buf_size
71 else do pokeElemOff buf i (fromIntegral (ord c) :: Word8)
72 writeFastMutInt r (i+1)
74 bPutStr :: BufHandle -> String -> IO ()
76 bPutStr b@(BufHandle buf r hdl) str = do
79 where loop _ i | i `seq` False = undefined
80 loop "" i = do writeFastMutInt r i; return ()
83 hPutBuf hdl buf buf_size
86 pokeElemOff buf i (fromIntegral (ord c))
89 bPutFS :: BufHandle -> FastString -> IO ()
90 bPutFS b@(BufHandle buf r hdl) fs@(FastString _ len _ fp _) =
91 withForeignPtr fp $ \ptr -> do
93 if (i + len) >= buf_size
94 then do hPutBuf hdl buf i
97 then hPutBuf hdl ptr len
100 copyBytes (buf `plusPtr` i) ptr len
101 writeFastMutInt r (i+len)
103 bPutLitString :: BufHandle -> Addr# -> Int# -> IO ()
104 bPutLitString b@(BufHandle buf r hdl) a# len# = do
106 i <- readFastMutInt r
107 if (i+len) >= buf_size
108 then do hPutBuf hdl buf i
111 then hPutBuf hdl (Ptr a#) len
112 else bPutLitString b a# len#
114 copyBytes (buf `plusPtr` i) (Ptr a#) len
115 writeFastMutInt r (i+len)
117 bFlush :: BufHandle -> IO ()
118 bFlush b@(BufHandle buf r hdl) = do
119 i <- readFastMutInt r
120 when (i > 0) $ hPutBuf hdl buf i
125 myPutBuf s hdl buf i =
126 modifyIOError (\e -> ioeSetErrorString e (ioeGetErrorString e ++ ':':s ++ " (" ++ show buf ++ "," ++ show i ++ ")")) $