@@ -24,6 +24,7 @@ module Data.Text.Lazy.Fusion
25import Prelude hiding (length)
25import Prelude hiding (length)
26import qualified Data.Text.Fusion.Common as S
26import qualified Data.Text.Fusion.Common as S
27+import Control.Monad.ST (runST)
27import Data.Text.Fusion.Internal
28import Data.Text.Fusion.Internal
28import Data.Text.Fusion.Size (isEmpty, unknownSize)
29import Data.Text.Fusion.Size (isEmpty, unknownSize)
29import Data.Text.Lazy.Internal
30import Data.Text.Lazy.Internal
@@ -47,7 +48,7 @@ stream text = Stream next (text :*: 0) unknownSize
47 where Iter c d = iter t i
48 where Iter c d = iter t i
48{-# INLINE [0] stream #-}
49{-# INLINE [0] stream #-}
50−data UC s = UC s {-# UNPACK #-} !Int
51+data UC s = UC I.Text s
52-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
53-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
53-- chunk size.
54-- chunk size.
@@ -60,13 +61,17 @@ unstreamChunks !chunkSize (Stream next s0 len0)
60 case next s of
61 case next s of
61 Done -> Empty
62 Done -> Empty
62 Skip s' -> outer s'
63 Skip s' -> outer s'
63− Yield x s' -> I.Text arr 0 len `chunk` outer s''
64+ Yield x s' -> t `chunk` outer s''
64− where (arr, UC s'' len) = A.run2 fill
65+ where UC t s'' = runST fill
65 fill = do a <- A.new unknownLength
66 fill = do a <- A.new unknownLength
66 unsafeWrite a 0 x >>= inner a unknownLength s'
67 unsafeWrite a 0 x >>= inner a unknownLength s'
67 unknownLength = 4
68 unknownLength = 4
69+ finish marr len s = do
70+ arr <- A.unsafeFreeze marr
71+ let !t = I.Text arr 0 len
68 inner marr !len s !i
73 inner marr !len s !i
69− | i + 1 >= chunkSize = return (marr, UC s i)
74+ | i + 1 >= chunkSize = finish marr i s
70 | i + 1 >= len = {-# SCC "unstreamChunks/resize" #-} do
75 | i + 1 >= len = {-# SCC "unstreamChunks/resize" #-} do
71 let newLen = min (len `shiftL` 1) chunkSize
76 let newLen = min (len `shiftL` 1) chunkSize
72 marr' <- A.new newLen
77 marr' <- A.new newLen
@@ -75,7 +80,7 @@ unstreamChunks !chunkSize (Stream next s0 len0)
75 | otherwise =
80 | otherwise =
76 {-# SCC "unstreamChunks/inner" #-}
81 {-# SCC "unstreamChunks/inner" #-}
77 case next s of
82 case next s of
78− Done -> return (marr, UC s i)
83+ Done -> finish marr i s
79 Skip s' -> inner marr len s' i
84 Skip s' -> inner marr len s' i
80 Yield x s' -> do d <- unsafeWrite marr i x
85 Yield x s' -> do d <- unsafeWrite marr i x
81 inner marr len s' (i+d)
86 inner marr len s' (i+d)