{-# LANGUAGE Trustworthy #-}
-- |
-- Copyright: © 2020 Herbert Valerio Riedel
-- SPDX-License-Identifier: GPL-2.0-or-later
--
-- Compat-layer providing (slow) fallbacks when compiled w/o
-- https://hackage.haskell.org/package/xor
--
module Data.XOR
( xor32StrictByteString'
, xor32LazyByteString
) where
import Data.Bits (rotateL, xor)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Internal as BL (ByteString (..))
import Data.Word (Word32, Word8)
xor32StrictByteString' :: Word32 -> ByteString -> (Word32,ByteString)
xor32StrictByteString' 0 = (,) 0
xor32StrictByteString' msk0 = BS.mapAccumL go msk0
where
go :: Word32 -> Word8 -> (Word32,Word8)
go msk b = let b' = fromIntegral msk' `xor` b
msk' = rotateL msk 8
in b' `seq` (msk',b')
xor32LazyByteString :: Word32 -> BL.ByteString -> BL.ByteString
xor32LazyByteString 0 = id
xor32LazyByteString msk0 = go msk0
where
go _ BL.Empty = BL.Empty
go msk (BL.Chunk x xs) = BL.Chunk x' (go msk' xs)
where
(msk',x') = xor32StrictByteString' msk x