1 {-# LANGUAGE CPP, MagicHash #-} 2 3 -- | 4 -- Module : Data.Text.UnsafeChar 5 -- Copyright : (c) 2008, 2009 Tom Harper, 6 -- (c) 2009, 2010 Bryan O'Sullivan, 7 -- (c) 2009 Duncan Coutts 8 -- 9 -- License : BSD-style 10 -- Maintainer : bos@serpentine.com, rtomharper@googlemail.com, 11 -- duncan@haskell.org 12 -- Stability : experimental 13 -- Portability : GHC 14 -- 15 -- Fast character manipulation functions. 16 module Data.Text.UnsafeChar 17 ( 18 ord 19 , unsafeChr 20 , unsafeChr8 21 , unsafeChr32 22 , unsafeWrite 23 -- , unsafeWriteRev 24 ) where 25 26 #ifdef ASSERTS 27 import Control.Exception (assert) 28 #endif 29 import Control.Monad.ST (ST) 30 import Data.Bits ((.&.)) 31 import Data.Text.UnsafeShift (shiftR) 32 import GHC.Exts (Char(..), Int(..), chr#, ord#, word2Int#) 33 import GHC.Word (Word8(..), Word16(..), Word32(..)) 34 import qualified Data.Text.Array as A 35 36 ord :: Char -> Int 37 -- entered 3,457,720 timesord (C# c#) = I# (ord# c#) 38 {-# INLINE ord #-} 39 40 unsafeChr :: Word16 -> Char 41 -- entered 8,138,513 timesunsafeChr (W16# w#) = C# (chr# (word2Int# w#)) 42 {-# INLINE unsafeChr #-} 43 44 unsafeChr8 :: Word8 -> Char 45 -- entered 3778 timesunsafeChr8 (W8# w#) = C# (chr# (word2Int# w#)) 46 {-# INLINE unsafeChr8 #-} 47 48 unsafeChr32 :: Word32 -> Char 49 -- entered 10,866 timesunsafeChr32 (W32# w#) = C# (chr# (word2Int# w#)) 50 {-# INLINE unsafeChr32 #-} 51 52 -- | Write a character into the array at the given offset. Returns 53 -- the number of 'Word16's written. 54 unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int 55 -- entered 2,820,735 timesunsafeWrite marr i c 56 | n < 0x10000 = do 57 #if defined(ASSERTS) 58 assert (i >= 0) . assert (i < A.length marr) $ return () 59 #endif 60 A.unsafeWrite marr i (fromIntegral n) 61 return 1 62 | otherwise = do 63 #if defined(ASSERTS) 64 assert (i >= 0) . assert (i < A.length marr - 1) $ return () 65 #endif 66 A.unsafeWrite marr i lo 67 A.unsafeWrite marr (i+1) hi 68 return 2 69 where n = ord c 70 m = n - 0x10000 71 lo = fromIntegral $ (m `shiftR` 10) + 0xD800 72 hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00 73 {-# INLINE unsafeWrite #-} 74 75 {- 76 unsafeWriteRev :: A.MArray s Word16 -> Int -> Char -> ST s Int 77 unsafeWriteRev marr i c 78 | n < 0x10000 = do 79 assert (i >= 0) . assert (i < A.length marr) $ 80 A.unsafeWrite marr i (fromIntegral n) 81 return (i-1) 82 | otherwise = do 83 assert (i >= 1) . assert (i < A.length marr) $ 84 A.unsafeWrite marr (i-1) lo 85 A.unsafeWrite marr i hi 86 return (i-2) 87 where n = ord c 88 m = n - 0x10000 89 lo = fromIntegral $ (m `shiftR` 10) + 0xD800 90 hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00 91 {-# INLINE unsafeWriteRev #-} 92 -}