module Rattletrap.Primitive.Section where import Rattletrap.Crc import Rattletrap.Primitive.Word32 import qualified Control.Monad as Monad import qualified Data.Binary as Binary import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.ByteString.Lazy as ByteString newtype Section a = Section { sectionBody :: a } deriving (Eq, Ord, Show) getSection :: Binary.Get a -> Binary.Get (Section a) getSection getBody = do size <- getWord32 crc <- getWord32 rawBody <- Binary.getLazyByteString (fromIntegral (word32Value size)) let actualCrc = Word32 (getCrc32 rawBody) Monad.when (actualCrc /= crc) (fail (crcMessage actualCrc crc)) let body = Binary.runGet getBody rawBody pure (Section body) putSection :: (a -> Binary.Put) -> Section a -> Binary.Put putSection putBody section = do let rawBody = Binary.runPut (putBody (sectionBody section)) let size = ByteString.length rawBody let crc = getCrc32 rawBody putWord32 (Word32 (fromIntegral size)) putWord32 (Word32 crc) Binary.putLazyByteString rawBody crcMessage :: Word32 -> Word32 -> String crcMessage actual expected = unwords ["actual CRC", show actual, "does not match expected CRC", show expected]