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