zip-stream 0.2.0.1 → 0.2.1.0
raw patch · 6 files changed
+24/−45 lines, 6 filesdep ~conduit
Dependency ranges changed: conduit
Files
- Codec/Archive/Zip/Conduit/Internal.hs +8/−16
- Codec/Archive/Zip/Conduit/Types.hs +1/−1
- Codec/Archive/Zip/Conduit/UnZip.hs +2/−10
- Codec/Archive/Zip/Conduit/Zip.hs +10/−15
- cmd/unzip.hs +1/−1
- zip-stream.cabal +2/−2
Codec/Archive/Zip/Conduit/Internal.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-} module Codec.Archive.Zip.Conduit.Internal ( osVersion, zipVersion@@ -21,13 +20,6 @@ import Codec.Archive.Zip.Conduit.Types -#if MIN_VERSION_conduit(1,3,0)-#define ConduitM ConduitT-#define PRE13(x)-#else-#define PRE13(x) x-#endif- -- | The version of this zip program, really just rough indicator of compatibility zipVersion :: Word8 zipVersion = 48@@ -39,32 +31,32 @@ zipError :: MonadThrow m => String -> m a zipError = throwM . ZipError -idConduit :: Monad m => C.ConduitM a a m ()+idConduit :: Monad m => C.ConduitT a a m () idConduit = C.awaitForever C.yield -passthroughFold :: Monad m => (a -> b -> a) -> a -> C.ConduitM b b m a+passthroughFold :: Monad m => (a -> b -> a) -> a -> C.ConduitT b b m a passthroughFold f !z = C.await >>= maybe (return z) (\x -> do C.yield x passthroughFold f (f z x)) -sizeCRC :: Monad m => C.ConduitM BS.ByteString BS.ByteString m (Word64, Word32)+sizeCRC :: Monad m => C.ConduitT BS.ByteString BS.ByteString m (Word64, Word32) sizeCRC = passthroughFold (\(!l, !c) b -> (l + fromIntegral (BS.length b), crc32Update c b)) (0, 0) -sizeC :: Monad m => C.ConduitM BS.ByteString BS.ByteString m Word64+sizeC :: Monad m => C.ConduitT BS.ByteString BS.ByteString m Word64 sizeC = passthroughFold (\l b -> l + fromIntegral (BS.length b)) 0 -- fst <$> sizeCRC -outputSize :: Monad m => C.ConduitM i BS.ByteString m () -> C.ConduitM i BS.ByteString m Word64+outputSize :: Monad m => C.ConduitT i BS.ByteString m () -> C.ConduitT i BS.ByteString m Word64 outputSize = (C..| sizeC) -inputSize :: Monad m => C.ConduitM BS.ByteString o m () -> C.ConduitM BS.ByteString o m Word64+inputSize :: Monad m => C.ConduitT BS.ByteString o m () -> C.ConduitT BS.ByteString o m Word64 -- inputSize = fuseUpstream sizeC -- won't work because we need to deal with leftovers properly-inputSize (CI.ConduitM src) = CI.ConduitM $ \rest -> let+inputSize (CI.ConduitT src) = CI.ConduitT $ \rest -> let go n (CI.Done ()) = rest n go n (CI.PipeM m) = CI.PipeM $ go n <$> m go n (CI.Leftover p b) = CI.Leftover (go (n - fromIntegral (BS.length b)) p) b- go n (CI.HaveOutput p PRE13(f) o) = CI.HaveOutput (go n p) PRE13(f) o+ go n (CI.HaveOutput p o) = CI.HaveOutput (go n p) o go n (CI.NeedInput p q) = CI.NeedInput (\b -> go (n + fromIntegral (BS.length b)) (p b)) (go n . q) in go 0 (src CI.Done)
Codec/Archive/Zip/Conduit/Types.hs view
@@ -32,7 +32,7 @@ data ZipEntry = ZipEntry { zipEntryName :: Either T.Text ByteString -- ^File name (in posix format, no leading slashes), either UTF-8 encoded text or raw bytes (CP437), with a trailing slash for directories , zipEntryTime :: LocalTime -- ^Modification time- , zipEntrySize :: Maybe Word64 -- ^Size of file data (if known); checked on zipping and also used as hint to enable zip64+ , zipEntrySize :: Maybe Word64 -- ^Size of file data (if known); checked on zipping and also used as hint to enable zip64. Disables compression for known 0-byte files. , zipEntryExternalAttributes :: Maybe Word32 -- ^Host-dependent attributes, often MS-DOS directory attribute byte (only supported when zipping) } deriving (Eq, Show)
Codec/Archive/Zip/Conduit/UnZip.hs view
@@ -1,5 +1,4 @@ -- |Stream the extraction of a zip file, e.g., as it's being downloaded.-{-# LANGUAGE CPP #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RankNTypes #-} module Codec.Archive.Zip.Conduit.UnZip@@ -10,9 +9,6 @@ import Control.Applicative ((<|>), empty) import Control.Monad (when, unless, guard)-#if !MIN_VERSION_conduit(1,3,0)-import Control.Monad.Base (MonadBase)-#endif import Control.Monad.Catch (MonadThrow) import Control.Monad.Primitive (PrimMonad) import qualified Data.Binary.Get as G@@ -20,7 +16,7 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC import qualified Data.Conduit as C-import qualified Data.Conduit.List as CL+import qualified Data.Conduit.Combinators as CC import Data.Conduit.Serialization.Binary (sinkGet) import qualified Data.Conduit.Zlib as CZ import qualified Data.Text as T@@ -101,11 +97,7 @@ -- Any errors are thrown in the underlying monad (as 'ZipError's or 'Data.Conduit.Serialization.Binary.ParseError'). unZipStream :: ( MonadThrow m-#if MIN_VERSION_conduit(1,3,0) , PrimMonad m-#else- , MonadBase b m, PrimMonad b-#endif ) => C.ConduitM BS.ByteString (Either ZipEntry BS.ByteString) m ZipInfo unZipStream = next where next = do -- local header, or start central directory@@ -132,7 +124,7 @@ } Just usize -> do -- known size (size, crc) <- pass fileCSize- C..| (fileDecompress >> CL.sinkNull)+ C..| (fileDecompress >> CC.sinkNull) C..| sizeCRC -- traceM $ "size=" ++ show size ++ "," ++ show (zipEntrySize fileEntry) ++ " crc=" ++ show crc ++ "," ++ show fileCRC -- optional data description (possibly ambiguous!)
Codec/Archive/Zip/Conduit/Zip.hs view
@@ -1,5 +1,4 @@ -- |Stream the creation of a zip file, e.g., as it's being uploaded.-{-# LANGUAGE CPP #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-} module Codec.Archive.Zip.Conduit.Zip@@ -15,9 +14,6 @@ import qualified Codec.Compression.Zlib.Raw as Z import Control.Arrow ((&&&), (+++), left) import Control.Monad (when)-#if !MIN_VERSION_conduit(1,3,0)-import Control.Monad.Base (MonadBase)-#endif import Control.Monad.Catch (MonadThrow) import Control.Monad.Primitive (PrimMonad) import Control.Monad.State.Strict (StateT, get)@@ -29,6 +25,7 @@ import qualified Data.ByteString.Lazy as BSL import qualified Data.Conduit as C import qualified Data.Conduit.Binary as CB+import qualified Data.Conduit.Combinators as CC import Data.Conduit.Lift (stateC, execStateC) import Data.Conduit.Serialization.Binary (sourcePut) import qualified Data.Conduit.Zlib as CZ@@ -46,7 +43,7 @@ -- |Options controlling zip file parameters and features data ZipOptions = ZipOptions { zipOpt64 :: Bool -- ^Allow 'ZipDataSource's over 4GB (reduces compatibility in some cases); this is automatically enabled for any files of known size (e.g., 'zipEntrySize')- , zipOptCompressLevel :: Int -- ^Compress (0 = store only, 9 = best) zipped files (improves compatibility, since some unzip programs don't supported stored, streamed files, including the one in this package)+ , zipOptCompressLevel :: Int -- ^Compress zipped files (0 = store only, 1 = minimal, 9 = best; non-zero improves compatibility, since some unzip programs don't supported stored, streamed files, including the one in this package) , zipOptInfo :: ZipInfo -- ^Other parameters to store in the zip file } @@ -64,9 +61,9 @@ True ?* x = x False ?* _ = 0 --- |Use a file on disk as 'ZipData' (@'ZipDataSource' . 'CB.sourceFile'@).+-- |Use a file on disk as 'ZipData' (@'ZipDataSource' . 'CC.sourceFile'@). zipFileData :: MonadResource m => FilePath -> ZipData m-zipFileData = ZipDataSource . CB.sourceFile+zipFileData = ZipDataSource . CC.sourceFile zipData :: Monad m => ZipData m -> Either (C.ConduitM () BS.ByteString m ()) BSL.ByteString zipData (ZipDataByteString b) = Right b@@ -77,7 +74,7 @@ dataSize (Right b) = Just $ fromIntegral $ BSL.length b toDOSTime :: LocalTime -> (Word16, Word16)-toDOSTime (LocalTime (toGregorian -> (year, month, day)) (TimeOfDay hour mins secs)) = +toDOSTime (LocalTime (toGregorian -> (year, month, day)) (TimeOfDay hour mins secs)) = ( fromIntegral hour `shiftL` 11 .|. fromIntegral mins `shiftL` 5 .|. truncate secs `shiftR` 1 , fromIntegral (year - 1980) `shiftL` 9 .|. fromIntegral month `shiftL` 5 .|. fromIntegral day )@@ -97,20 +94,16 @@ -- -- Depending on options, the resulting zip file should be compatible with most unzipping applications. -- Any errors are thrown in the underlying monad (as 'ZipError's).-zipStream :: +zipStream :: ( MonadThrow m-#if MIN_VERSION_conduit(1,3,0) , PrimMonad m-#else- , MonadBase b m, PrimMonad b-#endif ) => ZipOptions -> C.ConduitM (ZipEntry, ZipData m) BS.ByteString m Word64 zipStream ZipOptions{..} = execStateC 0 $ do (cnt, cdir) <- next 0 (return ()) cdoff <- get output cdir eoff <- get- endDirectory cdoff (eoff - cdoff) cnt + endDirectory cdoff (eoff - cdoff) cnt where next cnt dir = C.await >>= maybe (return (cnt, dir))@@ -120,7 +113,9 @@ entry (ZipEntry{..}, zipData -> dat) = do let usiz = dataSize dat sdat = left ((C..| sizeCRC) . C.toProducer) dat- comp = zipOptCompressLevel /= 0 && all (0 /=) usiz+ comp = zipOptCompressLevel /= 0+ && all (0 /=) usiz+ && all (0 /=) zipEntrySize (cdat, csiz) | comp = ( ((`C.fuseBoth` (outputSize $ CZ.compress zipOptCompressLevel deflateWindowBits))
cmd/unzip.hs view
@@ -52,7 +52,7 @@ unless (null args) $ do hPutStrLn stderr $ "Usage: " ++ prog ++ "\nRead a zip file from stdin and extract it in the current directory." exitFailure- ZipInfo{..} <- C.runConduit + ZipInfo{..} <- C.runConduit $ CB.sourceHandle stdin C..| C.fuseUpstream unZipStream extract BSC.putStrLn zipComment
zip-stream.cabal view
@@ -1,5 +1,5 @@ name: zip-stream-version: 0.2.0.1+version: 0.2.1.0 synopsis: ZIP archive streaming using conduits description: Process (extract and create) zip files as streams (e.g., over the network), accessing contained files without having to write the zip file to disk (unlike zip-conduit). license: BSD3@@ -29,7 +29,7 @@ binary >= 0.7.2, binary-conduit, bytestring,- conduit,+ conduit >= 1.3, conduit-extra, digest, exceptions,