module ForeignHash ( foreignFileHash ) where
import Data.Coerce (coerce)
import Data.Word (Word64)
import Foreign.C.String (CString, withCString)
import Foreign.C.Types (CInt (..), CULLong (..))
import Foreign.Marshal.Alloc (alloca)
import Foreign.Ptr (Ptr)
import Foreign.Storable (peek)
foreign import ccall ph_dct_imagehash :: CString -> Ptr CULLong -> IO CInt
foreignFileHash :: FilePath -> IO Word64
foreignFileHash :: FilePath -> IO Word64
foreignFileHash FilePath
fp = forall a. FilePath -> (CString -> IO a) -> IO a
withCString FilePath
fp forall a b. (a -> b) -> a -> b
$ \CString
cstr ->
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \Ptr CULLong
hashPtr -> do
CInt
res <- CString -> Ptr CULLong -> IO CInt
ph_dct_imagehash CString
cstr Ptr CULLong
hashPtr
forall {a} {f :: * -> *}. (Eq a, Num a, Applicative f) => a -> f ()
check CInt
res
coerce :: forall a b. Coercible a b => a -> b
coerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> IO a
peek Ptr CULLong
hashPtr
where check :: a -> f ()
check (-1) = forall a. HasCallStack => FilePath -> a
error (FilePath
"Hash of file " forall a. [a] -> [a] -> [a]
++ FilePath
fp forall a. [a] -> [a] -> [a]
++ FilePath
" failed.")
check a
0 = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
check a
_ = forall a. HasCallStack => FilePath -> a
error FilePath
"This should never happen."