packages feed

libarchive-conduit-0.1.0.0: src/Codec/Archive.hs

module Codec.Archive
       ( sourceArchive
       , ArchiveException(..)
       ) where

import Control.Monad (void)
import Control.Monad.IO.Class
import Control.Monad.Trans.Resource
import Data.ByteString (ByteString)
import Data.Conduit

import Codec.Archive.Read
import Codec.Archive.Util (ArchiveException(..))

-- | Stream an archive from disk as a 'Source' of paths in the archive and their
-- contents. The archive may be in any format supported by libarchive. The
-- contents of each file is presented as a strict 'ByteString' because
-- libarchive only supports streaming archives in order; if lazy 'ByteString's
-- were used, the evaluation order could become inconsistent. Throws an
-- 'ArchiveException' if an error occurs.
sourceArchive :: MonadResource m
              => FilePath  -- ^ path to archive
              -> Source m (FilePath, ByteString)
              -- ^ stream of paths in archive and their contents
sourceArchive path = bracketP (readArchive path) free go
  where
    free = void . archiveReadFree
    go p = do
        mentry <- liftIO $ getNextEntry p
        case mentry of
            Nothing -> return ()
            Just entry -> yield entry >> go p