on master help sign in
Remove more duplicated Builder code
3edced1Bryan O'Sullivan
Data/Text/Fusion.hs+2−1
@@ -106,7 +106,8 @@ unstream (Stream next0 s0 len) = I.textP (P.fst a) 0 (P.snd a)
106 let top' = (top + 1) `shiftL` 1
106 let top' = (top + 1) `shiftL` 1
107 arr' <- A.unsafeNew top'
107 arr' <- A.unsafeNew top'
108 A.copy arr' arr >> outer arr' top' s i
108 A.copy arr' arr >> outer arr' top' s i
109− | otherwise -> unsafeWrite arr i x >>= loop s'
109+ | otherwise -> do d <- unsafeWrite arr i x
110+ loop s' (i+d)
110 where j | ord x < 0x10000 = i
111 where j | ord x < 0x10000 = i
111 | otherwise = i + 1
112 | otherwise = i + 1
112{-# INLINE [0] unstream #-}
113{-# INLINE [0] unstream #-}
Data/Text/Lazy/Builder.hs+1−24
@@ -34,11 +34,11 @@ import Control.Exception (assert)
34#endif
34#endif
35import Control.Monad.ST (ST, runST)
35import Control.Monad.ST (ST, runST)
36import Data.Bits ((.&.))
36import Data.Bits ((.&.))
37−import Data.Char (ord)
38import Data.Monoid (Monoid(..))
37import Data.Monoid (Monoid(..))
39import Data.Text.Internal (Text(..))
38import Data.Text.Internal (Text(..))
40import Data.Text.Lazy.Internal (smallChunkSize)
39import Data.Text.Lazy.Internal (smallChunkSize)
41import Data.Text.Unsafe (inlineInterleaveST)
40import Data.Text.Unsafe (inlineInterleaveST)
41+import Data.Text.UnsafeChar (ord, unsafeWrite)
42import Data.Text.UnsafeShift (shiftR)
42import Data.Text.UnsafeShift (shiftR)
43import Prelude hiding (map, putChar)
43import Prelude hiding (map, putChar)
44
44
@@ -258,29 +258,6 @@ newBuffer size = do
258 return $! Buffer arr 0 0 size
258 return $! Buffer arr 0 0 size
259{-# INLINE newBuffer #-}
259{-# INLINE newBuffer #-}
260
260
261−-- Write a character to the array, starting at the specified offset
262−-- @i@. Returns the number of elements written.
263−unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
264−unsafeWrite marr i c
265− | n < 0x10000 = do
266−#if defined(ASSERTS)
267− assert (i >= 0) . assert (i < A.length marr) $ return ()
268−#endif
269− A.unsafeWrite marr i (fromIntegral n)
270− return 1
271− | otherwise = do
272−#if defined(ASSERTS)
273− assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
274−#endif
275− A.unsafeWrite marr i lo
276− A.unsafeWrite marr (i+1) hi
277− return 2
278− where n = ord c
279− m = n - 0x10000
280− lo = fromIntegral $ (m `shiftR` 10) + 0xD800
281− hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
282−{-# INLINE unsafeWrite #-}
283−
284------------------------------------------------------------------------
261------------------------------------------------------------------------
285-- Some nice rules for Builder
262-- Some nice rules for Builder
286
263
Data/Text/Lazy/Fusion.hs+5−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE BangPatterns #-}
1-- |
2-- |
2-- Module : Data.Text.Lazy.Fusion
3-- Module : Data.Text.Lazy.Fusion
3-- Copyright : (c) 2009, 2010 Bryan O'Sullivan
4-- Copyright : (c) 2009, 2010 Bryan O'Sullivan
@@ -59,10 +60,9 @@ unstreamChunks chunkSize (Stream next s0 len0)
59 Yield x s' -> I.Text arr 0 len `chunk` outer s''
60 Yield x s' -> I.Text arr 0 len `chunk` outer s''
60 where (arr,(s'',len)) = A.run2 fill
61 where (arr,(s'',len)) = A.run2 fill
61 fill = do a <- A.unsafeNew unknownLength
62 fill = do a <- A.unsafeNew unknownLength
62− i <- unsafeWrite a 0 x
63− inner a unknownLength s' i
63+ unsafeWrite a 0 x >>= inner a unknownLength s'
64 unknownLength = 4
64 unknownLength = 4
65− inner marr len s i
65+ inner marr len s !i
66 | i + 1 >= chunkSize = return (marr, (s,i))
66 | i + 1 >= chunkSize = return (marr, (s,i))
67 | i + 1 >= len = do
67 | i + 1 >= len = do
68 let newLen = min (len `shiftL` 1) chunkSize
68 let newLen = min (len `shiftL` 1) chunkSize
@@ -73,7 +73,8 @@ unstreamChunks chunkSize (Stream next s0 len0)
73 case next s of
73 case next s of
74 Done -> return (marr,(s,i))
74 Done -> return (marr,(s,i))
75 Skip s' -> inner marr len s' i
75 Skip s' -> inner marr len s' i
76− Yield x s' -> unsafeWrite marr i x >>= inner marr len s'
76+ Yield x s' -> do d <- unsafeWrite marr i x
77+ inner marr len s' (i+d)
77{-# INLINE [0] unstreamChunks #-}
78{-# INLINE [0] unstreamChunks #-}
78
79
79-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using
80-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using
Data/Text/UnsafeChar.hs+4−2
@@ -49,6 +49,8 @@ unsafeChr32 :: Word32 -> Char
49unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
49unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
50{-# INLINE unsafeChr32 #-}
50{-# INLINE unsafeChr32 #-}
51
51
52+-- | Write a character into the array at the given offset. Returns
53+-- the number of 'Word16's written.
52unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
54unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
53unsafeWrite marr i c
55unsafeWrite marr i c
54 | n < 0x10000 = do
56 | n < 0x10000 = do
@@ -56,14 +58,14 @@ unsafeWrite marr i c
56 assert (i >= 0) . assert (i < A.length marr) $ return ()
58 assert (i >= 0) . assert (i < A.length marr) $ return ()
57#endif
59#endif
58 A.unsafeWrite marr i (fromIntegral n)
60 A.unsafeWrite marr i (fromIntegral n)
59− return $! i+1
61+ return 1
60 | otherwise = do
62 | otherwise = do
61#if defined(ASSERTS)
63#if defined(ASSERTS)
62 assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
64 assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
63#endif
65#endif
64 A.unsafeWrite marr i lo
66 A.unsafeWrite marr i lo
65 A.unsafeWrite marr (i+1) hi
67 A.unsafeWrite marr (i+1) hi
66− return $! i+2
68+ return 2
67 where n = ord c
69 where n = ord c
68 m = n - 0x10000
70 m = n - 0x10000
69 lo = fromIntegral $ (m `shiftR` 10) + 0xD800
71 lo = fromIntegral $ (m `shiftR` 10) + 0xD800