% (c) The University of Glasgow, 1997-2006
%
\begin{code}
-{-# OPTIONS -fglasgow-exts -O #-}
-
{-
FastString: A compact, hash-consed, representation of character strings.
Comparison is O(1), and you can get a Unique from them.
-- ** Outputing
hPutFS,
+ -- ** Internal
+ getFastStringTable,
+ hasZEncoding,
+
-- * LitStrings
LitString,
mkLitString#,
import Foreign
import Foreign.C
-import GLAEXTS
-import UNSAFE_IO ( unsafePerformIO )
-import MONAD_ST ( stToIO )
-import DATA_IOREF ( IORef, newIORef, readIORef, writeIORef )
+import GHC.Exts
+import System.IO.Unsafe ( unsafePerformIO )
+import Control.Monad.ST ( stToIO )
+import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
import System.IO ( hPutBuf )
+import Data.Maybe ( isJust )
import GHC.Arr ( STArray(..), newSTArray )
import GHC.IOBase ( IO(..) )
-
-import IO
+import GHC.Ptr ( Ptr(..) )
#define hASH_TBL_SIZE 4091
isZEncoded fs | ZEncoded <- enc fs = True
| otherwise = False
+-- | Returns 'True' if this 'FastString' is not Z-encoded but already has
+-- a Z-encoding cached (used in producing stats).
+hasZEncoding :: FastString -> Bool
+hasZEncoding fs@(FastString uid n_bytes _ fp enc) =
+ case enc of
+ ZEncoded -> False
+ UTF8Encoded ref ->
+ inlinePerformIO $ do
+ m <- readIORef ref
+ return (isJust m)
+
-- | Returns 'True' if the 'FastString' is empty
nullFS :: FastString -> Bool
nullFS f = n_bytes f == 0
nilFS = mkFastString ""
-- -----------------------------------------------------------------------------
+-- Stats
+
+getFastStringTable :: IO [[FastString]]
+getFastStringTable = do
+ tbl <- readIORef string_table
+ buckets <- mapM (lookupTbl tbl) [0..hASH_TBL_SIZE]
+ return buckets
+
+-- -----------------------------------------------------------------------------
-- Outputting 'FastString's
-- |Outputs a 'FastString' with /no decoding at all/, that is, you
inlinePerformIO :: IO a -> a
inlinePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
+-- NB. does *not* add a '\0'-terminator.
pokeCAString :: Ptr CChar -> String -> IO ()
pokeCAString ptr str =
let
- go [] n = pokeElemOff ptr n 0
+ go [] n = return ()
go (c:cs) n = do pokeElemOff ptr n (castCharToCChar c); go cs (n+1)
in
go str 0
+#if __GLASGOW_HASKELL__ < 600
+
+mallocForeignPtrBytes :: Int -> IO (ForeignPtr a)
+mallocForeignPtrBytes n = do
+ r <- mallocBytes n
+ newForeignPtr r (finalizerFree r)
+
+foreign import ccall unsafe "stdlib.h free"
+ finalizerFree :: Ptr a -> IO ()
+
+peekCAStringLen = peekCStringLen
+
+#elif __GLASGOW_HASKELL__ <= 602
+
+peekCAStringLen = peekCStringLen
+
+#endif
\end{code}