import Codec.Compression.Zlib(ZlibDecoder(..), decompressIncremental) import Control.Monad(unless) import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L import Data.List(isSuffixOf) import Prelude hiding (readFile, writeFile) import System.Environment(getArgs) import System.IO(IOMode(..), Handle, openFile, hClose) main :: IO () main = do args <- getArgs case args of [ifile] -> if ".z" `isSuffixOf` ifile then do bstr <- L.readFile ifile let outname = take (length ifile - 2) ifile hndl <- openFile outname WriteMode runDecompression hndl (L.toChunks bstr) decompressIncremental else putStrLn "Unexpected file name." _ -> putStrLn "USAGE: deflate [filename]" runDecompression :: Handle -> [S.ByteString] -> ZlibDecoder -> IO () runDecompression hndl ls decoder = case decoder of Done -> do unless (null ls) $ putStrLn "WARNING: Finished decompression with data left." hClose hndl DecompError e -> do putStrLn ("ERROR: " ++ show e) hClose hndl NeedMore f | (x:rest) <- ls -> runDecompression hndl rest (f x) | otherwise -> do putStrLn "ERROR: Ran out of data mid-decompression." hClose hndl Chunk c m -> do L.hPut hndl c runDecompression hndl ls m