    -- |
    -- Module      : Crypto.Internal.ByteArray
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : stable
    -- Portability : Good
    --
    -- Simple and efficient byte array types
    --
    {-# LANGUAGE BangPatterns #-}
    {-# OPTIONS_HADDOCK hide #-}
    module Crypto.Internal.ByteArray
        ( module Data.ByteArray
        , module Data.ByteArray.Mapping
        , module Data.ByteArray.Encoding
        , constAllZero
        ) where

    import Data.ByteArray
    import Data.ByteArray.Mapping
    import Data.ByteArray.Encoding

    import Data.Bits ((.|.))
    import Data.Word (Word8)
    import Foreign.Ptr (Ptr)
    import Foreign.Storable (peekByteOff)

    import Crypto.Internal.Compat (unsafeDoIO)

    constAllZero :: ByteArrayAccess ba => ba -> Bool
    constAllZero :: forall ba. ByteArrayAccess ba => ba -> Bool
    constAllZero ba
    b = IO Bool -> Bool
    forall a. IO a -> a
    unsafeDoIO (IO Bool -> Bool) -> IO Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ba -> (Ptr Any -> IO Bool) -> IO Bool
    forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
    forall p a. ba -> (Ptr p -> IO a) -> IO a
    withByteArray ba
    b ((Ptr Any -> IO Bool) -> IO Bool)
    -> (Ptr Any -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Ptr Any
    p -> Ptr Any -> Int -> Word8 -> IO Bool
    forall b. Ptr b -> Int -> Word8 -> IO Bool
    loop Ptr Any
    p Int
    0 Word8
    0
      where
        loop :: Ptr b -> Int -> Word8 -> IO Bool
        loop :: forall b. Ptr b -> Int -> Word8 -> IO Bool
    loop Ptr b
    p Int
    i !Word8
    acc
            | Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    len  = Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> IO Bool) -> Bool -> IO Bool
    forall a b. (a -> b) -> a -> b
    $! Word8
    acc Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0
            | Bool
    otherwise = do
                Word8
    e <- Ptr b -> Int -> IO Word8
    forall b. Ptr b -> Int -> IO Word8
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr b
    p Int
    i
                Ptr b -> Int -> Word8 -> IO Bool
    forall b. Ptr b -> Int -> Word8 -> IO Bool
    loop Ptr b
    p (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) (Word8
    acc Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word8
    e)
        len :: Int
    len = ba -> Int
    forall ba. ByteArrayAccess ba => ba -> Int
    Data.ByteArray.length ba
    b