module Rattletrap.Utility.Crc where

import qualified Data.Array.Unboxed as Array
import qualified Data.Bits as Bits
import qualified Data.ByteString as ByteString
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.
--
-- @
-- compute ('Data.ByteString.Lazy.pack' [0x00])
-- @
--
-- This CRC uses an initial value of @0xefcbf201@ and a polynomial of
-- @0x04c11db7@.
compute :: ByteString.ByteString -> Word.Word32
compute :: ByteString -> Word32
compute = Word32 -> Word32
forall a. Bits a => a -> a
Bits.complement (Word32 -> Word32)
-> (ByteString -> Word32) -> ByteString -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word32 -> Word8 -> Word32) -> Word32 -> ByteString -> Word32
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
ByteString.foldl' Word32 -> Word8 -> Word32
update Word32
initial

update :: Word.Word32 -> Word.Word8 -> Word.Word32
update :: Word32 -> Word8 -> Word32
update Word32
crc Word8
byte =
  let
    index :: Word8
index = Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
Bits.xor Word8
byte (Word8 -> Word8) -> (Word32 -> Word8) -> Word32 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Word8
unsafeWord32ToWord8 (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
Bits.shiftR Word32
crc Int
24
    left :: Word32
left = Array Word8 Word32
table Array Word8 Word32 -> Word8 -> Word32
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
Array.! Word8
index
    right :: Word32
right = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
Bits.shiftL Word32
crc Int
8
  in Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
Bits.xor Word32
left Word32
right

unsafeWord32ToWord8 :: Word.Word32 -> Word.Word8
unsafeWord32ToWord8 :: Word32 -> Word8
unsafeWord32ToWord8 = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral

initial :: Word.Word32
initial :: Word32
initial = Word32 -> Word32
forall a. Bits a => a -> a
Bits.complement Word32
0xefcbf201

table :: Array.Array Word.Word8 Word.Word32
table :: Array Word8 Word32
table = (Word8, Word8) -> [Word32] -> Array Word8 Word32
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
Array.listArray
  (Word8
0, Word8
255)
  [ Word32
0x00000000
  , Word32
0x04c11db7
  , Word32
0x09823b6e
  , Word32
0x0d4326d9
  , Word32
0x130476dc
  , Word32
0x17c56b6b
  , Word32
0x1a864db2
  , Word32
0x1e475005
  , Word32
0x2608edb8
  , Word32
0x22c9f00f
  , Word32
0x2f8ad6d6
  , Word32
0x2b4bcb61
  , Word32
0x350c9b64
  , Word32
0x31cd86d3
  , Word32
0x3c8ea00a
  , Word32
0x384fbdbd
  , Word32
0x4c11db70
  , Word32
0x48d0c6c7
  , Word32
0x4593e01e
  , Word32
0x4152fda9
  , Word32
0x5f15adac
  , Word32
0x5bd4b01b
  , Word32
0x569796c2
  , Word32
0x52568b75
  , Word32
0x6a1936c8
  , Word32
0x6ed82b7f
  , Word32
0x639b0da6
  , Word32
0x675a1011
  , Word32
0x791d4014
  , Word32
0x7ddc5da3
  , Word32
0x709f7b7a
  , Word32
0x745e66cd
  , Word32
0x9823b6e0
  , Word32
0x9ce2ab57
  , Word32
0x91a18d8e
  , Word32
0x95609039
  , Word32
0x8b27c03c
  , Word32
0x8fe6dd8b
  , Word32
0x82a5fb52
  , Word32
0x8664e6e5
  , Word32
0xbe2b5b58
  , Word32
0xbaea46ef
  , Word32
0xb7a96036
  , Word32
0xb3687d81
  , Word32
0xad2f2d84
  , Word32
0xa9ee3033
  , Word32
0xa4ad16ea
  , Word32
0xa06c0b5d
  , Word32
0xd4326d90
  , Word32
0xd0f37027
  , Word32
0xddb056fe
  , Word32
0xd9714b49
  , Word32
0xc7361b4c
  , Word32
0xc3f706fb
  , Word32
0xceb42022
  , Word32
0xca753d95
  , Word32
0xf23a8028
  , Word32
0xf6fb9d9f
  , Word32
0xfbb8bb46
  , Word32
0xff79a6f1
  , Word32
0xe13ef6f4
  , Word32
0xe5ffeb43
  , Word32
0xe8bccd9a
  , Word32
0xec7dd02d
  , Word32
0x34867077
  , Word32
0x30476dc0
  , Word32
0x3d044b19
  , Word32
0x39c556ae
  , Word32
0x278206ab
  , Word32
0x23431b1c
  , Word32
0x2e003dc5
  , Word32
0x2ac12072
  , Word32
0x128e9dcf
  , Word32
0x164f8078
  , Word32
0x1b0ca6a1
  , Word32
0x1fcdbb16
  , Word32
0x018aeb13
  , Word32
0x054bf6a4
  , Word32
0x0808d07d
  , Word32
0x0cc9cdca
  , Word32
0x7897ab07
  , Word32
0x7c56b6b0
  , Word32
0x71159069
  , Word32
0x75d48dde
  , Word32
0x6b93dddb
  , Word32
0x6f52c06c
  , Word32
0x6211e6b5
  , Word32
0x66d0fb02
  , Word32
0x5e9f46bf
  , Word32
0x5a5e5b08
  , Word32
0x571d7dd1
  , Word32
0x53dc6066
  , Word32
0x4d9b3063
  , Word32
0x495a2dd4
  , Word32
0x44190b0d
  , Word32
0x40d816ba
  , Word32
0xaca5c697
  , Word32
0xa864db20
  , Word32
0xa527fdf9
  , Word32
0xa1e6e04e
  , Word32
0xbfa1b04b
  , Word32
0xbb60adfc
  , Word32
0xb6238b25
  , Word32
0xb2e29692
  , Word32
0x8aad2b2f
  , Word32
0x8e6c3698
  , Word32
0x832f1041
  , Word32
0x87ee0df6
  , Word32
0x99a95df3
  , Word32
0x9d684044
  , Word32
0x902b669d
  , Word32
0x94ea7b2a
  , Word32
0xe0b41de7
  , Word32
0xe4750050
  , Word32
0xe9362689
  , Word32
0xedf73b3e
  , Word32
0xf3b06b3b
  , Word32
0xf771768c
  , Word32
0xfa325055
  , Word32
0xfef34de2
  , Word32
0xc6bcf05f
  , Word32
0xc27dede8
  , Word32
0xcf3ecb31
  , Word32
0xcbffd686
  , Word32
0xd5b88683
  , Word32
0xd1799b34
  , Word32
0xdc3abded
  , Word32
0xd8fba05a
  , Word32
0x690ce0ee
  , Word32
0x6dcdfd59
  , Word32
0x608edb80
  , Word32
0x644fc637
  , Word32
0x7a089632
  , Word32
0x7ec98b85
  , Word32
0x738aad5c
  , Word32
0x774bb0eb
  , Word32
0x4f040d56
  , Word32
0x4bc510e1
  , Word32
0x46863638
  , Word32
0x42472b8f
  , Word32
0x5c007b8a
  , Word32
0x58c1663d
  , Word32
0x558240e4
  , Word32
0x51435d53
  , Word32
0x251d3b9e
  , Word32
0x21dc2629
  , Word32
0x2c9f00f0
  , Word32
0x285e1d47
  , Word32
0x36194d42
  , Word32
0x32d850f5
  , Word32
0x3f9b762c
  , Word32
0x3b5a6b9b
  , Word32
0x0315d626
  , Word32
0x07d4cb91
  , Word32
0x0a97ed48
  , Word32
0x0e56f0ff
  , Word32
0x1011a0fa
  , Word32
0x14d0bd4d
  , Word32
0x19939b94
  , Word32
0x1d528623
  , Word32
0xf12f560e
  , Word32
0xf5ee4bb9
  , Word32
0xf8ad6d60
  , Word32
0xfc6c70d7
  , Word32
0xe22b20d2
  , Word32
0xe6ea3d65
  , Word32
0xeba91bbc
  , Word32
0xef68060b
  , Word32
0xd727bbb6
  , Word32
0xd3e6a601
  , Word32
0xdea580d8
  , Word32
0xda649d6f
  , Word32
0xc423cd6a
  , Word32
0xc0e2d0dd
  , Word32
0xcda1f604
  , Word32
0xc960ebb3
  , Word32
0xbd3e8d7e
  , Word32
0xb9ff90c9
  , Word32
0xb4bcb610
  , Word32
0xb07daba7
  , Word32
0xae3afba2
  , Word32
0xaafbe615
  , Word32
0xa7b8c0cc
  , Word32
0xa379dd7b
  , Word32
0x9b3660c6
  , Word32
0x9ff77d71
  , Word32
0x92b45ba8
  , Word32
0x9675461f
  , Word32
0x8832161a
  , Word32
0x8cf30bad
  , Word32
0x81b02d74
  , Word32
0x857130c3
  , Word32
0x5d8a9099
  , Word32
0x594b8d2e
  , Word32
0x5408abf7
  , Word32
0x50c9b640
  , Word32
0x4e8ee645
  , Word32
0x4a4ffbf2
  , Word32
0x470cdd2b
  , Word32
0x43cdc09c
  , Word32
0x7b827d21
  , Word32
0x7f436096
  , Word32
0x7200464f
  , Word32
0x76c15bf8
  , Word32
0x68860bfd
  , Word32
0x6c47164a
  , Word32
0x61043093
  , Word32
0x65c52d24
  , Word32
0x119b4be9
  , Word32
0x155a565e
  , Word32
0x18197087
  , Word32
0x1cd86d30
  , Word32
0x029f3d35
  , Word32
0x065e2082
  , Word32
0x0b1d065b
  , Word32
0x0fdc1bec
  , Word32
0x3793a651
  , Word32
0x3352bbe6
  , Word32
0x3e119d3f
  , Word32
0x3ad08088
  , Word32
0x2497d08d
  , Word32
0x2056cd3a
  , Word32
0x2d15ebe3
  , Word32
0x29d4f654
  , Word32
0xc5a92679
  , Word32
0xc1683bce
  , Word32
0xcc2b1d17
  , Word32
0xc8ea00a0
  , Word32
0xd6ad50a5
  , Word32
0xd26c4d12
  , Word32
0xdf2f6bcb
  , Word32
0xdbee767c
  , Word32
0xe3a1cbc1
  , Word32
0xe760d676
  , Word32
0xea23f0af
  , Word32
0xeee2ed18
  , Word32
0xf0a5bd1d
  , Word32
0xf464a0aa
  , Word32
0xf9278673
  , Word32
0xfde69bc4
  , Word32
0x89b8fd09
  , Word32
0x8d79e0be
  , Word32
0x803ac667
  , Word32
0x84fbdbd0
  , Word32
0x9abc8bd5
  , Word32
0x9e7d9662
  , Word32
0x933eb0bb
  , Word32
0x97ffad0c
  , Word32
0xafb010b1
  , Word32
0xab710d06
  , Word32
0xa6322bdf
  , Word32
0xa2f33668
  , Word32
0xbcb4666d
  , Word32
0xb8757bda
  , Word32
0xb5365d03
  , Word32
0xb1f740b4
  ]