on builder help sign in
text/Data/Text/UnsafeChar.hs
92 lines 2.6 kB history raw
1{-# LANGUAGE CPP, MagicHash #-}
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.
16module Data.Text.UnsafeChar
17 (
18 ord
19 , unsafeChr
20 , unsafeChr8
21 , unsafeChr32
22 , unsafeWrite
23 -- , unsafeWriteRev
24 ) where
26#ifdef ASSERTS
27import Control.Exception (assert)
28#endif
29import Control.Monad.ST (ST)
30import Data.Bits ((.&.))
31import Data.Text.UnsafeShift (shiftR)
32import GHC.Exts (Char(..), Int(..), chr#, ord#, word2Int#)
33import GHC.Word (Word8(..), Word16(..), Word32(..))
34import qualified Data.Text.Array as A
36ord :: Char -> Int
37ord (C# c#) = I# (ord# c#)
38{-# INLINE ord #-}
40unsafeChr :: Word16 -> Char
41unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
42{-# INLINE unsafeChr #-}
44unsafeChr8 :: Word8 -> Char
45unsafeChr8 (W8# w#) = C# (chr# (word2Int# w#))
46{-# INLINE unsafeChr8 #-}
48unsafeChr32 :: Word32 -> Char
49unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
50{-# INLINE unsafeChr32 #-}
52-- | Write a character into the array at the given offset. Returns
53-- the number of 'Word16's written.
54unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
55unsafeWrite 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 #-}
75{-
76unsafeWriteRev :: A.MArray s Word16 -> Int -> Char -> ST s Int
77unsafeWriteRev 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-}