module Rattletrap.Crc where import Rattletrap.Data import qualified Data.Bits as Bits import qualified Data.ByteString.Lazy as ByteString import qualified Data.Vector.Unboxed as Vector import qualified Data.Word as Word -- | Computes the CRC32 of some bytes. This is done to ensure that the bytes -- are valid before trying to parse them. -- -- @ -- getCrc32 ('Data.ByteString.Lazy.pack' [0x00]) -- @ -- -- This CRC uses an initial value of @0xefcbf201@ and a polynomial of -- @0x04c11db7@. getCrc32 :: ByteString.ByteString -> Word.Word32 getCrc32 bytes = do let update = crc32Update crc32Table let initial = Bits.complement crc32Initial let crc = ByteString.foldl update initial bytes Bits.complement crc crc32Update :: Vector.Vector Word.Word32 -> Word.Word32 -> Word.Word8 -> Word.Word32 crc32Update table crc byte = do let toWord8 = fromIntegral :: (Integral a) => a -> Word.Word8 let toInt = fromIntegral :: (Integral a) => a -> Int let index = toInt (Bits.xor byte (toWord8 (Bits.shiftR crc 24))) let left = Vector.unsafeIndex table index let right = Bits.shiftL crc 8 Bits.xor left right crc32Initial :: Word.Word32 crc32Initial = 0xefcbf201 crc32Table :: Vector.Vector Word.Word32 crc32Table = Vector.fromList rawCrc32Table