@@ -1,36 +1,48 @@
11module Network.Wai.Zlib (compress) where
22
3−import Prelude
3+import Prelude hiding (head)
44import Network.Wai
55import Data.ByteString (ByteString)
6−import Data.Enumerator (Enumeratee)
7−import Blaze.ByteString.Builder (Builder)
6+import Data.Enumerator
7+ ( Enumeratee, checkDone, Stream (..), continue
8+ , (>>==), head, ($$), joinI
9+ )
10+import Blaze.ByteString.Builder (Builder, fromByteString)
11+import Blaze.ByteString.Builder.Enumerator (builderToByteString)
12+import Control.Monad.IO.Class (liftIO)
813
914import Codec.Zlib
1015
16+-- Note: this function really should return a stream of ByteStrings, but the
17+-- WAI protocol needs Builders anyway.
1118compress :: Enumeratee Builder Builder IO a
12−compress = undefined
13− {-
14− Enumerator $ \iter acc -> do
15− def <- initDeflate 7 $ WindowBits 31
16− compressInner iter acc enum def
19+compress step0 = joinI $ builderToByteString $$ do
20+ def <- liftIO $ initDeflate 7 $ WindowBits 31
21+ loop def step0
22+ where
23+ loop def = checkDone $ step def
24+ step def k = do
25+ minput <- head
26+ case minput of
27+ Nothing -> do
28+ bss <- liftIO $ finishDeflate def drain
29+ k (Chunks bss) >>== return
30+ Just input -> do
31+ bss <- liftIO $ withDeflateInput def input drain
32+ case bss of
33+ [] -> step def k
34+ _ -> k (Chunks bss) >>== loop def
1735
18−compressInner :: (acc -> ByteString -> IO (Either acc acc))
19− -> acc
20− -> Enumerator
21− -> Deflate
22− -> IO (Either acc acc)
23−compressInner iter acc enum def = do
24− eacc <- runEnumerator enum (compressIter iter def) acc
25− case eacc of
26− Left acc' -> return $ Left acc'
27− Right acc' -> finishStream iter def acc'
36+drain =
37+ go id
38+ where
39+ go front mbs' = do
40+ mbs <- mbs'
41+ case mbs of
42+ Nothing -> return $ map fromByteString $ front []
43+ Just bs -> go (front . (:) bs) mbs'
2844
29−finishStream :: (acc -> ByteString -> IO (Either acc acc))
30− -> Deflate
31− -> acc
32− -> IO (Either acc acc)
33−finishStream iter def acc = finishDeflate def $ drain iter acc
45+ {-
3446
3547compressIter :: (acc -> ByteString -> IO (Either acc acc))
3648 -> Deflate