module Data.Digest.CRC32 (
CRC32, crc32
) where
import Foreign
import Foreign.C.Types
import Foreign.ForeignPtr
import GHC.Ptr
import qualified Data.ByteString as S
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Internal as LI
class CRC32 a where
crc32 :: a -> Word32
instance CRC32 S.ByteString where
crc32 = crc32_s
instance CRC32 L.ByteString where
crc32 = crc32_l
instance CRC32 [Word8] where
crc32 = crc32 . L.pack
crc32_s :: S.ByteString -> Word32
crc32_s s = crc32_l (LI.Chunk s LI.Empty)
crc32_l :: L.ByteString -> Word32
crc32_l = LI.foldlChunks updateCRC 0
where updateCRC crc bs = fromIntegral $ crc32_c (fromIntegral crc) buf (fromIntegral len)
where (ptr, offset, len) = BI.toForeignPtr bs
buf = (unsafeForeignPtrToPtr ptr) `plusPtr` offset
foreign import ccall unsafe "zlib.h crc32"
crc32_c :: CInt -> Ptr Word8 -> CInt -> CInt