module Rattletrap.Utility.Crc
( getCrc32
)
where
import Rattletrap.Data
import qualified Data.Bits as Bits
import qualified Data.ByteString as Bytes
import qualified Data.IntMap as IntMap
import qualified Data.Word as Word
getCrc32 :: Bytes.ByteString -> Word.Word32
getCrc32 :: ByteString -> Word32
getCrc32 ByteString
bytes = do
let
update :: Word32 -> Word8 -> Word32
update = IntMap Word32 -> Word32 -> Word8 -> Word32
crc32Update IntMap Word32
crc32Table
initial :: Word32
initial = Word32 -> Word32
forall a. Bits a => a -> a
Bits.complement Word32
crc32Initial
crc :: Word32
crc = (Word32 -> Word8 -> Word32) -> Word32 -> ByteString -> Word32
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
Bytes.foldl Word32 -> Word8 -> Word32
update Word32
initial ByteString
bytes
Word32 -> Word32
forall a. Bits a => a -> a
Bits.complement Word32
crc
crc32Update
:: IntMap.IntMap Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32
crc32Update :: IntMap Word32 -> Word32 -> Word8 -> Word32
crc32Update IntMap Word32
table Word32
crc Word8
byte = do
let
toWord8 :: (Integral a) => a -> Word.Word8
toWord8 :: a -> Word8
toWord8 = a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
toInt :: (Integral a) => a -> Int
toInt :: a -> Int
toInt = a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
index :: Int
index = Word8 -> Int
forall a. Integral a => a -> Int
toInt (Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
Bits.xor Word8
byte (Word32 -> Word8
forall a. Integral a => a -> Word8
toWord8 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
Bits.shiftR Word32
crc Int
24)))
left :: Word32
left = IntMap Word32
table IntMap Word32 -> Int -> Word32
forall a. IntMap a -> Int -> a
IntMap.! Int
index
right :: Word32
right = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
Bits.shiftL Word32
crc Int
8
Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
Bits.xor Word32
left Word32
right
crc32Initial :: Word.Word32
crc32Initial :: Word32
crc32Initial = Word32
0xefcbf201
crc32Table :: IntMap.IntMap Word.Word32
crc32Table :: IntMap Word32
crc32Table = [(Int, Word32)] -> IntMap Word32
forall a. [(Int, a)] -> IntMap a
IntMap.fromDistinctAscList ([Int] -> [Word32] -> [(Int, Word32)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [Word32]
forall a. Integral a => [a]
rawCrc32Table)