11{-# LANGUAGE CPP, RankNTypes, DeriveDataTypeable, BangPatterns #-}
22{-# LANGUAGE DeriveGeneric #-}
33{-# LANGUAGE Trustworthy #-}
4+ {-# LANGUAGE LambdaCase #-}
5+ {-# LANGUAGE ScopedTypeVariables #-}
46-----------------------------------------------------------------------------
57-- |
68-- Copyright : (c) 2006-2015 Duncan Coutts
@@ -15,7 +17,9 @@ module Codec.Compression.Zlib.Internal (
1517
1618 -- * Pure interface
1719 compress ,
20+ compressFromHandle ,
1821 decompress ,
22+ decompressFromHandle ,
1923
2024 -- * Monadic incremental interface
2125 -- $incremental-compression
@@ -75,8 +79,8 @@ module Codec.Compression.Zlib.Internal (
7579 ) where
7680
7781import Prelude hiding (length )
78- import Control.Monad (when )
79- import Control.Exception (Exception , throw , assert )
82+ import Control.Monad (when , (>=>) )
83+ import Control.Exception (Exception , throw , assert , throwIO )
8084import Control.Monad.ST.Lazy hiding (stToIO )
8185import Control.Monad.ST.Strict (stToIO )
8286import qualified Control.Monad.ST.Unsafe as Unsafe (unsafeIOToST )
@@ -95,6 +99,8 @@ import GHC.IO (noDuplicate)
9599import qualified Codec.Compression.Zlib.Stream as Stream
96100import Codec.Compression.Zlib.ByteStringCompat (mkBS , withBS )
97101import Codec.Compression.Zlib.Stream (Stream )
102+ import System.IO (Handle , hIsSeekable , hSeek , SeekMode (.. ))
103+ import Data.ByteString.Builder.Extra (defaultChunkSize )
98104
99105-- | The full set of parameters for compression. The defaults are
100106-- 'defaultCompressParams'.
@@ -487,6 +493,32 @@ compress format params = foldCompressStreamWithInput
487493compressST format params = compressStreamST format params
488494compressIO format params = compressStreamIO format params
489495
496+ compressFromHandle
497+ :: forall acc .
498+ Stream. Format
499+ -> CompressParams
500+ -> Handle
501+ -> (acc -> S. ByteString -> IO acc )
502+ -> acc
503+ -> IO acc
504+ compressFromHandle format params hndl cons nil = go nil (compressStreamIO format params)
505+ where
506+ go :: acc -> CompressStream IO -> IO acc
507+ go ! acc = \ case
508+ CompressInputRequired next ->
509+ S. hGetSome hndl defaultChunkSize >>= next >>= go acc
510+ CompressOutputAvailable outchunk next -> do
511+ acc' <- acc `cons` outchunk
512+ next >>= go acc'
513+ CompressStreamEnd ->
514+ pure acc
515+
516+ -- foldCompressStream
517+ -- (S.hGetSome hndl defaultChunkSize >>=)
518+ -- undefined -- (fmap . L.chunk)
519+ -- (pure L.empty)
520+ -- (compressStreamIO format params)
521+
490522-- | Chunk size must fit into t'CUInt'.
491523compressStream :: Stream. Format -> CompressParams -> S. ByteString
492524 -> Stream (CompressStream Stream )
@@ -621,6 +653,19 @@ decompress format params = foldDecompressStreamWithInput
621653decompressST format params = decompressStreamST format params
622654decompressIO format params = decompressStreamIO format params
623655
656+ decompressFromHandle :: Stream. Format -> DecompressParams -> Handle -> IO L. ByteString
657+ decompressFromHandle format params hndl = foldDecompressStream
658+ (S. hGetSome hndl defaultChunkSize >>= )
659+ (fmap . L. chunk)
660+ (\ unconsumed -> do
661+ isSeekable <- hIsSeekable hndl
662+ when isSeekable $
663+ hSeek hndl RelativeSeek (toInteger $ S. length unconsumed)
664+ pure L. empty
665+ )
666+ throwIO
667+ (decompressStreamIO format params)
668+
624669-- | Chunk size must fit into t'CUInt'.
625670decompressStream :: Stream. Format -> DecompressParams
626671 -> Bool -> S. ByteString
0 commit comments