@@ -1,8 +1,6 @@
2-- Module : Data.Text.Lazy.Fusion
2-- Module : Data.Text.Lazy.Fusion
3−-- Copyright : (c) Tom Harper 2008-2009,
4−-- (c) Bryan O'Sullivan 2009,
3+-- Copyright : (c) Bryan O'Sullivan 2009
5−-- (c) Duncan Coutts 2009
7-- License : BSD-style
5-- License : BSD-style
8-- Maintainer : rtharper@aftereternity.co.uk, bos@serpentine.com,
6-- Maintainer : rtharper@aftereternity.co.uk, bos@serpentine.com,
@@ -16,6 +14,7 @@ module Data.Text.Lazy.Fusion
18 , unstream
16 , unstream
21import Data.Text.Fusion.Internal
20import Data.Text.Fusion.Internal
@@ -28,6 +27,7 @@ import Data.Text.Unsafe (iter)
29default(Int)
28default(Int)
30+-- | /O(n)/ Convert a 'Text' into a 'Stream Char'.
31stream :: Text -> Stream Char
31stream :: Text -> Stream Char
32stream text = Stream next (text :!: 0) 4
32stream text = Stream next (text :!: 0) 4
@@ -38,23 +38,25 @@ stream text = Stream next (text :!: 0) 4
38 where (c,d) = iter t i
38 where (c,d) = iter t i
39{-# INLINE [0] stream #-}
39{-# INLINE [0] stream #-}
41+-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
41−unstream :: Stream Char -> Text
43+unstreamChunks :: Int -> Stream Char -> Text
42−unstream (Stream next s0 len0)
44+unstreamChunks chunkSize (Stream next s0 len0)
43 | len0 == 0 = Empty
45 | len0 == 0 = Empty
44 | otherwise = outer s0
46 | otherwise = outer s0
46 outer s = case next s of
48 outer s = case next s of
47− Done -> Empty
49+ Done -> Empty
48− Skip s' -> outer s'
50+ Skip s' -> outer s'
49− Yield x s' -> chunk t (outer s'')
51+ Yield x s' -> I.Text arr 0 len `chunk` outer s''
50− where (t,s'') = fill x s'
52+ where (arr,(s'',len)) = A.run2 fill
51− fill x s = (I.Text a 0 l,s')
53+ fill = do arr <- A.unsafeNew unknownLength
52− where (a,(s',l)) = A.run2 (A.unsafeNew initLen >>= (\arr -> inner arr initLen x s 0))
54+ inner arr unknownLength x s' 0
53− initLen = 8
55+ unknownLength = 4
54 inner marr len x s i
56 inner marr len x s i
55− | i + 1 >= defaultChunkSize = return (marr, (s,i))
57+ | i + 1 >= chunkSize = return (marr, (s,i))
56− | i + 1 >= len = do
58+ | i + 1 >= len = do
57− let newLen = min (len * 2) defaultChunkSize
59+ let newLen = min (len * 2) chunkSize
58 marr' <- A.unsafeNew newLen
60 marr' <- A.unsafeNew newLen
59 A.copy marr marr'
61 A.copy marr marr'
60 inner marr' newLen x s i
62 inner marr' newLen x s i
@@ -64,5 +66,12 @@ unstream (Stream next s0 len0)
64 return (marr,(s,i'))
66 return (marr,(s,i'))
65 Skip s' -> inner marr len x s i
67 Skip s' -> inner marr len x s i
66 Yield x' s' -> unsafeWrite marr i x >>= inner marr len x' s'
68 Yield x' s' -> unsafeWrite marr i x >>= inner marr len x' s'
69+{-# INLINE [0] unstreamChunks #-}
71+-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using
72+-- 'defaultChunkSize'.
73+unstream :: Stream Char -> Text
74+unstream = unstreamChunks defaultChunkSize
67{-# INLINE [0] unstream #-}
75{-# INLINE [0] unstream #-}
68{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
77{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}