{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Hash.Class.Pure.Salted
( Hash(..)
, IncrementalHash(..)
, hashPtr
, hashStorable
, hashByteString
, hashByteStringLazy
, hashShortByteString
, hashByteArray
, updateByteString
, updateByteStringLazy
, updateShortByteString
, updateStorable
, updateByteArray
) where
import Control.Monad
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Short as BS
import Data.Kind
import Data.Word
import Foreign.Ptr
import Foreign.Storable
import GHC.Exts
import Data.Hash.Class.Pure.Internal
class IncrementalHash a => Hash a where
type Salt a :: Type
initialize :: Salt a -> Context a
hashPtr :: forall a. Hash a => Salt a -> Ptr Word8 -> Int -> IO a
hashPtr :: Salt a -> Ptr Word8 -> Int -> IO a
hashPtr Salt a
k Ptr Word8
p Int
n = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> IO (Context a) -> IO a
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Context a -> Ptr Word8 -> Int -> IO (Context a)
forall a.
IncrementalHash a =>
Context a -> Ptr Word8 -> Int -> IO (Context a)
update @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) Ptr Word8
p Int
n
{-# INLINE hashPtr #-}
hashByteString :: forall a . Hash a => Salt a -> B.ByteString -> a
hashByteString :: Salt a -> ByteString -> a
hashByteString Salt a
k ByteString
b = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> Context a -> a
forall a b. (a -> b) -> a -> b
$! Context a -> ByteString -> Context a
forall a. IncrementalHash a => Context a -> ByteString -> Context a
updateByteString @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) ByteString
b
{-# INLINE hashByteString #-}
hashByteStringLazy :: forall a . Hash a => Salt a -> BL.ByteString -> a
hashByteStringLazy :: Salt a -> ByteString -> a
hashByteStringLazy Salt a
k ByteString
b = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> Context a -> a
forall a b. (a -> b) -> a -> b
$! Context a -> ByteString -> Context a
forall a. IncrementalHash a => Context a -> ByteString -> Context a
updateByteStringLazy @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) ByteString
b
{-# INLINE hashByteStringLazy #-}
hashShortByteString :: forall a . Hash a => Salt a -> BS.ShortByteString -> a
hashShortByteString :: Salt a -> ShortByteString -> a
hashShortByteString Salt a
k ShortByteString
b = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> Context a -> a
forall a b. (a -> b) -> a -> b
$! Context a -> ShortByteString -> Context a
forall a.
IncrementalHash a =>
Context a -> ShortByteString -> Context a
updateShortByteString @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) ShortByteString
b
{-# INLINE hashShortByteString #-}
hashStorable :: forall a b . Hash a => Storable b => Salt a -> b -> a
hashStorable :: Salt a -> b -> a
hashStorable Salt a
k b
b = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> Context a -> a
forall a b. (a -> b) -> a -> b
$! Context a -> b -> Context a
forall a b.
(IncrementalHash a, Storable b) =>
Context a -> b -> Context a
updateStorable @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) b
b
{-# INLINE hashStorable #-}
hashByteArray :: forall a . Hash a => Salt a -> ByteArray# -> a
hashByteArray :: Salt a -> ByteArray# -> a
hashByteArray Salt a
k ByteArray#
b = Context a -> a
forall a. IncrementalHash a => Context a -> a
finalize (Context a -> a) -> Context a -> a
forall a b. (a -> b) -> a -> b
$! Context a -> ByteArray# -> Context a
forall a. IncrementalHash a => Context a -> ByteArray# -> Context a
updateByteArray @a (Salt a -> Context a
forall a. Hash a => Salt a -> Context a
initialize @a Salt a
k) ByteArray#
b
{-# INLINE hashByteArray #-}