gearhash-1.0.0: src/Data/Digest/GearHash/Conduit.hs
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Digest.GearHash.Conduit
( GearHashTable
, mkGearHashTable
, rollingHash, rollingHashWith, defaultGearHashTable, defaultGearHashTableFor
, rollingHash', rollingHashWith'
, BitVector
) where
import Prelude
import Data.Conduit
import Data.Conduit.Combinators (chunksOfE, yieldMany)
import Data.Digest.GearHash
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import Data.Monoid (Endo(..))
rollingHashWith' :: forall m acc.
( Monad m
, Monoid acc
)
=> (BitVector -> acc)
-> GearHashTable
-> ConduitT ByteString acc m ()
rollingHashWith' toAcc tbl = chunksOfE 128 .| go (hashInitWith tbl)
where
go hState = do
chunk' <- await
case chunk' of
Nothing -> return ()
Just chunk -> do
let (hState', acc) = ByteString.foldl' go' (hState, mempty) chunk
yield acc
go hState'
go' (hState, acc) w = out `seq` (hState', acc <> toAcc out)
where hState' = hashUpdate w hState
out = hashFinalize hState'
rollingHash' :: forall m acc.
( Monad m
, Monoid acc
)
=> (BitVector -> acc)
-> ConduitT ByteString acc m ()
rollingHash' = flip rollingHashWith' defaultGearHashTable
rollingHashWith :: forall m.
Monad m
=> GearHashTable
-> ConduitT ByteString BitVector m ()
rollingHashWith tbl = rollingHashWith' (Endo . (:)) tbl .| awaitForever (yieldMany . flip appEndo [])
rollingHash :: forall m.
Monad m
=> ConduitT ByteString BitVector m ()
rollingHash = rollingHashWith defaultGearHashTable