on master help sign in
Remove more duplicated Builder code

This time, I also changed the return value from UnsafeChar.unsafeWrite to return the number of Word16 values written, instead of the next offset in the array to use. --HG-- extra : convert_revision : 4f794c2ff14d267b2e85c7224d6fb07af550276b

commit3edced17ba66dacfdd83fb9bb81ba4ec59056421 authorBryan O'Sullivan <bos@serpentine.com> dateMon 16 Aug 2010, 01:28 (16 years ago) parent7f16bfa
4 files changed+12−31
Data/Text/Fusion.hs+2−1 Data/Text/Lazy/Builder.hs+1−24 Data/Text/Lazy/Fusion.hs+5−4 Data/Text/UnsafeChar.hs+4−2
Data/Text/Fusion.hs+2−1
@@ -106,7 +106,8 @@ unstream (Stream next0 s0 len) = I.textP (P.fst a) 0 (P.snd a)
106106 let top' = (top + 1) `shiftL` 1
107107 arr' <- A.unsafeNew top'
108108 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)
110111 where j | ord x < 0x10000 = i
111112 | otherwise = i + 1
112113{-# INLINE [0] unstream #-}
Data/Text/Lazy/Builder.hs+1−24
@@ -34,11 +34,11 @@ import Control.Exception (assert)
3434#endif
3535import Control.Monad.ST (ST, runST)
3636import Data.Bits ((.&.))
37−import Data.Char (ord)
3837import Data.Monoid (Monoid(..))
3938import Data.Text.Internal (Text(..))
4039import Data.Text.Lazy.Internal (smallChunkSize)
4140import Data.Text.Unsafe (inlineInterleaveST)
41+import Data.Text.UnsafeChar (ord, unsafeWrite)
4242import Data.Text.UnsafeShift (shiftR)
4343import Prelude hiding (map, putChar)
4444
@@ -258,29 +258,6 @@ newBuffer size = do
258258 return $! Buffer arr 0 0 size
259259{-# INLINE newBuffer #-}
260260
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−
284261------------------------------------------------------------------------
285262-- Some nice rules for Builder
286263
Data/Text/Lazy/Fusion.hs+5−4
@@ -1,3 +1,4 @@
1+{-# LANGUAGE BangPatterns #-}
12-- |
23-- Module : Data.Text.Lazy.Fusion
34-- Copyright : (c) 2009, 2010 Bryan O'Sullivan
@@ -59,10 +60,9 @@ unstreamChunks chunkSize (Stream next s0 len0)
5960 Yield x s' -> I.Text arr 0 len `chunk` outer s''
6061 where (arr,(s'',len)) = A.run2 fill
6162 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'
6464 unknownLength = 4
65− inner marr len s i
65+ inner marr len s !i
6666 | i + 1 >= chunkSize = return (marr, (s,i))
6767 | i + 1 >= len = do
6868 let newLen = min (len `shiftL` 1) chunkSize
@@ -73,7 +73,8 @@ unstreamChunks chunkSize (Stream next s0 len0)
7373 case next s of
7474 Done -> return (marr,(s,i))
7575 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)
7778{-# INLINE [0] unstreamChunks #-}
7879
7980-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using
Data/Text/UnsafeChar.hs+4−2
@@ -49,6 +49,8 @@ unsafeChr32 :: Word32 -> Char
4949unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
5050{-# INLINE unsafeChr32 #-}
5151
52+-- | Write a character into the array at the given offset. Returns
53+-- the number of 'Word16's written.
5254unsafeWrite :: A.MArray s -> Int -> Char -> ST s Int
5355unsafeWrite marr i c
5456 | n < 0x10000 = do
@@ -56,14 +58,14 @@ unsafeWrite marr i c
5658 assert (i >= 0) . assert (i < A.length marr) $ return ()
5759#endif
5860 A.unsafeWrite marr i (fromIntegral n)
59− return $! i+1
61+ return 1
6062 | otherwise = do
6163#if defined(ASSERTS)
6264 assert (i >= 0) . assert (i < A.length marr - 1) $ return ()
6365#endif
6466 A.unsafeWrite marr i lo
6567 A.unsafeWrite marr (i+1) hi
66− return $! i+2
68+ return 2
6769 where n = ord c
6870 m = n - 0x10000
6971 lo = fromIntegral $ (m `shiftR` 10) + 0xD800