on master help sign in
Refactor writing a Char into an A.MArray s Word16

--HG-- extra : convert_revision : c585b4f64759a222c96b87572eeead06b400f1ad

commit27debf3e6a6c0deddb97a9a14d8f666148b02de5 authorBryan O'Sullivan <bos@serpentine.com> dateFri 13 Feb 2009, 06:48 (18 years ago) parent98a26cb
2 files changed+27−19
Data/Text/Fusion.hs+6−18 Data/Text/UnsafeChar.hs+21−1
Data/Text/Fusion.hs+6−18
@@ -111,7 +111,7 @@ import qualified Data.List as L
111111import Data.Word (Word16)
112112import GHC.Exts (Int(..), (+#))
113113import Data.Text.Internal (Text(..))
114−import Data.Text.UnsafeChar (unsafeChr)
114+import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
115115import qualified Data.Text.Array as A
116116import qualified Data.Text.Internal as I
117117import qualified Data.Text.Utf16 as U16
@@ -149,29 +149,17 @@ unstream :: Stream Char -> Text
149149unstream (Stream _next0 _s0 0) = I.empty
150150unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
151151 where
152− a = runST (A.unsafeNew len >>= (\arr -> loop arr 0 len s0))
153− loop arr !i !top !s
152+ a = runST (A.unsafeNew len >>= (\arr -> loop arr len s0 0))
153+ loop arr !top !s !i
154154 | i + 1 >= top = case next0 s of
155155 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
156156 _ -> do
157157 arr' <- A.unsafeNew (top*2)
158− copy arr arr' >> loop arr' i (top*2) s
158+ copy arr arr' >> loop arr' (top*2) s i
159159 | otherwise = case next0 s of
160160 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
161− Skip s' -> loop arr i top s'
162− Yield x s'
163− | n < 0x10000 -> do
164− A.unsafeWrite arr i (fromIntegral n)
165− loop arr (i+1) top s'
166− | otherwise -> do
167− A.unsafeWrite arr i l
168− A.unsafeWrite arr (i + 1) r
169− loop arr (i+2) top s'
170− where
171− n = ord x
172− m = n - 0x10000
173− l = fromIntegral $ (m `shiftR` 10) + 0xD800
174− r = fromIntegral $ (m .&. 0x3FF) + 0xDC00
161+ Skip s' -> loop arr top s' i
162+ Yield x s' -> unsafeWrite arr i x >>= loop arr top s'
175163{-# INLINE [0] unstream #-}
176164{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
177165
Data/Text/UnsafeChar.hs+21−1
@@ -12,16 +12,21 @@
1212-- Stability : experimental
1313-- Portability : GHC
1414--
15−-- Fast character manipulation function.
15+-- Fast character manipulation functions.
1616module Data.Text.UnsafeChar
1717 (
1818 unsafeChr
1919 , unsafeChr8
2020 , unsafeChr32
21+ , unsafeWrite
2122 ) where
2223
24+import Control.Monad.ST (ST)
25+import Data.Bits ((.&.), shiftR)
26+import Data.Char (ord)
2327import GHC.Exts (Char(..), chr#, word2Int#)
2428import GHC.Word (Word8(..), Word16(..), Word32(..))
29+import qualified Data.Text.Array as A
2530
2631unsafeChr :: Word16 -> Char
2732unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
@@ -34,3 +39,18 @@ unsafeChr8 (W8# w#) = C# (chr# (word2Int# w#))
3439unsafeChr32 :: Word32 -> Char
3540unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
3641{-# INLINE unsafeChr32 #-}
42+
43+unsafeWrite :: A.MArray s Word16 -> Int -> Char -> ST s Int
44+unsafeWrite marr i c
45+ | n < 0x10000 = do
46+ A.unsafeWrite marr i (fromIntegral n)
47+ return (i+1)
48+ | otherwise = do
49+ A.unsafeWrite marr i l
50+ A.unsafeWrite marr (i+1) r
51+ return (i+2)
52+ where n = ord c
53+ m = n - 0x10000
54+ l = fromIntegral $ (m `shiftR` 10) + 0xD800
55+ r = fromIntegral $ (m .&. 0x3FF) + 0xDC00
56+{-# INLINE unsafeWrite #-}